首先上结论:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
关于 sizeof 和 strlen :
1.sizeof 是操作符,只关注占用内存的大小,单位是字节,不关心内存中放的是什么。
2.strlen 是库函数,统计的是'\0'之前出现的字符的个数,一定要找到'\0'才算结束,所以可能存在越界访问。
注释:下面皆为x86(32位)环境中运行结果,单位字节
一维数组:
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); //整个数组的大小16
printf("%d\n",sizeof(a+0)); //第一个元素的大小4
printf("%d\n",sizeof(*a)); //*a是素组首元素,大小4
printf("%d\n",sizeof(a+1)); //第二个元素的地址,大小4
printf("%d\n",sizeof(a[1])); //第二个元素,大小4
printf("%d\n",sizeof(&a)); //整个数组的地址,既然是地址,大小就为4
printf("%d\n",sizeof(*&a)); //&和*抵消,*&a->a,整个数组的大小 16
printf("%d\n",sizeof(&a+1)); //&a是整个数组的地址,&a+1,跳过整个数组,是地址大小4
printf("%d\n",sizeof(&a[0])); //首元素的地址,大小4
printf("%d\n",sizeof(&a[0]+1));//第二个元素的地址,大小4
代码运行结果如下:
字符数组:
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr)); //arr单独放在sizeof内部,计算整个数组大小,大小6
printf("%d\n", sizeof(arr+0)); //首元素地址,大小4
printf("%d\n", sizeof(*arr)); //数组首元素,大小1
printf("%d\n", sizeof(arr[1])); //数组第二个元素,大小1
printf("%d\n", sizeof(&arr)); //整个数组的地址,是地址,大小为4
printf("%d\n", sizeof(&arr+1)); //跳过整个素组,指向下一个地址,是地址,大小为4
printf("%d\n", sizeof(&arr[0]+1));//第二个元素的地址,大小为4
printf("%d\n", strlen(arr)); //随机值,数组没有‘\0’,无法计算字符串长度
printf("%d\n", strlen(arr+0)); //随机值
//printf("%d\n", strlen(*arr)); //strlen('a')->strlen(97),非法访问-err
//printf("%d\n", strlen(arr[1])); //'b'->98 非访问-err
printf("%d\n", strlen(&arr)); //&arr虽然是数组的地址,但仍是从数组'a'开始,故随机值
printf("%d\n", strlen(&arr+1)); //跳过整个数组的地址,随机值
printf("%d\n", strlen(&arr[0]+1));//跳过第一个字符的地址,随机值
代码运行结果如下:
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //包含'\0',大小7
printf("%d\n", sizeof(arr+0)); //首元素地址,大小4
printf("%d\n", sizeof(*arr)); //首元素,大小1
printf("%d\n", sizeof(arr[1])); //第二个元素,大小1
printf("%d\n", sizeof(&arr)); //整个数组的地址,是地址,大小为4
printf("%d\n", sizeof(&arr+1)); //跳过整个数组,指向下一个地址,是地址大小4
printf("%d\n", sizeof(&arr[0]+1));//第二个元素的地址,大小4
printf("%d\n", strlen(arr)); //arr数组首元素地址,统计‘\0’之前6个字符,故结果6
printf("%d\n", strlen(arr+0)); //同上是首元素地址,结果6
//printf("%d\n", strlen(*arr)); //*arr是‘a’,是97,非法地址,非法访问-err
//printf("%d\n", strlen(arr[1]));//同上,非法访问
printf("%d\n", strlen(&arr)); //取到了整个数组的地址,由于从第一个元素地址开始,结果仍为6
printf("%d\n", strlen(&arr+1)); //跳过了整个数组,随机值
printf("%d\n", strlen(&arr[0]+1));//第二个元素的地址,故结果为5
代码运行结果如下:
char *p = "abcdef";
printf("%d\n", sizeof(p)); //p是指针变量,大小为4
printf("%d\n", sizeof(p+1)); //p+1是b的地址,是地址,大小4
printf("%d\n", sizeof(*p)); //首元素,大小为1
printf("%d\n", sizeof(p[0])); //p[0]->*(p+0)->*P,大小为1
printf("%d\n", sizeof(&p)); //&p是二级指针,是地址,大小4
printf("%d\n", sizeof(&p+1)); //跳过p变量后的地址,还是地址,大小4
printf("%d\n", sizeof(&p[0]+1));//b的地址,是地址,大小4
printf("%d\n", strlen(p)); //p是a的地址,结果6
printf("%d\n", strlen(p+1)); //p+1是b的地址,结果5
//printf("%d\n", strlen(*p)); //*p是a,97,非法访问-err
//printf("%d\n", strlen(p[0]));//同上
printf("%d\n", strlen(&p)); //&p拿到p的地址,是二级指针,随机值
printf("%d\n", strlen(&p+1)); //跳过p的地址,随机值
printf("%d\n", strlen(&p[0]+1));//b的地址,结果为5
代码运行结果如下:
二维数组:
//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a)); //整个数组的大小3*4*4=48
printf("%d\n",sizeof(a[0][0])); //第一个元素的大小 4
printf("%d\n",sizeof(a[0])); //第一行的元素 4*4=16
printf("%d\n",sizeof(a[0]+1)); //a[0]没有单独放在括号内,表示第一行首元素地址,+1为第二元素地址,是地址大小4
printf("%d\n",sizeof(*(a[0]+1)));//由上可知是第一行第二个元素,大小4
printf("%d\n",sizeof(a+1)); //a是二维数组的数组名是第一行的地址,+1第二行的地址大小4
printf("%d\n",sizeof(*(a+1))); //由上可知(a+1)是第二行的地址,*(a+1)为第二行大小4*4=16
printf("%d\n",sizeof(&a[0]+1)); //&a[0]第一行的地址,+1是第二行的地址,地址的大小4
printf("%d\n",sizeof(*(&a[0]+1)));//第二行的大小 4*4=16
printf("%d\n",sizeof(*a)); //a是数组名,表示首元素地址(第一行),第一行的大小16
printf("%d\n",sizeof(a[3])); //如果存在第四行,a[3]是第四行的数组名,数组名单独放在sizeof()中间,计算的是第四行的大小16
代码运行结果如下:
文章到这里就结束了,谢谢大家的观看