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

C语言二维数组解引用问题:为何*(b+1)和b+1输出的地址一致?

问题原理说明

首先明确C语言中二维数组的本质是数组的数组,你定义的int b[3][4],实际是一个长度为3的数组,数组的每个元素都是「长度为4的int数组」。

各表达式的含义解析

  • b是二维数组名,作为右值使用时会自动退化为「指向第一行数组的指针」,类型为int (*)[4](指向长度为4的int数组的指针),值为整个二维数组的起始地址,也就是你输出的0x7ffeecee6730。
  • b+1是基于b的指针运算:指针偏移的步长由指向的类型长度决定,b指向的是4个int组成的数组(假设单个int占4字节,总长度为16字节),因此b+1会向后偏移16字节,指向第二行数组的起始地址,值为0x7ffeecee6740,类型仍为int (*)[4]。
  • *(b+1)是对b+1的解引用操作,得到的是第二行的数组本身,类型为int [4]。当数组作为printf参数传入时,会自动退化为「指向数组首元素的指针」,类型为int *,值就是第二行第一个元素的起始地址。

为什么两者输出地址相同?

b+1是指向第二行整个数组的指针,*(b+1)退化后是指向第二行第一个int元素的指针,两者指向的内存起始位置完全一致,所以用%p打印出来的地址值完全相同,仅指针的类型不同。

为什么用%d打印*(b+1)得到垃圾值?

*(b+1)最终退化为int *类型的指针,你用%d格式符去打印指针的地址值:

  • 64位系统下指针长度为8字节,int长度为4字节,格式符和参数类型不匹配,会触发未定义行为
  • 就算长度匹配,你打印的本质是内存地址的数值,不是你预期的元素值,自然是无意义的结果

如何正确拿到第二行第一个元素的值?

需要对退化后的int *指针再做一次解引用,两种写法等价:

// 写法1
printf("%d\n", *(*(b+1)));
// 写法2 更直观的数组下标写法
printf("%d\n", b[1][0]);

以上两种写法都会输出你预期的第二行第一个元素值4。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:24:02