其实你这个疑问是概念上的混淆,或者说对指针了解上上的欠缺 首先讲int a[3] = {2,3,4}; 这里的a是这个数组的首地址,比如定义如:int *p = a;这时如果你进行如下操作: p++; printf("%d\n",*p); 结果会是输出2,也就是说p+1相当于数组索引加1,但是像你所问的为什么&a和a是相同的 ,首先要知道他们分别代表什么意思,a:像上面所说的是数组的首地址,做自加运算会根据数组类型来计算偏移量,那么&a是什么东西呢,实际上它也是一个指针,是指向一个具有3个元素的数组的指针,如何理解,看以下定义: 如果你定义int *q = &a;这时编译器肯定报错,绘制出数据类型不一致,那么你这样样定义就没有问题:int (*q)[3] = &a;这时如果你再对q进行++操作,那么加的就不同了,如相面的p++操作后p的值会加4,而这里q++操作后的值会加12,也就是跳过3个数组元素,然而,确实这两个指针的初始值是一样的,只是类型不一样而已,这对二维数组的访问时很方便的,这个你可以参照2维数组得到进一步理解,讲的有点乱,不知道你能不能理解
c语言中数组和数组的一些计算
1.数组的创建
元素类型 数组名 [] eg:int arr[10]
注意:[]内是一个常量表达式,用来指定数组的大小
2.数组的初始化
若指定数组大小,可以不进行初始化,若数组完全初始化后,可以不指定其大小
注意:字符串放在字符数组中,默认后面有'\0',字符数组是里面有哪些元素,就是哪些元素..
3.指针初步,指针是一个专门用来存放地址的变量,内存中一个内存单元对应一个地址,
注意:在32位平台上指针(地址)的大小始终为4个字节,64位平台上是8个字节...
4.数组的计算
一维数组
(1)
-
int main()
-
{
-
//一维数组
-
int a[] = { 1, 2, 3, 4};
-
//size of ----一个操作符,可以求出操作数的类型长度(以字节为单位)
-
printf( "%d\n", sizeof(a)); //==16
-
//本身数组名一般代表的是数组首元素的地址,但当数组名单独放在sizeof内部代表的是整个数组中全部元素,因此sizeof(a),求取的是 整个数组中所有元素的类型长度,数组中有4个整型元素,一个整型元素在内存中会占4个字节,因此求出来的类型长度为4*4==16个 字节;
-
-
printf( "%d\n", sizeof(a+ 0)); //==4
-
//sizeof(a+0),由以上叙述可以知道,此处sizeof后边的a代表的是数组首元素中的地址,加上0还是代表数组首元素的地址,而地址 在内存中占用的空间全部都是4个字节,因此,此处的长度为4;
-
-
printf( "%d\n", sizeof(*a)); //==4
-
//此时数组名同样没有单独放在sizeof内部,因此a代表数组首元素的地址,加上*,解引用后,表示的是此数组第一个元素--1,1作为 一个整型元素,在内存中占4个字节,因此求出的长度是4;
-
-
printf( "%d\n", sizeof(a+ 1)); //==4
-
//此时,a依然代表的是数组首元素的地址,加上1之后表示第二个元素的地址,地址在内存中占用的空间是4个字节,因此求出的长度 为4;
-
-
printf( "%d\n", sizeof(a[ 1])); //==4
-
//a[1] == 2;2作为一个整型元素,在内存中占4个字节,因此求出的长度是4;
-
-
printf( "%d\n", sizeof(&a)); //==4
-
//&a代表的是整个数组的地址,依旧是个地址,而地址在内存中占用的空间全部都是4个字节,因此,此处的长度为4;
-
-
printf( "%d\n", sizeof(*&a)); //==16
-
//&a代表的是整个数组的地址,加*号解引用后,代表的是整个数组元素,数组中有4个整型元素,一个整型元素在内存中会占4个字 节,因此求出来的类型长度为4*4==16个字节;
-
-
printf( "%d\n", sizeof(&a+ 1)); //==4
-
//&a代表的是整个数组的地址,&a+1指向的跳过该数组的下一个地址,而地址在内存中占用的空间全部都是4个字节,因此,此处的 长度为4;
-
-
-
printf( "%d\n", sizeof(&a[ 0])); //==4
-
//&a[0]代表的是数组第一个元素的地址,而地址在内存中占用的空间全部都是4个字节,因此此处的长度为4;
-
-
printf( "%d\n", sizeof(&a[ 0]+ 1)); //==4
-
//&a[0]代表的是数组第一个元素的地址,&a[0]+1指向的是第二个元素的地址,而地址在内存中占用的空间全部都是4个字节,因此此 处的长度为4;
-
-
printf( "%p\n",a); //==0038F9EC,数组首元素地址
-
printf( "%p\n",a+ 1); //==0038F9F0,数组中第二个元素地址,与上一个元素地址差4
-
printf( "%d\n", sizeof(*a)); //==4,数组首元素地址解引用,代表数组第一个元素的值,占用4个字节的空间
-
-
printf( "%p\n",&a); //==0038F9EC,虽然&a代表整个数组的地址但为了方便起见,传回来的是首元素的地址
-
printf( "%p\n",&a+ 1); //==0038F9F0,&a代表整个数组的地址,+1后代表跳过数组后的那个一个地址值,与上一个差16;
-
printf( "%d\n", sizeof(*&a)); //==16,&a代表的是整个数组的地址,加*号解引用后,代表的是整个数组元素,数组中有4个整型元素,一个整型元素在内存中会占4个字节,因此求出来的类型长度为4*4==16个字节;
-
-
return 0;
-
}
字符数组
(1)
-
int main()
-
{
-
//字符数组
-
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f'};
-
//size of ----一个操作符,可以求出操作数的类型长度(以字节为单位)
-
//此时数组中元素有[a,b,c,d,e,f],一共6个元素
-
-
printf( "%d\n", sizeof(arr)); //==6
-
//数组名单独存放在sizeof中代表整个数组中所有元素,一个字符型元素在内存中占用空间1个字节,一共6个元素,因此求出的长度是6;
-
-
printf( "%d\n", sizeof(arr+ 0)); //==4
-
//sizeof(arr+0),此处sizeof后边的a代表的是数组首元素中的地址,加上0还是代表数组首元素的地址,而地址在内存中占用的空间全部都是4个字节,因此,此处的长度为4;
-
-
printf( "%d\n", sizeof(*arr)); //==1
-
//此时数组名同样没有单独放在sizeof内部,因此a代表数组首元素的地址,加上*,解引用后,表示的是此数组第一个元素__'a','a'作为一个字符型元素,在内存中占1个字节,因此求出的长度是1;
-
-
printf( "%d\n", sizeof(arr[ 1])); //==1
-
//arr[1]代表的是第二个元素'b'个,作为一个字符型元素,在内存中占用1个字节的长度;
-
-
printf( "%d\n", sizeof(&arr)); //==4
-
//&arr代表的是整个数组的地址,依旧是个地址,而地址在内存中占用的空间全部都是4个字节,因此,此处的长度为4;
-
-
printf( "%d\n", sizeof(&arr+ 1)); //==4
-
//&arr代表的是整个数组的地址,&arr+1指向的跳过该数组的下一个地址,而地址在内存中占用的空间全部都是4个字节,因此,此处的长度为4;
-
-
printf( "%d\n", sizeof(&arr[ 0]+ 1)); //==4
-
//&arr[0]代表的是数组第一个元素的地址,&arr[0]+1指向的是第二个元素的地址,而地址在内存中占用的空间全部都是4个字节,因此此处的长度为4;
-
return 0;
-
}
(2)
-
int main()
-
{
-
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f'};
-
//此时数组中元素有[a,b,c,d,e,f],一共6个元素
-
//strlen函数,参数是要开始寻找元素字符串的起始地址,返回值是字符串中字符的数量(不包括最后'\0'这个结束标志)
-
-
printf( "%d\n", strlen(arr)); //==随机值
-
//arr 代表数组首元素地址,将数组首元素地址传给strlen函数,该函数从该地址开始数数,直到碰到'\0'为止,因此输出为随机值
-
-
printf( "%d\n", strlen(arr+ 0)); //==随机值
-
//arr+0 代表数组首元素地址,将数组首元素地址传给strlen函数,该函数从该地址开始数数,直到碰到'\0'为止,因此输出为随机值
-
-
printf( "%d\n", strlen(*arr)); //==程序中断
-
printf( "%d\n", strlen(arr[ 1])); //==程序中断
-
//上面*arr,对数组首元素地址解引用,表示第一个元素'a',而arr[1]也表示元素'a',这样会把字符a的ascii码值97传给strlen函数,而此函数是访问不到这个地址的,因此会程序中断!
-
-
printf( "%d\n", strlen(&arr)); //随机值
-
printf( "%d\n", strlen(&arr+ 1)); //随机值
-
printf( "%d\n", strlen(&arr[ 0]+ 1)); //随机值
-
//以上三个都是因为'\0',没有在数组中,因此会显示随机值!
-
-
return 0;
-
}
(3)
-
int main()
-
{
-
char arr[] = "abcdef";
-
//此时数组中含有[a,b,c,d,e,f,\0]
-
-
printf( "%d\n", strlen(arr)); //==6
-
//数组首元素地址传给函数,数组中有'\0',前有6个元素!
-
-
printf( "%d\n", strlen(arr+ 0)); //==6
-
////数组首元素地址传给函数,数组中有'\0',前有6个元素!
-
-
printf( "%d\n", strlen(*arr)); //error
-
printf( "%d\n", strlen(arr[ 1])); //error
-
//上面*arr,对数组首元素地址解引用,表示第一个元素'a',而arr[1]也表示元素'a',这样会把字符a的ascii码值97传给strlen函数,而此函数是访问不到这个地址的,因此会程序中断!
-
-
printf( "%d\n", strlen(&arr)); //==6
-
//数组首元素地址传给函数,数组中有'\0',前有6个元素!
-
-
printf( "%d\n", strlen(&arr+ 1)); //==随机值
-
//&arr表示整个数组地址,+1表示跳过该数组后第一个地址,又在寻找'\0',所以是随机值!
-
-
printf( "%d\n", strlen(&arr[ 0]+ 1)); //==5
-
//将第二个元素地址传给函数,知道寻找到'\0',所以为5
-
-
return 0;
-
}
(4)
-
int main()
-
{
-
char *p = "abcdef";
-
//数组中内容[a,b,c,d,e,f,\0]
-
//此时把数组中首元素地址,存放在指针变量p中去了
-
-
printf( "%d\n", sizeof(p)); //==4
-
//p是数组中首元素地址,地址在内存中均占用4个字节的位置,因此为4;
-
-
printf( "%d\n", sizeof(p+ 1)); //==4
-
//p是数组中首元素地址,p+1表示首元素地址后面的那个地址,地址在内存中均占用4个字节的位置,因此为4;
-
-
printf( "%d\n", sizeof(*p)); //==1
-
//p是数组中首元素地址,地址解引用,表示数组第一个元素'a',他是一个字符型元素,在内存中占用1个字节;
-
-
printf( "%d\n", sizeof(p[ 0])); //==1 == *(p+0) == *(arr+0) == arr[0yi]
-
//p是数组中首元素的地址,而arr也表示数组中首元素的1地址,从某种角度来说,arr[0]和p[0]是等价的,表示首元素'a',他是一个字符型元素,在内存中占用1个字节;
-
-
printf( "%d\n", sizeof(&p)); //==4
-
printf( "%d\n", sizeof(&p+ 1)); //==4
-
printf( "%d\n", sizeof(&p[ 0]+ 1)); //==4
-
//以上三个都是一个类型,都是取出来的地址,地址在内存中占4个字节,因此为4!
-
-
printf( "%d\n", strlen(p)); //==6
-
//将数组元素首地址传递给给函数,数组中有'\0',所以有6个元素!
-
-
printf( "%d\n", strlen(p+ 1)); //==5
-
//将数组元素首地址的下一个地址,也就是第二个元素的地址,传递给给函数,数组中有'\0',所以有5个元素!
-
-
printf( "%d\n", strlen(*p)); //error
-
printf( "%d\n", strlen(p[ 0])); //error
-
//上面*p,对数组首元素地址解引用,表示第一个元素'a',而p[1]也表示元素'a',这样会把字符a的ascii码值97传给strlen函数,而此函数是访问不到这个地址的,因此会程序中断!
-
-
printf( "%d\n", strlen(&p)); //随机值
-
//&p表示对指针变量再取地址传入函数中,而中从此处开始查找的时候,后面并没有'\0',所以是随机值
-
-
printf( "%d\n", strlen(&p+ 1)); //随机值
-
//&p表示对指针变量再取地址,然后这个地址的下一个地址传入函数中,而中从此处开始查找的时候,后面并没有'\0',所以是随机值
-
-
printf( "%d\n", strlen(&p[ 0]+ 1)); //==5
-
////将数组元素首地址的下一个地址,也就是第二个元素的地址,传递给给函数,数组中有'\0',所以有5个元素!
-
-
return 0;
-
}