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

关于C语言多维数组声明与指针访问结果的疑问

关于C语言多维数组声明与指针访问结果的疑问

嗨,我来帮你理清这里的两个关键点——多维数组的初始化规则,以及指针访问背后的内存布局问题。

首先说初始化的部分:你以为必须用{{1,2,3},{4,5,6}}这种双层大括号的形式初始化二维数组,但其实C语言允许省略内层的大括号。当你写int arr[2][3] = {1,2,3,4,5};时,编译器会按照行优先的顺序,把列表里的元素依次填充到数组的每个位置:先填满第一行的3个元素(1、2、3),再填第二行的前两个(4、5),剩下的元素(第二行第三个)会被自动初始化为0。所以这个声明完全合法,不会报错,它等价于int arr[2][3] = {{1,2,3}, {4,5,0}};。

接下来解释为什么(*arr)[4]会得到5:

  • 首先,二维数组名arr在表达式中(除了sizeof和取地址&的场景)会隐式转换为指向数组第一行的指针,也就是int (*)[3]类型的指针(指向一个包含3个int的数组)。
  • *arr就是对这个指针解引用,得到的是第一行的数组本身(arr[0],类型是int[3])。而当这个一维数组名出现在表达式中时,又会再次转换为指向其第一个元素的指针(int*类型,指向arr[0][0])。
  • 所以(*arr)[4]本质上是*( (int*)arr + 4 )——也就是从数组的起始地址开始,偏移4个int的位置去访问内存。而二维数组在内存里是连续存储的,整个arr的内存布局是:1, 2, 3, 4, 5, 0(连续排列),偏移4个位置正好是第5个元素(下标从0开始),也就是5。

不过要特别提醒:这种写法其实属于数组越界访问,因为(*arr)代表的是第一行的3元素数组,[4]已经超出了它的合法下标范围(应该是0-2)。虽然当前编译器下你得到了预期的结果,但这是标准里定义的「未定义行为」——换个编译器、编译选项甚至运行环境,结果可能完全不同,甚至导致程序崩溃。所以实际开发中绝对不要依赖这种写法。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:54:36