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

C语言静态数组指针运算疑问:&a与a地址相同为何解引用结果不同?

C语言静态数组指针运算疑问解答

先看你提供的代码和运行输出:

代码

#include <stdlib.h>
#include <stdio.h>
void main() {
    int N=3, a[N];
    for (int i=0; i<N; i++) a[i] = 1000+i;
    printf("&a    = %p\n",&a);
    printf("a     = %p\n",a);
    printf("*a    = %d\n",*a);
    printf("*(&a) = %d   (as an int)\n",*(&a));
    printf("*(&a) = %p  (as a pointer)\n",*(&a));
}

运行输出

&a    = 0x7ffee9043ae0
a     = 0x7ffee9043ae0
*a    = 1000
*(&a) = -319989024   (as an int)
*(&a) = 0x7ffee9043ae0  (as a pointer)

核心疑问解答:为什么&a和a的地址值完全相同?

这是因为数组的起始地址和它首元素的起始地址是同一个内存位置:

  • a作为数组名,在大多数表达式场景中会隐式转换为指向数组首元素的指针(类型为int*),它指向的是a[0]的起始地址。
  • &a是整个数组的地址,类型为int(*)[3](指向包含3个int元素的数组的指针),它指向的是整个数组的起始位置,而数组的起始位置正好就是首元素a[0]的起始位置。

两者指向的内存起点完全一致,所以用%p打印时,地址值自然相同,但它们的类型本质完全不同——这也是*a和*(&a)结果不同的根本原因。

补充:*a和*(&a)的差异解析

  • *a:因为a转换为int*,解引用后得到的是首元素a[0]的值,也就是1000,类型是int,用%d打印正常。
  • *(&a):&a是int(*)[3]类型,解引用后得到的是数组a本身(类型为int[3]),而数组名又会再次转换为指向首元素的指针(int*)。当你用%d打印这个指针时,是把指针的地址值当成int类型来解析(由于指针和int的字节长度、存储方式可能不同,就出现了奇怪的负数);用%p打印时,就是正确的首元素地址。

另外纠正一个误区:你之前认为&a是int**类型是错误的,&a的类型是指向数组的指针,不是指向指针的指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:56:06