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

数组名转指针实验遇意外输出:为何两次打印均为地址?

数组名与指针的疑惑:为何两次输出都是地址?

你的代码:

#include<stdio.h> 
   
int main() 
{ 
  int a[] = {1, 2, 3, 4, 5, 6}; 
  printf("%d\n",*(&a+1));
  printf("%d\n",**(&a+1));
  return 0; 
}

运行输出:

6422304
6422284

你预期第一个输出是地址,第二个是该地址的数值,但实际都是地址,问题出在这几个核心点:

1. 先明确&a的类型

a是长度为6的int数组,&a的类型是指向int[6]数组的指针(记作int (*)[6])。这种指针的移动步长是整个数组的大小(假设int占4字节,步长就是6*4=24字节),和普通int指针的步长(4字节)完全不同。

2. &a+1的指向

给&a加1时,指针会向后移动一个整个数组的长度,最终指向数组a末尾之后的第一个位置(等价于a+6的地址)。

3. *(&a+1)的本质

解引用&a+1得到的是int[6]类型的数组,但在传给printf这类函数时,数组类型会自动退化为指向其第一个元素的指针(也就是int*类型),这个指针指向的就是a数组末尾之后的地址。你用%d打印这个指针,本质是把指针的内存地址值以十进制整数输出,所以第一个输出是地址的数值。

4. **(&a+1)为何也输出地址?

首先*(&a+1)退化为int*指针,再解引用一次理论上应该访问该指针指向的内存值,但这里有两个关键问题:

  • 你用错了格式符:%d用于打印int类型,但**(&a+1)访问的是数组a之外的内存,属于未定义行为——编译器不会按你预期的逻辑处理。
  • 你的输出呈现为地址,大概率是编译器内存布局或优化导致的异常结果,这个操作本身就是非法的,结果完全不可靠。

正确的写法示例

如果想打印地址,要用%p格式符;如果要合法访问数组元素,不能越界:

#include<stdio.h> 
   
int main() 
{ 
  int a[] = {1, 2, 3, 4, 5, 6}; 
  // 打印&a+1的数组指针地址
  printf("%p\n", &a+1);
  // 打印*(&a+1)退化成的指针地址(和上面地址值一致)
  printf("%p\n", *(&a+1));
  // 打印数组最后一个元素的合法值
  printf("%d\n", a[5]);
  return 0; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:16:03