You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中数组名、&数组名、&数组首元素地址为何输出值相同?

核心认知澄清

你看到的三个完全相同的地址值,不代表对应内存位置上同时存储了地址值和数值6,这是对指针、地址概念的典型混淆。

  • 地址0x7ff9c94a10对应的内存块里,实际只连续存放了3个long类型的元素:从该地址开始的8字节存数值6,接下来8字节存9,再8字节存10,整个24字节的数组内存块里没有其他任何存储内容。
  • 你用%p打印出来的三个相同数值,是三个不同类型的指针表达式计算得到的指向位置的坐标值。这些值既不是指针自身在内存中的存储地址,也不是坐标位置上存放的内容,只是编译器推导出的、用来标记“指针指向的内存从哪个位置开始”的数值。
三个表达式的本质差异

三个指针的指向坐标完全重合,只是因为数组是连续排布的,内存块的物理起点和块内首个元素的起点天然是同一个位置,但三者的类型、指向范围、偏移规则完全不同:

  • a:数组名在除sizeof、取地址&之外的所有场景下,都会发生隐式类型退化,从“长度为3的long型数组”转换为指向数组首元素的long*类型指针,取值就是首元素的起始地址。
  • &a:是对整个数组取地址,不会发生隐式退化,类型是long (*)[3]——也就是指向“长度为3的long型数组”的指针。它的取值是整个数组内存块的起始坐标,和首元素坐标完全重合,因此打印出来的地址值和a一致。
  • &a[0]:是对数组第一个元素直接取地址,类型和隐式退化后的a完全相同,都是long*,取值自然也和a一致。
直观验证三者区别

三个指针的起点坐标一样,但因为指向的对象大小不同,指针偏移的步长完全不同,可以通过简单的地址计算验证差异:

printf("%p\n", a + 1);     // 输出地址比原位置多8字节(跳过1个long的长度),指向数组里的元素9
printf("%p\n", &a + 1);   // 输出地址比原位置多24字节(跳过整个3元素数组的长度),直接指向数组内存块的末尾之外
printf("%p\n", &a[0] + 1);// 输出结果和a+1完全一致,同样指向元素9

这种坐标重合的逻辑和现实中一样:一段30米长的路,“路的起点”“整段路的范围起点”“路边第一个里程碑的位置”,三个描述的坐标完全重合,但不代表这三个概念是同一个东西——只是所有计量范围都是从同一个点开始向外延伸的而已。


内容的提问来源于stack exchange,提问作者Widd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 17:45:05