废话不多说,上代码:
#include <stdio.h>
char array[100];
int main( )
{
printf("%p\n%p\n", array, &array);
return 0;
}
使用%p来打印地址,直接显示16进制,并加上0x前缀。
将上述代码分别保存为test.c和test.cpp,用C和C++编译器来执行,在Ubuntu虚拟机里执行结果如下:
$ gcc -o test test.c
0x55f40b401040
0x55f40b401040
$ g++ -o test test.cpp
0x556ad0fa9040
0x556ad0fa9040
看到没有,两个值一摸一样,还真是活久见,之前编码确实没遇到过。
今天你就遇到了!
改代码改了半天发现好奇怪,就发现了这个问题。
为啥?
在C语言里,数组名其实就是一个指针,是指向数组中的第一个元素的地址。
所以上面例子中,array就是第一个元素的地址;
而&array表示这个数组的地址,和array的值是一样的。
但array+1和&array+1是不同的,如果数组中的元素超过一个的话。
#include <stdio.h>
char array[16];
int main( )
{
printf("%p\n%p\n", array, &array);
printf("%p\n%p\n", array+1, &array+1);
return 0;
}
$ gcc -o test test.c
0x55bd17a6e020
0x55bd17a6e020
0x55bd17a6e021
0x55bd17a6e030
根据上面结果,array+1是数组中下一个元素的地址。
而&array+1,是以整个数组为单位,下一个数组的地址。
就是说对一个数组定义T array[size]来说,array的定义类型是T*,表示的是指向第一个元素的指针。
对其进行+1操作,取得的是数组中的下一个元素。
而对数组名使用单目的地址操作符&时,这时数组名表示的是整个数组,得到的类型是T(*)[size]。
其表达式值和整个数组的第一个元素的地址相同,但表示的是指向一个数组的指针,不是指向单个元素。
对这个指针执行+1操作,增加的是整个数组的大小,而不是单个元素的大小。
另外一点,当对数组名使用sizeof运算符时,数组名所代表的也是整个数组。
所以sizeof array会返回整个数组所占用的字节数,而不是指向第一个元素的指针的大小。
参考:
pointers - How come an array's address is equal to its value in C? - Stack Overflow