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

如何用单个索引访问C语言二维数组?相关内存地址疑问解答

二维数组访问与地址疑问解答

问题背景

代码1及运行结果

#include <stdio.h>

int main() {
    int a[2][2] = { 0,1,2,3};
    printf("\n%d %d \n%d %d\n",a[0][0],a[0][1],a[1][0],a[1][1]);
    printf("%d %d %d %d\n",*a[0],*a[1],*a[2],*a[3]);
    return 0;
}

运行输出:

0 1 
2 3
0 2 0 1491303602

代码2及运行结果

printf("\n%d %d \n%d %d\n",&a[0][0],&a[0][1],&a[1][0],&a[1][1]);
printf("%d %d %d %d\n",a[0],a[1],a[2],a[3]);

运行输出:

1137924528 1137924532 
1137924536 1137924540
1137924528 1137924536 1137924544 1137924552

疑问

  1. 由于二维数组在内存中是连续存储的,是否可以通过单个索引来访问二维数组?
  2. 为什么前两个元素的内存地址&a[0][0]等于a[0]、&a[0][1]等于a[1],但后两个却不匹配?

解答

1. 单个索引访问二维数组的可行性

可以。二维数组在内存中是连续线性存储的,对于int a[m][n],完全可以当作长度为m*n的一维数组访问,常用两种方式:

  • 强制类型转换:将数组名转为一维数组指针,例如*(int*)a + i,其中i取值范围是0到m*n-1,对应一维数组的第i个元素;
  • 地址偏移:通过*(&a[0][0] + i)直接访问,本质和第一种方式一致,也可以用下标计算a[i/n][i%n](前提是i不越界)。

注意:代码中a[2]、a[3]属于越界访问,原数组仅2行,超出范围的行指针指向数组内存外的未知区域,这就是输出出现随机值的原因,属于未定义行为,严禁这么写。

2. 地址匹配问题的原因

首先明确二维数组的类型逻辑:

  • a是int[2][2]类型,a[0]、a[1]本身是int[2]类型的一维数组,在表达式中会隐式转换为指向自身首元素的指针;
  • a[0]转换后指向a[0][0],所以a[0]的值等于&a[0][0];a[1]转换后指向a[1][0],所以a[1]的值等于&a[1][0]——你误以为a[1]等于&a[0][1]是完全错误的,二者地址差了一个int的大小(看输出:a[1]是1137924536,&a[0][1]是1137924532)。

而a[2]、a[3]属于越界访问,原数组只有2行,这两个指针指向数组内存范围外的“虚拟行”首地址,自然和&a[1][0]、&a[1][1]不匹配,这类访问属于未定义行为,结果不可预测。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:55:09