一个关于结构体中数组访问范围的题目,一开始做错了,现在记录下来,分享一下:
- #include <stdio.h>
- struct S {
- int i[2];
- char str;
- int *p;
- };
- int main(int argc, char* argv[])
- {
- /////////////////////////////////
- //本部分关于指针运算的先后问题
- int arr[]={6,7,8,9,10};
- int *ptr=arr;
- (*ptr++)+=123;
- ptr++;
- printf("%d\n",*ptr);
- printf("%d.%d\n",*ptr,*(++ptr));
- /////////////////////////////////////
- //////////////////////////////////////
- //本部分是关于结构体中数组的访问范围
- struct S s;
- int *p =s.i;
- printf("%d",sizeof(S));
- p[0]=4;
- p[1]=3;
- p[2]=4;
- s.p=p;
- s.p[0] = 0;
- s.p[1] = 1;
- s.p[2] = 2;
- for(int k=0; k<3; ++k)
- {
- printf("\n%d",s.p[k]);
- }
- s.p[3] = 3;
- s.p[4] = 4;
- ///////////////////////////////////////
- return 0;
- }
程序的第一部分输出的结果是:
- 8
- 9.9
可以看出第二个printf语句的和第一个语句的输出不同了,因为第二个输出的计算的顺序是从右向左,所以ptr是++运算后的地址。
程序第二部分输出结果是:崩溃了,哈哈~~猜猜在哪个地方崩溃了
答案是:第37行s.p[4]=4;崩溃了,注释掉第37行,输出结果如下:
- 16
- 0
- 1
- 2
为什么到第37行崩溃了呢?
这里主要是因为结构体的大小,我们在指针是结构体中数组 i 的地址,从此地址开始到结构体结束空间大小只有16,所以我们能访问4个int型的数据,故到s.p[4]时崩溃了。
如果我们把s.p[3]=3;写到循环前面,会在哪个地方崩溃呢?
答案是:在for循环中的第一个printf语句处崩溃,因为我们把指针的地址改了,哈哈~~s.p[3]实际上是结构体中指针p的地址。