CC++ & Algorithm

C++二维数组的定义与使用

困难19
语言版本:C++Python
概述:学习如何创建像表格一样的二维数组,并存放和取出数据。

像表格一样存数据:C++二维数组入门

想象一下,你的班级有3排座位,每排有4个座位,每个座位上坐着一个同学。你想记住每个座位上同学的名字,最方便的办法就是画一张“座位表”——一个3行4列的表格,表格的每个格子对应一个座位。在C++里,这种表格叫做二维数组。它就像一张Excel表格,可以存放成行成列的数据,非常适合用来记录考试成绩、游戏棋盘、商品价格表等等。


1. 定义二维数组:告诉电脑“我要画一张几行几列的表格”

定义二维数组的格式很简单:

数据类型 数组名[行数][列数];
  • 数据类型:每个格子里存放的数据类型,比如 int(整数)、double(小数)、char(字符)。
  • 数组名:你给这张表格取的名字,比如 seats(座位)、scores(分数)。
  • 行数列数:表格有几行、几列,必须是整数。

举个例子:
你要记录3排4列的座位上同学的(假设用学号表示),可以这样写:

int seats[3][4];  // 定义一张3行4列的座位表,每个格子存整数(学号)

这行代码会创建12个格子(3×4=12),每个格子都可以放一个整数。注意:行号和列号都是从0开始数的,所以第一行的行号是0,第二行是1,第三行是2;第一列的列号是0,第二列是1,第三列是2,第四列是3。

生活中的例子:
你想记录一个班级3次考试、每次考4个科目的成绩(整数),可以用:

int examScores[3][4];  // 3次考试 × 4个科目

2. 给二维数组赋值:往表格的格子里填数据

定义好二维数组后,你可以往每个格子里放数据。有两种方法:一个一个地填,或者在定义时一次性填好。

方法一:逐个格子赋值

就像在座位表上写名字一样,用 数组名[行号][列号] = 值; 的格式。

假设 seats 表格是3行4列,我们想给第一排第一列(第0行第0列)的同学学号设为1101,第二排第三列(第1行第2列)的同学学号设为1224:

seats[0][0] = 1101;   // 第1排第1列(行号0列号0)
seats[1][2] = 1224;   // 第2排第3列(行号1列号2)

注意下标从0开始,所以第一排是行号0,第一列是列号0。很多人刚开始会搞错,写成 seats[1][1] 以为是指第一排第一列,其实是第二排第二列。

方法二:定义时初始化——一次性填好整张表

如果你已经知道所有格子里的值,可以在定义数组的同时用大括号 { } 把它们列出来。格式为:

数据类型 数组名[行数][列数] = {
    {第0行所有列的值},
    {第1行所有列的值},
    ...
    {最后一行所有列的值}
};

例如,记录某个小组2行3列的成绩(满分10分):

int matrix[2][3] = { 
    {8, 7, 9},   // 第0行:语文、数学、英语
    {6, 10, 8}   // 第1行:科学、历史、体育
};

这相当于创建了一个2行3列的表格:

  • 第一行:8, 7, 9
  • 第二行:6, 10, 8

特别提醒: 初始化时大括号里的行数必须和定义的行数一致,列数也要一致。如果给了更多或更少,编译器会报错。


3. 从二维数组里取出数据:查找格子里的值

要取出某个格子里的值,直接用 数组名[行号][列号] 就行。比如把上面 matrix 中第一行第二列(行号0列号1)的值7拿出来,存到变量 score 里:

int subjectScore = matrix[0][1];  // subjectScore 的值就是7

你也可以直接输出它,或者用在计算中。举个例子,把全班同学的身高(厘米)存进二维数组,然后计算第一排的平均身高:

double height[3][4];  // 假设已经赋值
double sum = 0;
for (int col = 0; col < 4; col++) {
    sum = sum + height[0][col];  // 行号0代表第一排
}
double average = sum / 4;  // 第一排的平均身高

(这里用到了循环,如果你还没学,可以先跳过这个例子,重点是理解怎么取出单个数据。)


4. 新手最容易犯的错误

❌ 错误1:下标越界——超过了行数或列数

比如定义 int arr[3][4]; 表示行号范围02,列号范围03。如果你写成:

arr[3][0] = 5;  // 错误!行号3超出了范围(最大行号是2)

程序可能不会直接报错,但会覆盖其他变量的内存区域,导致数据错乱甚至程序崩溃。要记住:行数和列数都是定义时的数字,下标从0开始,最大下标是行数-1和列数-1。

❌ 错误2:混淆行和列的顺序

定义 int a[2][3]; 的意思是2行3列。但有些同学会误以为是2列3行。在访问时:

a[1][2] = 10;  // 这是第2行第3列(行号1列号2)

如果实际表格是2行3列,那么行号最大是1,列号最大是2,这样写是对的。但如果你反过来想成3行2列,就会把行和列弄反,可能下标越界或得到错误的数据。

❌ 错误3:初始化时行数或列数与定义不匹配

int b[2][3] = {{1,2},{3,4,5}};  // 第0行只给了2个数,第1行给了3个数

这样虽然不会编译错误,但第0行缺少的第2列会被自动设为0。但如果你给了更多列,比如 {{1,2,3,4},{5,6,7,8}},编译器会报错,因为列数超过了3。

建议:写初始化时,保持每行的列数一致,并且等于定义时的列数。

❌ 错误4:忘记下标从0开始,用1当第一行

比如定义 int grid[3][2]; 表示3行2列,有人想给第一行第一列赋值,却写成:

grid[1][1] = 10;  // 实际上是第二行第二列!

【正确写法】 第一行第一列是 grid[0][0],第一行第二列是 grid[0][1],第二行第一列是 grid[1][0],以此类推。


5. 完整可运行的代码示例:记录班级小组的跳绳次数

假设有3个小组,每组有2个同学。记录他们一分钟跳绳的次数,然后输出第2组第1个同学的成绩。

#include <iostream>
using namespace std;

int main() {
    // 定义3行2列的二维数组,记录跳绳次数
    int jumps[3][2];  // 3个小组,每组2人

    // 给每个格子赋值(手动输入或者直接写死,这里直接给值)
    jumps[0][0] = 120;   // 第1组 第1人
    jumps[0][1] = 135;   // 第1组 第2人
    jumps[1][0] = 110;   // 第2组 第1人
    jumps[1][1] = 145;   // 第2组 第2人
    jumps[2][0] = 130;   // 第3组 第1人
    jumps[2][1] = 125;   // 第3组 第2人

    // 取出第2组第1个人的成绩(行号1,列号0)
    int score = jumps[1][0];  // 第2组第1人(行1列0)
    cout << "第2组第1个同学一分钟跳绳次数是:" << score << endl;

    // 也可以直接输出
    cout << "第1组第2个同学次数:" << jumps[0][1] << endl;

    return 0;
}

运行结果:

第2组第1个同学一分钟跳绳次数是:110
第1组第2个同学次数:135

你可以修改这些数,或者用 cin 从键盘输入每个格子的值,让程序更灵活。


6. 相关指引

学会了二维数组,你还可以继续学习:

  • 一维数组:如果把二维数组比作一张表格,一维数组就是一行数据(或者一列数据)。二维数组其实就是由多个一维数组拼起来的。
  • 三维数组:在C++里,你还可以定义更高维的数组,比如 int cube[3][4][2]; 就像一堆叠在一起的表格,常用于表示空间坐标或时间序列数据。
  • 循环遍历二维数组:使用嵌套for循环可以访问所有格子,例如 for(int i=0; i<3; i++) for(int j=0; j<4; j++)

二维数组在算法竞赛和游戏开发中非常常见,比如井字棋棋盘、扫雷格子、迷宫地图等。弄清了它的定义、赋值和访问,你就掌握了一个强大的数据存储工具!

例题精讲

1单选题

执行以下代码后,数组 arr 中共有多少个元素? int arr[3][4];

A7
B12
C16
D20
2判断题

在C++中,二维数组在内存中是按行优先顺序存储的。

3填空题
以下代码计算一个 3×4 二维数组所有元素的和,请补全循环条件。
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int sum = 0;
for (int i = 0; i < ___; i++) {
    for (int j = 0; j < ___; j++) {
        sum += arr[i][j];
    }
}
4单选题

设有定义:int a[2][3] = {{1,2},{3,4,5}}; 则 a[1][2] 的值是?

A0
B3
C4
D5
5判断题

在C++中,定义二维数组时可以省略行数,但必须指定列数。