前段时间有朋友给了我一道指针的习题,我当时并没有做对。并且输出的结果让我很是不解。今天仔细学复杂类型的时候,忽然灵光一现想起此道题并仔细琢磨一阵明白其中的幽微之处,遂写下此博文以记之。
题目代码如下:
int _tmain(int argc, _TCHAR* argv[]) { int a[5]={1,2,3,4,5}; int *p; p=(int *)(&a+1); printf("%d\n",*(p-1)); return 0; }
问:程序运行输出结果是多少?
我当时的回答是:1;当时的想法是&a+1 为 a[0]的地址加1,那么p所指向的是a[1],输出的时候在对p进行了减1 所以p指向a[0];
正确的解法应该是:
1、在解决这个题目时 我们首先要清楚对于数组a[5]来讲 a 与&a 的区别(这个题目的关键之处)。
ok 我们先来看看a与&a所指向的空间占的字节数。
对a来说我们都很熟悉 a指向的是数组a[0]的地址那么它所指的向空间占的字节数为4。
对&a在这里我们要稍稍的变通一下,我们都知道下面代码中
由 int a=6; int *p=&a; 可得到p是指向a的,那么p所指向的空间占的字节数与sizeof(a)的值是相等的。
用代码来看一下
int _tmain(int argc, _TCHAR* argv[]) { int a=6; int *p=&a; printf("%ld %ld\n",sizeof(*p),sizeof(a)); return 0; }
结果也验证了:
那么对于数组&a的类型,我们可以先假设一个指针q=&a;那么对于指针q所指向空间占的字节数应该为 sizeof(a);用代码来看看他的字节数:
int _tmain(int argc, _TCHAR* argv[]) { int a[5]={1,2,3,4,5}; printf("%ld\n",sizeof(a)); return 0; }
结果:
而我们的整个数组所占用的字节数刚好为20个字节,说明了该指针q指向了我们的整个数组a;使我们想到了指针数组,那么q应该是 int (*q)[5] ,ok弄清楚了&a的类型就好办了,对与表达式&a+1 则为从a[0]的地址算起加上20个字节,刚好跳出了数组a。实际上p所指向的地址应该为p=a+5, 在输出函数中对p进行了减一 此时的p=a+4;神奇的又使p指向了数组的最后一个元素。从而输出结果为5。
复杂类型(二)一个题目引发的博文,布布扣,bubuko.com
原文:http://www.cnblogs.com/showCode/p/3633225.html