C++中函数内数组a的地址为何与首元素a[0]地址不同?
造成该现象的核心原因
这个差异是C/C++的数组退化规则导致的,两个场景下的a本质不是同一种实体:
- 在
main函数中,int a[] = {0,1,2,3}是直接在栈上分配的完整数组,此处的a是数组类型,不是指针。&a取的是整个数组的内存起始地址,&a[0]取的是数组第一个int元素的起始地址——数组的内存块本身就是从第一个元素的位置开始排布的,因此两个地址值完全相等,和你观察到的main内输出一致。 - 当数组作为函数形参传递时,C/C++语法规定数组会自动退化为指向数组首元素的指针,也就是说你写的
void func(int a[])和void func(int* a)是完全等价的。 - 进入
func函数后,形参a根本不是main里定义的原数组,而是func自己的栈帧上单独创建的一个int*类型指针变量,这个变量里存储的值,才是main里数组首元素的地址(也就是你输出里的0x7ffef67d6790)。 - 你在func里写
&a时,取的是这个指针变量自身在栈上的存储地址,不是原数组的地址,所以输出是和原数组地址不同的0x7ffef67d6778;而写&a[0]时,等价于对存了首元素地址的指针解引用后取第一个元素的地址,拿到的自然是原数组首元素的地址,和main里的结果一致。
你可以用一个简单的方式验证这个结论:分别在main和func中打印sizeof(a),main中得到的是整个数组的大小(4个int共16字节),func中得到的是指针类型的大小(64位系统为8字节,32位系统为4字节),可以直接证明func内的形参a是独立的指针变量,不是原数组。
内容的提问来源于stack exchange,提问作者Hai
相关产品推荐
相关产品推荐

