整形数组:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));
system("pause");
return 0;
}
分析:
printf("%d\n", sizeof(a));//16
数组名单独放到sizeof内部,计算的是数组的总大小,单位是字节,所以是16
printf("%d\n", sizeof(a+0));//4
数组名并没有单独放到sizeof内部,表示的是首元素的地址,首元素的地址+0还是首元素的地址,是地址,就是4个字节
printf("%d\n", sizeof(*a));//4
数组名a没有单独放在sizeof内部,表示首元素的地址,首元素地址解引用就找到首元素,这个数组是整形,所以是4个字节
printf("%d\n", sizeof(a+1));//4
a是数组名,表示首元素地址,首元素地址+1,第二个元素地址,是地址,在32位平台上就是4个字节
printf("%d\n", sizeof(a[1]));//4
这个就是数组的第二个元素,这个数组的元素为整形,所以是4个字节
printf("%d\n", sizeof(&a));//4
&a,取的是数组的地址,数组的地址依然是个地址,大小为4,数组的地址+1跳过的是整个数组的大小
printf("%d\n", sizeof(*&a));//16
先取地址,再解引用,相当于a没动,数组的地址前面解引用一下,访问的是整个数组的大小,单位是字节,当然大小是16
补充一点,数组的地址的类型和首元素地址的类型是不一样的,数组的地址的类型为:int(*)[4] ,首元素地址的类型为int*
printf("%d\n", sizeof(&a + 1));//4
&a取出的是数组的地址,地址就是4个字节,&a+1加的是整个数组的大小
printf("%d\n", sizeof(&a[0]));//4
首元素地址,是地址就是4个字节
printf("%d\n", sizeof(&a[0]+1));//4
第二个元素地址,是地址就是4个字节
字符数组(1):
#include <stdio.h>
#include <stdlib.h>
int main()
{
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
system("pause");
return 0;
}
分析:
printf("%d\n",sizeof(arr));//6
数组名单独放在sizeof内部,表示整个数组的大小,单位是字节,大小为6个字节
printf("%d\n", sizeof(arr+0));//4
数组名并没有单独放到sizeof内部,所以arr表示的是首元素地址,首元素地址+0仍然是首元素地址,是地址就是4个字节
printf("%d\n", sizeof(*arr));//1
arr是数组名。表示首元素地址,首元素地址解引用后是首元素,这个数组的首元素是char,所以是1个字节
printf("%d\n", sizeof(arr[1]));//1
下表为1的元素,大小为1个字节
printf("%d\n", sizeof(&arr));//4
&数组名,依然是个地址,所以是4个字节
printf("%d\n", sizeof(&arr+1));//4
数组的地址+1,跳过整个数组的大小,但是仍旧是个地址,是4个字节
printf("%d\n", sizeof(&arr[0]+1));//4
首元素取地址再+1就是第二个元素的地址,大小为4个字节
printf("%d\n", strlen(arr));//随机值
strlen找的是\0,而 'a', 'b', 'c', 'd', 'e', 'f'放进去之后并没有\0,strlen找的时候并不知道在哪停下来,所以是随机值
printf("%d\n", strlen(arr+0));//随机值
arr是首元素地址,+0还是首元素地址,所以和上个一样,不知道什么时候找到\0,也是随机值
printf("%d\n", strlen(*arr));//错误
首元素地址解引用后是个元素,strlen传的是地址,把元素传给strlen就有问题,所以会出现错误
printf("%d\n", strlen(arr[1]));//错误
arr[1]是下标为1的元素,strlen传的是地址,把元素传给strlen就有问题,同样会出现错误
printf("%d\n", strlen(&arr));//随机值
&arr取的是数组的地址,数组的地址和数组首元素的地址在值上讲是一模一样的,所以也是从 'a'开始找,因为不知道\0在哪,所以是随机值
printf("%d\n", strlen(&arr+1));//随机值
同理,只是&arr+1跳过了整个数组才开始找,因为没有\0,也是随机值,
printf("%d\n", strlen(&arr[0]+1));//随机值
这个是跳过首元素去找,由于没有\0,也是随机值,只是和strlen(&arr+1))的值相差1
字符数组(2):
#include <stdio.h>
#include <stdlib.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
system("pause");
return 0;
}
分析:
printf("%d\n", sizeof(arr));//7
arr里面不仅放了abcdef,还把\0放了进去,sizeof(arr)计算的是整个数组的大小,单位是字节,大小为7,不考虑\0
printf("%d\n", sizeof(arr + 0));//4
arr是首元素地址,+0还是首元素地址,所以是4个字节
printf("%d\n", sizeof(*arr));//1
arr是首元素地址,解引用后是首元素,数组首元素是char类型,所以大小为1个字节
printf("%d\n", sizeof(arr[1]));//1
计算的是数组第二个元素的大小,是char类型,大小为1个字节
printf("%d\n", sizeof(&arr));//4
&arr取出的是数组的地址,是地址,就是4个字节
printf("%d\n", sizeof(&arr + 1));//4
数组的地址+1,跳过整个数组,把\0也跳过去了,所以这个地址指向的是\0的后面,不管怎么说,还是个地址,为4个字节
printf("%d\n", sizeof(&arr[0] + 1));//4
这个地址指向的是b,大小还是4个字节
printf("%d\n", strlen(arr));//6
strlen求字符串长度,不包含\0,长度为6
printf("%d\n", strlen(arr + 0));//6
strlen(arr + 0)和strlen(arr)没什么区别,还是6
printf("%d\n", strlen(*arr));//错误
strlen需要的是地址,传元素过去就有问题
printf("%d\n", strlen(arr[1]));//错误
strlen需要的是地址,传元素过去就有问题
printf("%d\n", strlen(&arr));//6
strlen要的是地址,把数组的地址传过去,数组的地址和数组首元素地址从值上讲是一样的,大小依然为6
printf("%d\n", strlen(&arr + 1));//随机值
&arr+1把整个数组和\0都跳过去了,从\0之后找,不确定,是随机值
printf("%d\n", strlen(&arr[0] + 1));//5
从b开始往后数,大小为5
指针数组:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p + 1));
printf("%d\n", sizeof(&p[0] + 1));
printf("%d\n", strlen(p));
printf("%d\n", strlen(p+1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0] +1));
system("pause");
return 0;
}
分析:
printf("%d\n", sizeof(p));//4
p是个指针变量,指针变量在32位平台上就是4个字节
printf("%d\n", sizeof(p + 1));//4
p里面存的是a的地址,p+1存的是b的地址,是地址,就是4个字节
printf("%d\n", sizeof(*p));//1
p里面存的是a的地址,p的地址解引用就是a,是a就是一个字节
printf("%d\n", sizeof(p[0]));//1
p[0]等价于*(p+0),p是首元素a的地址,+0还是a的地址,解引用就是a,a是char类型,大小为1个字节
printf("%d\n", sizeof(&p));//4
取地址p,是个地址,是地址就是4个字节,这里需要注意的是&p的类型是char**
printf("%d\n", sizeof(&p + 1));//4
取地址p+1,还是个地址,大小为4个字节,这个地址指向的是p的后面,而不是p所指向的字符串的后面
printf("%d\n", sizeof(&p[0] + 1));//4
&p[0] + 1存的是数组第二个元素的地址,即指针p指向了b
printf("%d\n", strlen(p));//6
p里面存的是a的地址,strlen向后数字符,直到遇到\0就停下来了,所以是6
printf("%d\n", strlen(p + 1));//5
p + 1里面存的是b的地址,strlen从b开始向后数字符,数到\0就停下来,所以大小是5
printf("%d\n", strlen(*p));//错误
p是首元素地址,解引用就是a,strlen要的是地址,传值过去就有问题
printf("%d\n", strlen(p[0]));//错误
p[0]表示首元素a,strlen要的是地址,传值过去就有问题
printf("%d\n", strlen(&p));//随机值
取地址p,取出的是p本身的地址,而非p指向的空间的地址,不知道什么时候遇到\0,所以是随机值
printf("%d\n", strlen(&p + 1));//随机值
取地址p+1,取出的是跳过p本身的地址之后的地址,由于没有\0,也是随机值
printf("%d\n", strlen(&p[0] + 1));//5
&p[0] + 1取出的是b的地址,strlen从b向后数,一直到找到\0,大小为5