为何数组不符合「指针自身地址与存储地址不同」的规则?
数组与指针的地址差异解析
首先得掰明白一个核心误区:数组不是指针。很多人误以为数组名是个指针,但它本质是代表整个数组的标识符,只是在大多数表达式里会被编译器隐式转换成指向数组首元素的指针——但它本身不是占用内存的指针变量。
先看指针变量的情况
m_pointer是正经的指针变量,它自己占一块内存(比如4或8字节),用来存另一个变量的地址。所以&m_pointer是这个指针变量自己的内存地址,而m_pointer里面存的是m的地址,这俩地址肯定不一样,完全合理。
再看数组的情况
拿int m_arr[5]来说:
&m_arr[0]是数组第一个元素的地址,也就是数组在内存里的起始位置。- 数组名
m_arr在表达式里会自动转成指向首元素的指针,所以它的数值和&m_arr[0]完全相同。 - 而
&m_arr是整个数组的地址,它的类型是int (*)[5](指向包含5个int的数组的指针)——虽然数值上和前两者一样,但类型完全不同。数值相同的原因很简单:整个数组的起始地址,本来就是首元素的起始地址。
你误以为数组是“指向自身的const指针”,这是错的。数组名根本不是变量,它不需要占用内存来存储地址,也就不存在“自己的独立地址”。它只是编译器用来定位数组实体的符号,只有像指针变量、普通变量这种实实在在占内存的东西,才有自己的地址。
修正后的示例代码
#include <iostream> using namespace std; int main() { int m = 5; int* m_pointer; m_pointer = &m; // &m_pointer != m_pointer 合理,因为m_pointer存的是m的地址,自己也有独立内存地址 int m_arr[5]; // 重命名避免变量名冲突 // 打印三个地址看数值 cout << "m_arr 的值:" << m_arr << endl; cout << "&m_arr[0] 的值:" << &m_arr[0] << endl; cout << "&m_arr 的值:" << &m_arr << endl; // 可以取消注释看类型差异 // cout << "m_arr 的类型:" << typeid(m_arr).name() << endl; // cout << "&m_arr[0] 的类型:" << typeid(&m_arr[0]).name() << endl; // cout << "&m_arr 的类型:" << typeid(&m_arr).name() << endl; }
&m_pointer != m_pointer ,, thats make sense and understandable
because m_pointer stores the address of (m) but it has it's own address
内容的提问来源于stack exchange,提问作者Eslam Mohamed
相关产品推荐
相关产品推荐

