这条语句是在 C 语言中声明一个二维整型数组。

(图片来源网络,侵删)
语句分解
我们把 int a[3][3]; 拆开来看:
int: 这是数据类型,它表示这个数组将用来存储整数(integer)。a: 这是数组名,你可以把它想象成一个给这个数组区域起的名字,之后你就可以通过这个名字来访问数组中的元素。[3][3]: 这是维度说明符,它定义了数组的结构。- 第一个
[3]表示这个数组有 3 行。 - 第二个
[3]表示每一行有 3 列。
- 第一个
int a[3][3]; 的完整意思是:*声明一个名为 a 的二维数组,它有 3 行 3 列,总共可以存储 3 3 = 9 个整数。**
内存中的形象化
你可以把这个二维数组想象成一个表格或者矩阵:
列 0 列 1 列 2
行 0 a[0][0] a[0][1] a[0][2]
行 1 a[1][0] a[1][1] a[1][2]
行 2 a[2][0] a[2][1] a[2][2]
a[i][j]这种形式被称为下标表示法,用来访问数组中特定位置的元素。i代表行索引(从 0 开始)。j代表列索引(从 0 开始)。
重要提示:在 C 语言中,数组索引总是从 0 开始的,对于一个 3x3 的数组,有效的行索引是 0, 1, 2,有效的列索引也是 0, 1, 2,尝试访问 a[3][3] 会导致数组越界,这是非常危险的错误。

(图片来源网络,侵删)
如何初始化和赋值
声明数组后,你可以用多种方式给它赋初值。
完全初始化
在声明时,按行顺序列出所有元素的值。
int a[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
这种方式非常清晰,每个内层的 对应一行。
不完全初始化(部分初始化)
如果你只提供了部分初始值,C 编译器会自动将未指定的元素初始化为 0。

(图片来源网络,侵删)
// 只初始化第一行,其余所有元素自动为 0
int b[3][3] = {
{1, 2, 3}
};
// 或者只提供前几个值,按行顺序填充
// b[0][0]=1, b[0][1]=2, b[0][2]=3, b[1][0]=4, 其余为 0
int c[3][3] = {
{1, 2, 3},
{4}
};
连续初始化(不推荐)
你也可以不使用内层花括号,把所有值写在一个大括号里,编译器会按行顺序依次填充。
// 1 填充 a[0][0], 2 填充 a[0][1], ..., 9 填充 a[2][2]
int d[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
这种方式虽然代码简洁,但可读性差,尤其是当数组变大时,很容易出错。强烈推荐使用方式一。
如何访问和遍历数组
通常使用嵌套的 for 循环来访问二维数组的所有元素。
示例代码:声明、初始化、打印
这是一个完整的 C 语言程序示例,展示了如何声明、初始化并打印一个 3x3 的整型数组。
#include <stdio.h>
int main() {
// 1. 声明并初始化一个 3x3 的整型数组
int a[3][3] = {
{10, 20, 30},
{40, 50, 60},
{70, 80, 90}
};
// 2. 使用嵌套 for 循环遍历并打印数组
// 外层循环控制行
for (int i = 0; i < 3; i++) {
// 内层循环控制列
for (int j = 0; j < 3; j++) {
// 打印 a[i][j] 的值
printf("%d\t", a[i][j]);
}
// 每打印完一行,就换行
printf("\n");
}
return 0;
}
程序输出:
10 20 30
40 50 60
70 80 90
在内存中的存储方式(重要概念)
虽然二维数组看起来像一个二维表格,但在计算机内存中,它是以一维、连续的方式存储的,它是按行优先(Row-Major Order)存储的。
这意味着数组的元素在内存中是这样排列的:
a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2], a[2][0], a[2][1], a[2][2]
所有第一行的元素排在一起,然后是第二行,以此类推。
| 特性 | 描述 |
|---|---|
| 语句 | int a[3][3]; |
| 名称 | 二维整型数组 |
| 含义 | 声明一个名为 a 的数组,包含 3 行 3 列,共 9 个整数。 |
| 索引 | 从 0 开始,有效范围:a[0][0] 到 a[2][2]。 |
| 初始化 | 推荐 的形式,可读性高。 |
| 遍历 | 使用两个嵌套的 for 循环,外层循环行,内层循环列。 |
| 内存 | 在内存中是连续存储的,按行优先排列。 |
