在网上看到一个这样代码:
int main
{
int a[5] = {1,2,3,4,5};
int *str = (int *)(&a+1);
printf("%d\n%d\n", *(a+1), *(str-1));
return 0;
}
我一开始也陷入了陷阱里,没想这一个数组指针,以为只是普通的首地址加上一个数据类型的字节,于是我开始进行了下面一系列的实验:
#include<stdio.h>
int main(void)
{
int a[5] = { 1,2,3,4,5 };
int *b = (int*)(&a+1);
for (int count = 0; count < 6; count++)
{
printf("&a[%d]=%d\n", count, a + count);
printf("&a[%d]=%d\n", count, &a[count]);
}
printf("\n");
printf("b=%d\n",b);
printf("b-1=%d\n", b-1);
printf("*b=%d\n",*b);
printf("*b-1=%d\n",*b-1);
printf("*(b-1)=%d\n",*(b-1));
return 0;
}
打印出来的结果如图一所示:
因为指针类型是int*类型,所以在每+1为4个字节(编译环境:VS2015)。b和a[5]的地址相同,其实这个写法是错的,会越界。b-1和a[4]地址相同。所以可以看出这个+1加的&a是整一个数组的长度。
那是不是这样呢?我们把上面的printf(“&a[%d]=%d\n”, count, a + count);改成printf(“&a[%d]=%d\n”, count, &a + count);
打印结果如图二所示:
可以看到&a+1之间是以20个字节为单位,&a[1]之间以4个字节为单位。证明我上面说的,那+1该加多少呢?是不是与前面的地址所指的长度有关?我们把上面的printf(“&a[%d]=%d\n”, count, &a + count);改成printf(“b + %d =%d\n”, count, b + count);,我们来看一下结果:
我们可以看到第一个b+0还是&a[5]的地址,那为什么后面是以4个字节为单位呢?而不是以20个字节呢?那是因为在定义b这个指针的时候,把他的类型转换成了int*型(int b=(int)(&a+1));所以现在可以证明:+1要加多少跟+1前面的指针类型有关系。
那二维数组的时候,情况又是怎么样的呢?我又写了以下的程序进行测试:
#include<stdio.h>
int main(void)
{
int a[3][3] = { { 1,2 },{ 3,4 },{ 5,6 } };
int *b = (int*)(&a + 1);
for (int c = 0; c < 3; c++)
for (int d = 0; d < 3; d++)
printf("&a[%d][%d]=%d\n", c, d, &(a[c][d]));
printf("\n");
for (int count = 0; count < 3; count++)
{
printf("a + %d=%d\n", count, a + count);
printf("&a[%d]=%d\n", count, &a[0] + count);
}
printf("\n");
printf("&a[2][1]=%d\n", &(a[2][1]));
printf("b=%d\n", b);
printf("b-1=%d\n", b - 1);
printf("*b=%d\n", *b);
printf("*b-1=%d\n", *b - 1);
printf("*(b-1)=%d\n", *(b - 1));
return 0;
}
结果如图四所示:
我们可以看出a+count是以12个字节为单位,因为我们定义的是int型3*3的二维数组,所以一行为12。在二维数组的指针中a=&a[0][0],a+1=&a[1][0],依此类推。
我们现在把printf(“a + %d=%d\n”, count, a + count);改成printf(“&a + %d=%d\n”, count, &a + count);看看是不是以3*3*4=36个字节为单位递增,我们打印看一下结果:
看来我们的推导是正确的,果然是以36个字节为单位递增。所以:+1要加多少个字节跟+1前面的指针类型有关系。&a是数组指针,代表数组的总长度,所以&a+1中的1为数组a所占的内存。而a+1中的a跟&a[0][0]是一样的,都表示的是数组的首地址,所以其中+1中的1为数组的类型字节数。
以上实验均在windows平台上运行,Linux平台下结果不同。