8. 二维数组
前面我们学习了一维数组,一维数组是具有相同数据类型的变量排列在一起组成的数据结构。
这一节我们来学习 C 语言中的 二维数组。二维数组你可以看成是多个相同长度的一维数组组成的数组,即:数组的数组。
在软件开发的过程中经常会用到二维数组来表示所需要的数据结构,比如:数学中的矩阵、黑白照片、五子棋或围棋的棋盘等。
在 C 语言中,我们可以认为二维数组使用行和列组成的网格结构。每个网格中的数据元素类型必须一致。
8.1 二维数组声明
二维数组声明的语法:
数据类型 数组名[行整数表达式m][列整数表达式n] = {...}, ...;
语法说明:
- 数据类型是数组内所有成员的数据类型,不是数组的数据类型。
- 数组名必须是标识符。
- 数组名是一个常量,不能使用赋值语句对其进行赋值操作。
- 在逻辑上 二维数组 是 m 行 n 列的二维网格的结构,每一行的数据个数都必须相等,每一列的数据个数也必须相等。
- 在物理存储时实际是以每一行为单位的 m 个 一维数组依次顺序摆放在内存中。
- 行整数表达式m 是整数常量表达式,表示二维数组的行数,在有初始化列表时可以省略不写,由初始化列表推导出行数m。
- 列整数表达式n 是整数常量表达式,表示二维数组的列数,此数值必须给出。
= {...}是数组的初始化列表,此部分可以省略不写,如果不给定初始化列表,数组内的数据元素的值可能是任意值。- 初始化列表 必须是用一对大括号(
{})括起来的表达式列表,该初始化列表用来初始化数组中每一个数据的初始值。 - 二维数组的 初始化列表 的写法是
{{第一行数据的初始化列表},{第二行数据的初始化列表}, ...}的格式。 - 如果 初始化列表 内表达式的个数小于数据元素的个数,则后面其余的数据补充 零值。
- 行整数表达式m 和 初始化列表 不能同时丢失,否则编译器则因无法确定数组的行数而报错。
, ...表达式后面还可以声明变量,指针,数组等其它变量。- 数组的每一行有自己的数据类型,每一行的数据类型是
数据类型[列整数表达式n]。 - 数组有自己的数据类型,数组的数据类型是
数据类型[行整数表达式m][列整数表达式n]。
示例:
// filename: 2d_array.c
#include <stdio.h>
int main(int argc, char *argv[]) {
// 声明 2 行 3 列一共含有 6 个整型数据元素的二维数组。
int arr2d_1[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 声明 10 行 20 列的字符型数据的二维数组,内部数据元素都是 '\0'。
char arr2d_2[10][20] = {};
// 声明 3 行 4 列的短整型数据的二维数组,内部数据元素是如下结构:
// 1 2 0 0 //(初始化列表没有给出部分补充 0)
// 5 6 7 0
// 0 0 0 0
short int arr2d_3[][4] = {{1, 2}, {5, 6, 7}, {}};
// 声明 5 行 2 列整数数据的二维数组,不进行初始化:
int arr2d_4[5][2];
printf("sizeof(arr2d_1): %ld\n", sizeof(arr2d_1));
printf("sizeof(arr2d_2): %ld\n", sizeof(arr2d_2));
printf("sizeof(arr2d_3): %ld\n", sizeof(arr2d_3));
printf("sizeof(arr2d_4): %ld\n", sizeof(arr2d_4));
return 0;
}
运行结果如下:
weimingze@mzstudio:~$ gcc -o 2d_array 2d_array.c
weimingze@mzstudio:~$ ./2d_array
sizeof(arr2d_1): 24
sizeof(arr2d_2): 200
sizeof(arr2d_3): 24
sizeof(arr2d_4): 40
下面我们来看一下 二维数组 int arr2d_1[2][3] = {{1, 2, 3}, {4, 5, 6}}; 的逻辑结构和物理存储结构。
上述二维数组逻辑结构是 2 行 3 列的二维网格如下:
+-----+-----+-----+
| 1 | 2 | 3 |
+-----+-----+-----+
| 4 | 5 | 6 |
+-----+-----+-----+
物理存储结构是 连续的 6 个短整型数据进行存储的一段内存,如下:
----+-----+-----+-----+-----+-----+-----+----
... | 1 | 2 | 3 | 4 | 5 | 6 | ...
----+-----+-----+-----+-----+-----+-----+----