C++数组指针引用疑问:为何*(&int_array)等于数组地址而非1?
C++数组地址与内存结构问题解答
示例代码
int int_array[5] = {1, 2, 3, 4, 5}; std::cout << int_array << " " << &int_array << " " << *(&int_array) << " " << **(&int_array) << " " << *(int_array) << std::endl; for (int i=0;i<5;i++) { std::cout << i << " " << int_array[i] << " " << &int_array[i] << " " << *(&int_array[i]) << std::endl; }
运行输出
0xd1a03ff9e0 0xd1a03ff9e0 0xd1a03ff9e0 1 1 0 1 0xd1a03ff9e0 1 1 2 0xd1a03ff9e4 2 2 3 0xd1a03ff9e8 3 3 4 0xd1a03ff9ec 4 4 5 0xd1a03ff9f0 5
数组内存地址表
| 数值 | 内存地址 |
|---|---|
| 1 | 0xd1a03ff9e0 |
| 2 | 0xd1a03ff9e4 |
| 3 | 0xd1a03ff9e8 |
| 4 | 0xd1a03ff9ec |
| 5 | 0xd1a03ff9f0 |
为什么*(&int_array)输出的是数组地址而非1?
要搞清楚这个问题,得先明确几个关键的类型和转换规则:
int_array的类型是int[5](长度为5的int数组),在大多数表达式里(除了作为sizeof、&、decltype的操作数时),会自动触发数组到指针的隐式转换,变成指向数组第一个元素的int*指针,值就是第一个元素的地址0xd1a03ff9e0。&int_array得到的是指向整个数组的指针,类型是int(*)[5],它的存储值就是数组的起始地址(和第一个元素的地址重合),所以输出和int_array转换后的指针值一致。*(&int_array)是对这个数组指针的解引用,得到的是整个数组本身(类型还是int[5])。当这个数组被传入cout输出时,又触发了数组到指针的隐式转换,再次变成指向第一个元素的int*,所以输出的还是数组起始地址。
如果想要得到第一个元素的值1,需要再解引用一次,也就是**(&int_array)——这和*(int_array)的效果完全一样,都是取数组第一个元素的值。
int_array的变量值与内存结构
内存结构
int_array在内存中是连续存放的5个int类型数据,从地址差值能看出来,每个int占4字节(比如第二个元素地址0xd1a03ff9e4减去第一个元素地址0xd1a03ff9e0等于4)。内存布局从低地址到高地址依次是:
- 地址0xd1a03ff9e0:存储数值1
- 地址0xd1a03ff9e4:存储数值2
- 地址0xd1a03ff9e8:存储数值3
- 地址0xd1a03ff9ec:存储数值4
- 地址0xd1a03ff9f0:存储数值5
变量值的本质
int_array作为数组变量,它本身不是指针,而是代表了整个数组的存储空间。只有在大多数表达式场景下,它会自动转换成指向第一个元素的指针,所以直接输出int_array时看到的是第一个元素的地址。
有几个特殊场景下它会保持数组类型:比如sizeof(int_array)得到的是整个数组的字节数(5*4=20),而不是指针的大小;&int_array得到的是指向整个数组的指针,而不是指向指针的指针。
内容的提问来源于stack exchange,提问作者Query
相关产品推荐
相关产品推荐

