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

二维数组指针访问疑问:为何ptr+1与*(ptr+1)输出地址相同?

为何ptr+1与*(ptr+1)输出的地址完全相等?

先看你的代码

#include <stdio.h>
int main()
{
   int arr_2D[3][3]={ {1,2,3},
                      {11,22,33},
                      {111,222,333} };
    int (*ptr)[3]=arr_2D;
    
    printf("ptr=0x%0X\n",ptr+1); // ptr=0x60FEE4
    
    printf("*(ptr)=0x%0X\n",*(ptr+1)); //*(ptr+1)=0x60FEE4
    return 0;
}

核心原因拆解

  1. 先明确ptr的类型
    int (*ptr)[3]是指向3个int元素组成的数组的指针(俗称数组指针)。它指向的不是单个int变量,而是一整行包含3个int的数组。

  2. ptr+1的偏移逻辑
    指针的加减操作是按它指向类型的大小来偏移的。因为ptr指向的是3个int的数组(假设int占4字节,总大小就是12字节),所以ptr+1会直接跳过12字节,指向二维数组的第二行(也就是arr_2D[1])的起始位置。

  3. *(ptr+1)的本质变化
    对这个数组指针解引用后,得到的是它指向的那个一维数组(arr_2D[1])。但在C语言里,数组名只要不是出现在sizeof或者&运算符后面,都会自动“退化”成指向数组第一个元素的指针。所以arr_2D[1]会直接变成&arr_2D[1][0]——也就是第二行第一个元素的地址。

  4. 地址相同的关键
    二维数组中某一行的起始地址,和这一行第一个元素的地址在内存里是同一个位置。ptr+1指向的是第二行数组的起始地址,*(ptr+1)退化后指向的是第二行第一个元素的地址,两者自然是同一个值,输出也就完全相等了。

直观的内存示例

假设arr_2D的起始地址是0x60FED8:

  • ptr指向第一行数组arr_2D[0],地址是0x60FED8
  • ptr+1跳过12字节,指向第二行数组arr_2D[1],地址是0x60FED8 + 12 = 0x60FEE4
  • *(ptr+1)是arr_2D[1],退化后指向arr_2D[1][0],地址同样是0x60FEE4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:17:54