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

C++数组名与指针疑惑:为何打印数组名与指针地址结果一致?

数组名与指针的迷惑:为什么&arr和arr打印地址相同?

兄弟,我太懂这种疑惑了!当年我刚学C++的时候也对着这个问题挠了半天头,咱们一步步拆解清楚。

首先先还原你大概率写的测试代码(如果不对你可以补充,但八九不离十):

#include <iostream>
using namespace std;

int main() {
    int arr[] = {10, 20, 30};
    cout << &arr << endl;   // 你以为的「指针自身的内存地址」
    cout << arr << endl;    // 你以为的「指针存储的地址」
    cout << *arr << endl;   // 你以为的「地址指向的值」
    return 0;
}

你说前两行结果完全相同,核心原因有两个:

  1. 数组名的隐式转换:在绝大多数表达式中,数组名会自动转换成指向数组第一个元素的指针。比如arr在这里会变成int*类型,指向arr[0]的地址。
  2. 数组的起始地址就是第一个元素的地址:数组在内存里是连续存储的,整个数组的起始位置和第一个元素的起始位置是同一个内存点,所以&arr(数组的地址)和arr(转成指针后指向第一个元素的地址)的数值是完全一样的。

但这里要划重点:它们的类型完全不同!

  • &arr的类型是int (*)[3]——这是一个「指向包含3个int的数组的指针」,如果你对它做指针加法,&arr + 1会直接跳过整个数组(也就是跳过3个int的大小);
  • 而arr转成的int*,做arr + 1只会跳过一个int的大小。

那你预期的「指针自身的内存地址」怎么打印?其实你误解了:arr本身不是指针变量,它是数组类型,不存在「自身的内存地址」这种说法(或者说&arr是数组的地址,不是某个指针的地址)。如果要看到真正的「指针自身地址」,你得先把数组名转成一个指针变量:

int* ptr = arr;
cout << &ptr << endl;  // 这才是指针变量ptr自己的内存地址
cout << ptr << endl;   // ptr存储的地址(也就是arr[0]的地址)
cout << *ptr << endl;  // 指向的值(arr[0])

这时候你会发现前两行结果完全不同,符合你的预期。

再补充几个数组名和指针的核心区别,帮你彻底搞清楚:

  • 数组名不能被赋值:比如arr = arr + 1;是编译错误,但ptr = ptr + 1;完全合法;
  • sizeof(arr)得到的是整个数组的字节大小(比如上面的例子是12,因为3个int每个4字节),而sizeof(ptr)得到的是指针类型的大小(在64位系统是8字节);
  • 取地址的结果类型不同:&arr是数组指针,&ptr是指针的指针(int**)。

总结一下:你看到的前两行地址相同,只是因为数组的起始地址和第一个元素的地址重合,但它们的类型和语义完全不一样。而你想要的「指针自身地址」,得先把数组名转成一个真正的指针变量才能看到~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:41:13