数组与指针,&a和a

今天无意中看到一道题目,考察的是数组与指针,如下

int a[5] = {1,2,3,4,5};
int *ptr1 = (int *)(a + 1);
int *ptr2 = (int *)(&a + 1);
printf("%d %d\n" , *ptr1, *(ptr2-1));
初一看,我想的答案是2,1,因为a是数组名称,也就是数组的首地址,a+1指向的就是数组的第二个元素了,也就是2,所以打印的是2,&a+1也是这样理解的,先+1再-1,那应该输出的是数组的第一个元素了,但是上机运行,输出的是2,5,感觉很不解,于是用了下面这个语句去查各个元素分配的地址

printf("%p %p %p %p %p %p %p %p %p\n", a, &a, &a[0], &a[1], &a[2], &a[3], &a[4], ptr1, ptr2);
打印出来的结果是0022FE84 0022FE84 0022FE84 0022FE88 0022FE8C 0022FE90 0022FE94 0022FE88 0022FE98

从这个结果可以看出a,&a[0],&a这三者在数值上是一样的,都表示了数字a的首地址,但是a+1和&a+1的结果却是完全不同的,后来查了资料,原来a的数据类型是int *,而&a的数据类型是int (*)[5],于是sizeof(&a)=5*sizeof(int)=20,所以&a+1实际上跳过了整块的a所分配的内存地址,也就是越界了,ptr2-1将指针拉回到数组a所在的地址区域,指向了a[4],所以会输出5,至此这道题我算是理解了。从这里看出,C语言中的指针真的是很灵活,需要用心去体会了。




阅读更多
文章标签: C语言 指针
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭