目录
前言
这里是参考b站鹏哥C语言讲解,要是我写的不明白,大家可以去看看视频
一、一维数组
1.先自己算下以下结果
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));
详细解答如下图所示:
tips:
1.sizeof(数组名)()里只有数组名,这里的数组名表示整个数组,说明计算的是整个数组的大小
2.&数组名,这里的数组名表示整个数组,因此取出的是整个数组的地址
3.除此之外,所有的数组名均表示数组首元素的地址
二、字符数组
1.以下运行结果是
简单说一下:
char arr[] = { 'a','b','c','d','e','f' }以这种形式表示,说明里面是什么就是什么,没看见\0就没有\0,
所以,sizeof(arr) 数组大小是6
sizeof(arr + 0) +0,首元素地址大小4/8,32位平台下为4
sizeof(*arr) 地址解引用表示首元素,所以为1
sizeof(arr[1]) 表示b的大小,1
sizeof(&arr) & arr表示地址的大小,为4/8,sizeof(&arr+1)& arr + 1也是地址,4/8
sizeof(&arr[0] + 1)), & arr[0] + 1相当于int*,表示b的地址,为4/8
strlen(arr)要见到\0才会停下来,这里面没有\0,所以是一个随机值
strlen(arr + 0),从首地址开始计算字符串长度,还是随机值
strlen()函数里是int strlen(const char* str),也就是传的是地址,strlen(*arr)中 * arr进行了解引用,出错,error,算不出来
同理,strlen(arr[1])也出错,error,算不出来
先看下一个理解最后3个的辅助图
strlen(&arr), & arr==char(*)[6],随机值
strlen(&arr + 1), 随机值-6
strlen(&arr[0] + 1) 随机值 - 1
2.在看一个孪生姐妹,猜一猜运行结果是多少
解释以下:
/* char arr[] = "abcdef",这样写,里面是含有\0的,
即是[a b c d e f \0],
sizeof(arr) 为7
sizeof(arr + 0) 4/8 表示首元素地址,地址大小不就是4/8
sizeof(*arr) 1 首元素地址解引用,是a
sizeof(arr[1]) 1 是b
sizeof(&arr) 4/8 相当于char(*)[7],到底是个放地址的指针
sizeof(&arr + 1) 4/8
sizeof(&arr[0] + 1) 4/8
*/
/*
strlen(arr) 6
strlen(arr + 0) 6
strlen(*arr) error
strlen(arr[1]) error,传的参数出错
strlen(&arr) 6
strlen(&arr + 1) 随机值,与上一个关系应该是-6,下一个我不知道会在哪遇到\0
strlen(&arr[0] + 1) 5
*/
3.还有一个,再对比分析一下
解惑大师来了:
/*
在内存中是这么存储的a b c d e f \0
sizeof(p) p是指针呀,指针大小4/8
sizeof(p + 1) 指向的是b,还是指针,4/8
sizeof(*p) 对指针首元素进行解引用,1
sizeof(p[0]) p[0] -->*(p+0),不还是个1
sizeof(&p) 4/8 二级指针
sizeof(&p + 1) 4/8
sizeof(&p[0] + 1) 4/8
*/
/*
strlen(p) 6
strlen(p + 1) 元素首地址+1,在计算strlen,5
strlen(*p) 出错,
strlen(p[0]) 出错
strlen(&p) 随机值
strlen(&p + 1) 随机值,这个跟上面没有关系,主要是不知道哪里见到\0
strlen(&p[0] + 1)) 5
*/
辅助图:
二、二维数组
以下结果为什么呢?
答案及分析:
sizeof(a) 48
sizeof(a[0][0]) 4
sizeof(a[0]) a[0]作为数组名并没有单独放在sizeof内部,
也没取地址,所以a[0]就是第一行第一个开始算的地址,16
sizeof(a[0] + 1)是第一行第二个元素的地址 4
sizeof(*(a[0] + 1)) *(a[0] + 1)第一行第二个元素的解引用,4
sizeof(a + 1) 4,a是二维数组的数组名,并没有取地址,也没有放在sizeof()
内部,所以a表示二维数组首元素的地址,即第一行的地址,a + 1就是二维数组第二行的地址
sizeof(*(a + 1)) 16 对第二行地址进行解引用,计算的是第2行的大小
sizeof(&a[0] + 1) a[0]是第一行的数组名,&a[0]取出的是第一行的地址,
&a[0] + 1就是第二行的地址,所以结果为4
sizeof(*(&a[0] + 1)) 16
sizeof(*a) 16, *(a+0)-->a[0],对首行地址进行解引用
sizeof(a[3]) 16,因为sizeof()内部的表达式是不计算的
a[3]其实是第4行的数组名(如果有的话),所以其实不存在,也能通过类型计算大小
总结
重在理解,关键是知道指针所指向的谁,在内存中是怎么分布的~