C99标准的C语言支持可变长度数组,可以用变量作为数组长度创建二维数组。那么,在C89标准的C语言中如何实现动态创建二维数组?
用一维数组代替二维数组
内存是线性(一维)的,不管数组是几维,最终在内存中都是线性存储的。二维数组的内存模型如图:

C语言通过计算与数组首地址的偏移字节数来定位到数组元素。例如在数组int array[M][N]
中,访问元素array[i][j]
时,计算地址的方式为:
1 | 单位字节数 = sizeof (int) |
由此想到,我们分配一维数组,然后自己计算偏移量(以sizeof (int)
为单位),将二维数组下标转换为一维数组下标,就能正确访问到数组元素了。
1 | int rows = 3, cols = 4; |
缺点:不能用array[i][j]
的语法访问数组元素,可读性较差。
规则的动态二维数组
- 先动态分配一个指针数组(第一维数组)
- 再为指针数组的每个指针分配元素数组(第二维数组)
1 | int rows = 3, cols = 4; |
内存模型如图:

可通过array[i][j]
的语法访问数组元素,其本质是两级指针解引用,即等同于*(*(array + i) + j)
。
用gcc -std=c89
编译通过,运行结果正确。
Java语言的多维数组就是这种原理,即多级一维数组。
不规则的动态二维数组
如果分配第二维数组时,长度不固定,那么二维数组就不是规则的矩形,而是每行长度不同的不规则的形状。
1 | int rows = 3; |
内存模型如图:

同样可以通过array[i][j]
访问数组元素,只不过对于不同的i
,j
的合法范围不同。
这种模式可以用来存储三角矩阵。