为何数组名及其地址打印出的内存地址值完全相同?
为什么数组名和数组的地址打印出来是同一个值?
哈哈,这个问题简直是C语言数组/指针的经典坑!我当初刚学的时候也卡了好久,给你掰扯清楚:
首先先还原你大概率写的测试代码:
#include <stdio.h> int main() { int x[5] = {1,2,3,4,5}; printf("%p\n", x); // 打印数组名 printf("%p\n", &x); // 打印"数组的地址" return 0; }
输出的两个地址值看起来完全一样,这就是你的疑惑点对吧?核心原因有两个:
1. 数组名的隐式转换规则
数组名x在绝大多数表达式场景下(比如传给printf),会被编译器隐式转换成指向数组首元素的指针,也就是等价于&x[0]——所以第一个printf打印的是数组第一个元素的起始地址。
2. &x的本质是"指向整个数组的指针"
&x并不是你以为的"存储首元素地址的指针的地址",因为数组名根本不是一个指针变量!指针变量是占用独立内存空间的(比如4/8字节),用来存储另一个地址;但数组名只是编译器用来标记数组起始位置的符号,它本身不占用内存空间。
&x的类型是int (*)[5](翻译一下:指向包含5个int的数组的指针),它指向的是整个数组的起始位置——而整个数组的起始位置,和第一个元素的起始位置,本来就是同一个内存点啊!就像一栋5层楼的地址,和一楼第一个房间的地址是同一个物理位置,但前者代表整栋楼,后者只代表一个房间。
3. 用指针偏移验证类型差异
你可以加个测试代码,就能看出两者的本质区别:
printf("%p\n", x + 1); // 偏移1个int,地址+4(假设int占4字节) printf("%p\n", &x + 1); // 偏移1个整个数组,地址+20(5*4)
运行后会发现两个偏移后的地址完全不同——这就证明了,虽然初始地址值相同,但x(转换后是int*)和&x(int (*)[5])是完全不同类型的指针,语义天差地别。
总结一下:地址值相同只是因为它们指向的是同一个内存起始点,但一个指向单个元素,一个指向整个数组,别被表面的地址值迷惑啦!
内容的提问来源于stack exchange,提问作者Dilini Peiris
相关产品推荐
相关产品推荐

