数组 a+1 和 &a+1 的区别
先来看一段代码:
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
printf("a = %p\n", a); // I
printf("&a = %p\n", &a); // II
printf("a + 1 = %p\n", a + 1); // III
printf("&a + 1 = %p\n",&a + 1); // IV
return 0;
}
运行结果
本机(linux)结果输出:
a = 0xbf89d00c
&a = 0xbf89d00c
a + 1 = 0xbf89d010 //0x10-0x0C=0x04
&a + 1 = 0xbf89d020 // 0x20-0x0c=0x14 = 20(10进制)
可以看到,上面 I 和 II 打印出来的地址是一样的,IV 要比 III 大 20 个字节的地址空间。
首先引用《C和指针》p141中的理论:
在C中, 在几乎所有使用数组的表达式中,数组名的值是个指针常量
,也就是数组第一个元素的地址。 它的类型取决于数组元素的类型: 如果它们是int类型,那么数组名的类型就是“指向 int 的常量指针“。
看到这里我想应该就知道为什么 会有 I 和 III 式的结果了。
对于 II 和 IV 则是特殊情况,在《C和指针》p142 中说到,在以下两种场合下,数组名并不是用指针常量来表示,就是当数组名作为 sizeof 操作符 和 单目操作符 & 的操作数时。sizeof 返回整个数组的长度,而不是指向数组的指针的长度。 取一个数组名的地址所产生的是一个指向数组的指针
,而不是一个指向某个指针常量的指针。所以 &a 后返回的指针便是指向数组的指针,跟 a(一个指向 a[0] 的指针)在指针的类型上是有区别的。与二维数组比较。数组名和 & 数组名代表同一个地址不同意思所对应用户代码为 printf(“a =%p\n”, &a + 1),根据《C和指针》中的理论,当 a 前面有 & 操作符时,编译器将会把 a 对应符号表中的地址看作指向数组的指针。