C++: 多维数组
最后更新:2026-08-26
一维数组像"一排信箱",那如果要表示表格数据(如Excel表格、棋盘、矩阵)呢?
这就需要多维数组——数组的数组。
1. 二维数组
(1) 1.1 什么是二维数组?
二维数组就是"数组的数组"——每个元素本身又是一个数组。
| 生活场景 | 程序中的对应 |
|---|---|
| Excel 表格(行 × 列) | 二维数组 |
| 棋盘(8 × 8) | 二维数组 |
| 矩阵(3 × 3) | 二维数组 |
(2) 1.2 声明二维数组
语法:
▶ 示例 2:代码示例(难度⭐)
类型 数组名[行数][列数];
输出:
(程序输出)
示例:
int matrix[3][4]; // 3 行 4 列的二维数组
内存布局:
matrix[0][0] matrix[0][1] matrix[0][2] matrix[0][3] ← 第 0 行
matrix[1][0] matrix[1][1] matrix[1][2] matrix[1][3] ← 第 1 行
matrix[2][0] matrix[2][1] matrix[2][2] matrix[2][3] ← 第 2 行
💡 重点: 二维数组的第一个下标是行,第二个下标是列。
2. 初始化二维数组
(1) 2.1 声明时初始化
#include <iostream>
int main() {
// 方法一:按行初始化
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 方法二:按顺序初始化(不推荐,可读性差)
int matrix2[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
return 0;
}
(2) 2.2 部分初始化
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2}, // 第一行只初始化前两个,剩下的变成 0
{5}, // 第二行只初始化第一个,剩下的变成 0
{} // 第三行全部变成 0
};
return 0;
}
💡 提示: 省略的行或列会自动初始化为 0。
3. 访问二维数组元素
(1) 3.1 读取元素
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
std::cout << "第一行第一列:" << matrix[0][0] << std::endl; // 1
std::cout << "第二行第三列:" << matrix[1][2] << std::endl; // 7
std::cout << "第三行第四列:" << matrix[2][3] << std::endl; // 12
return 0;
}
(2) 3.2 修改元素
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
matrix[1][2] = 100; // 把第二行第三列改成 100
std::cout << "修改后的元素:" << matrix[1][2] << std::endl; // 100
return 0;
}
4. 遍历二维数组
(1) 4.1 用嵌套 for 循环遍历
#include <iostream>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 外层循环:遍历行
for (int i = 0; i < 3; i++) {
// 内层循环:遍历列
for (int j = 0; j < 4; j++) {
std::cout << matrix[i][j] << "\t";
}
std::cout << std::endl; // 换行
}
return 0;
}
💡 重点: 外层循环控制行,内层循环控制列。
5. 实战:矩阵相加
▶ 示例 1:两个 3×3 矩阵相加(难度⭐⭐)
#include <iostream>
int main() {
int A[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int B[3][3] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int C[3][3]; // 结果矩阵
// 矩阵相加
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
C[i][j] = A[i][j] + B[i][j];
}
}
// 输出结果
std::cout << "矩阵 C = A + B:" << std::endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
std::cout << C[i][j] << "\t";
}
std::cout << std::endl;
}
return 0;
}
输出:
矩阵 C = A + B:
10 10 10
10 10 10
10 10 10
6. 三维数组(选学)
(1) 6.1 什么是三维数组?
三维数组就是"二维数组的数组"。
| 生活场景 | 程序中的对应 |
|---|---|
| 多个二维表格叠在一起 | 三维数组 |
| 立方体(长 × 宽 × 高) | 三维数组 |
(2) 6.2 声明和访问
#include <iostream>
int main() {
int cube[2][3][4]; // 2 层,3 行,4 列
// 初始化
cube[0][1][2] = 5; // 第 0 层,第 1 行,第 2 列
cube[1][2][3] = 10; // 第 1 层,第 2 行,第 3 列
return 0;
}
💡 提示: 三维数组很难可视化,通常只在科学计算、图形学里用。实际项目中,优先考虑用 std::vector(后面会学)。
7. 常见错误
(1) 7.1 下标顺序写反
错误示例:
#include <iostream>
int main() {
int matrix[3][4];
matrix[1][2] = 5; // ✅ 正确:第一行,第二列
matrix[2][1] = 10; // ✅ 正确:第二行,第一列
// ❌ 错误:把行和列写反了
// 本来想访问第一行第二列,结果访问了第二行第一列
std::cout << matrix[2][1] << std::endl;
return 0;
}
(2) 7.2 数组越界
错误示例:
#include <iostream>
int main() {
int matrix[3][4];
matrix[3][0] = 5; // ❌ 越界!行下标最大是 2
matrix[0][4] = 10; // ❌ 越界!列下标最大是 3
return 0;
}
💡 提示: 二维数组 matrix[m][n] 的下标范围是:
- 行:
0到m-1 - 列:
0到n-1
▶ 示例 3:遍历二维数组计算总和(难度⭐)
#include <iostream>
int main() {
int scores[3][4] = {
{85, 90, 78, 92},
{88, 76, 95, 80},
{70, 85, 88, 90}
};
int total = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
total += scores[i][j];
}
}
std::cout << "总分:" << total << std::endl;
std::cout << "平均:" << total / 12 << std::endl;
return 0;
}
输出:
总分:967
平均:80
❓ 常见问题
Q:二维数组在内存里是怎么存的? A:C++ 的二维数组是行优先(Row-Major)——先存完第一行的所有元素,再存第二行,以此类推。 > > matrix[3][4] 在内存里的布局: > [0][0] [0][1] [0][2] [0][3] [1][0] [1][1] ... [2][3] > Q:怎么把二维数组传给函数? A:需要传数组名、行数、列数。 > > void printMatrix(int arr[4], int rows) { // 列数必须写! > for (int i = 0; i < rows; i++) { > for (int j = 0; j < 4; j++) { > std::cout << arr[i][j] << "\t"; > } > std::cout << std::endl; > } > } > Q:二维数组能改成动态大小吗? A:不能用普通数组(大小必须在编译时确定)。
解决方法:
- 用
std::vector<std::vector<int>>(推荐,后面会学)- 用动态内存分配(后面会学指针和
new)
Q:关于multi dimensional arrays最重要的是什么? A:先理解核心概念,再通过实践例子来巩固。
Q:如何高效练习multi dimensional arrays? A:从简单例子开始,逐步增加难度,务必测试你的代码。
📖 小节
- 二维数组是"数组的数组",适合表示表格数据
- 声明:
类型 数组名[行数][列数]; - 访问:
数组名[行下标][列下标] - 遍历:用嵌套 for 循环(外层行,内层列)
- C++ 的二维数组是行优先存储
- 二维数组作为参数时,列数必须写
📝 作业
- 基础题 (Difficulty ⭐): 声明一个 2×3 的二维数组,初始化为:
1 2 3
4 5 6
然后输出这个数组。
- 进阶题 (Difficulty ⭐⭐):
写一个函数
void transpose(int arr[3], int rows),计算 3×3 矩阵的转置(行列互换)。
原矩阵:
1 2 3
4 5 6
7 8 9
转置后:
1 4 7
2 5 8
3 6 9
- 挑战题 (Difficulty ⭐⭐⭐): 写一个程序,实现"井字棋"游戏(Tic-Tac-Toe):
- 用 3×3 二维数组表示棋盘
- 两个玩家轮流下棋(一个用
X,一个用O) - 判断是否有玩家连成一条线(横、竖、斜)
- 二维数组:行优先存储,声明方式 类型 数组名[行][列]
- 嵌套 for 循环遍历二维数组
- 多维数组常用场景:矩阵、表格、图像
- 二维数组作为函数参数时必须指定列数
- 不规则二维数组可用指针数组实现
8. 🚀 下一步
学会了多维数组,接下来我们学习 C 风格字符串(第18课)—— 用字符数组表示字符串,理解 C++ 字符串的底层原理。