问题描述
使用指向数组的指针,得到数组的最后一个数。
实现代码
#include <stdio.h>
int main()
{
int a[8] = {1, 2, 4, 8, 16, 32, 64, 128};
int *p = (int*)(&a + 1);
printf("%d\n", *(p - 1));
return 0;
}
结果:
128
合理性分析
比如说:
int m = 1;
则:
*m 由于m不是指针变量,所以不存在。
&m 是指向m的地址。
*&m 是指地址为&m的内存中存放的值,也就是m的值。
C语言的数组地址为其首元地址,每个元素地址都是其首地址。
比如一个长度为4的int数组,首元地址600000,第二个元素是600004,第三个元素是600008,最后一个元素是600012,数组地址范围600000 ~ 600015,长16字节。
&a+1 表示了在数组首地址加上数组总长,上例则为600016。
同理,如果是&a+2 则表示600032,&+3 则为600048,……
int *p = (int*)(&a + 1);
上面的语句定义了一个int类型的指针,指向的位置是&a+1,上例的600016。
“相当于”是一个新的数组,此时600016成了首元,p-1则是倒着取一个元素,地址600012,p-2则是600008,……
*(p-1)对p-1地址的数据取出,得到的正是600012存的元素,即第四个元素,也是最后一个元素。
测试
#include <stdio.h>
int main()
{
int a[8] = {1, 2, 4, 8, 16, 32, 64, 128};
int *p = (int*)(&a + 1);
printf("%d\n", a);
printf("%d\n", &a[0]);
printf("%d\n", *a);
printf("%d\n", &a);
printf("%d\n", (&a+1));
printf("%d\n", (&a+2));
printf("%d\n", (&a+3));
printf("%d\n", p);
printf("%d\n", (p - 1));
printf("%d\n", (p - 2));
printf("%d\n", *p);
printf("%d\n", *(p - 1));
return 0;
}
执行结果:
6422000
6422000
1
6422000
6422032
6422064
6422096
6422032
6422028
6422024
7869392
128
反思
看不懂就说明还是不会C/C++的指针,以后要加强对这方面的理解。
这篇文章的大部分结论都来自于自己做测试得到的猜测,未必都准确,还望懂C/C++的读者多多指教!