C++: 多维数组

最后更新:2026-08-26

一维数组像"一排信箱",那如果要表示表格数据(如Excel表格、棋盘、矩阵)呢?

这就需要多维数组——数组的数组。


1. 二维数组

(1) 1.1 什么是二维数组?

二维数组就是"数组的数组"——每个元素本身又是一个数组。

生活场景 程序中的对应
Excel 表格(行 × 列) 二维数组
棋盘(8 × 8) 二维数组
矩阵(3 × 3) 二维数组

(2) 1.2 声明二维数组

语法:

▶ 示例 2:代码示例(难度⭐)

CPP
类型 数组名[行数][列数];
▶ 试一试

输出:

TEXT 📖 仅展示
(程序输出)

示例:

CPP
int matrix[3][4]; // 3 行 4 列的二维数组

内存布局:

TEXT 📖 仅展示
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 声明时初始化

CPP
#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 部分初始化

CPP
#include <iostream>

int main() {
 int matrix[3][4] = {
 {1, 2}, // 第一行只初始化前两个,剩下的变成 0
 {5}, // 第二行只初始化第一个,剩下的变成 0
 {} // 第三行全部变成 0
 };
 
 return 0;
}

💡 提示: 省略的行或列会自动初始化为 0。



3. 访问二维数组元素

(1) 3.1 读取元素

CPP
#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 修改元素

CPP
#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 循环遍历

CPP
#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 矩阵相加(难度⭐⭐)

CPP
#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;
}
▶ 试一试

输出:

TEXT 📖 仅展示
矩阵 C = A + B:
10	10	10	
10	10	10	
10	10	10	


6. 三维数组(选学)

(1) 6.1 什么是三维数组?

三维数组就是"二维数组的数组"。

生活场景 程序中的对应
多个二维表格叠在一起 三维数组
立方体(长 × 宽 × 高) 三维数组

(2) 6.2 声明和访问

CPP
#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 下标顺序写反

错误示例:

CPP
#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 数组越界

错误示例:

CPP
#include <iostream>

int main() {
 int matrix[3][4];
 
 matrix[3][0] = 5; // ❌ 越界!行下标最大是 2
 matrix[0][4] = 10; // ❌ 越界!列下标最大是 3
 
 return 0;
}

💡 提示: 二维数组 matrix[m][n] 的下标范围是:


▶ 示例 3:遍历二维数组计算总和(难度⭐)

CPP
#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;
}
▶ 试一试

输出:

TEXT 📖 仅展示
总分: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:不能用普通数组(大小必须在编译时确定)。

解决方法:

  1. std::vector<std::vector<int>>(推荐,后面会学)
  2. 用动态内存分配(后面会学指针和 new

Q:关于multi dimensional arrays最重要的是什么? A:先理解核心概念,再通过实践例子来巩固。

Q:如何高效练习multi dimensional arrays? A:从简单例子开始,逐步增加难度,务必测试你的代码。

📖 小节


📝 作业

  1. 基础题 (Difficulty ⭐): 声明一个 2×3 的二维数组,初始化为:
TEXT 📖 仅展示
1 2 3
4 5 6

然后输出这个数组。

  1. 进阶题 (Difficulty ⭐⭐): 写一个函数 void transpose(int arr[3], int rows),计算 3×3 矩阵的转置(行列互换)。
TEXT 📖 仅展示
原矩阵:
1 2 3
4 5 6
7 8 9

转置后:
1 4 7
2 5 8
3 6 9
  1. 挑战题 (Difficulty ⭐⭐⭐): 写一个程序,实现"井字棋"游戏(Tic-Tac-Toe):
  2. 用 3×3 二维数组表示棋盘
  3. 两个玩家轮流下棋(一个用 X,一个用 O
  4. 判断是否有玩家连成一条线(横、竖、斜)

8. 🚀 下一步

学会了多维数组,接下来我们学习 C 风格字符串(第18课)—— 用字符数组表示字符串,理解 C++ 字符串的底层原理。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏