最近在看《高级C语言程序员测试必过的十六道最佳题》时,发现一道非常有趣的题目。题目如下:
Consider the following program:
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
printf("%d %d\n", *(a+1), *(ptr-1));
return 0;
}
The output for this program is
(a) 2 2
(b) 2 1
(c) 2 5
(d) None of the above
经过测试,其输出结果如下:
从运行结果可知,我们应该选择C。那么,为什么选C呢?
首先,我们可以看下它的题目,数组a是一个数组,每个数组元素的类型是int,且总共有5个元素。也就是说数组名a的类型是整型数组类型。那么,&a的类型是什么呢?我们只有知道了&a的类型才能知道其加1具体是什么意思?在这里,&a的类型是指向整型数组的指针类型。那么&a+1表示的意思就是:将指针移动的大小是5*4=20(在32系统上)。即这里加1实际上是加上了数组a的整个数组长度。因为&a的类型是指向整个数组a的指针类型。那么,它指向的类型的长度是含有5个整型元素的数组,所以这里加1,实际上是加上数组a的长度。那么,后面的printf函数的里面的输出就可以很好的得出了。要注意下就是,&a+1是从数组的第一个元素处开始移动的,移动后,它指向了数组a最后一个元素的下一个位置处,所以,后面才有了(ptr-1)。
我们也可以编程去验证它,例如,下面的程序:
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a+1);
printf("&a = %d\n", &a);
printf("(&a+1) = %d\n", (&a+1));
printf("%d %d \n", *(a+1), *(ptr-1));
return 0;
}
我们可以看下它的输出结果:
从输出的结果中,我们可以看到,&a的地址是1244980,而&a+1的地址是1245000。二者相差20,从而验证上面所说的额,&a的类型是一个指向整型数组的指针类型。