二维数组¶
二维数组的定义¶
一维数组像一排格子,二维数组像一张表,有行、有列。
开了 110 行、110 列,一共能存 110 × 110 个 int。
数组的访问¶
先行,后列。
这里的行列下标,也都是从 0 开始。
下面的例子统一处理 n 行 m 列,1 <= n, m <= 100,从下标 0 开始存。
实际数据用到 a[0][0] 到 a[n-1][m-1]。
数组的初始化¶
数组开全局,默认都是 0
局部数组,也可以用大括号清零
普通局部数组如果不初始化,不能直接读取元素值。
使用两层 for 循环赋值
这里只清零实际使用的 n 行 m 列,不是整个数组容量。
使用大括号给出初始值
按行依次填,剩余位置补 0:
每行也可以单独用大括号:
每行没写够的部分补 0:
数组的输入输出¶
外层管行,内层管列。一行输出完,再换行。
#include <iostream>
using namespace std;
int a[110][110];
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) cin >> a[i][j];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) cout << a[i][j] << ' ';
cout << '\n';
}
return 0;
}
注意输出换行,这里经常出错。
一行输出完,再换行。cout << '\n'; 写在内层循环外面、外层循环里面。
- 漏写换行,所有数据会挤在同一行。
- 把换行写进内层循环,会变成每输出一个数就换一行。
数组的遍历¶
逐行遍历,先走完一行,再换下一行。上面的输出就是这种写法。
逐列遍历,先走完一列,再换下一列。
注意:这里每输出完一列,就换行,不是按原表格的行来输出。
用常量开数组¶
二维数组,容量要把行数、列数乘起来算。
常见环境中,一个 int 是 4 字节,1000 × 1000 个 int 约占 4 MB。
能开多大,还要看题目的内存限制、其他数据的占用,以及数组放在全局还是局部。
较大的数组,优先开全局,但开全局也不能突破内存限制。
常见错误¶
行列写反
n 行 m 列,行下标用 i < n,列下标用 j < m。
测试时,除了正方形,还要试一试 2 行 3 列,行列写反才容易暴露出来。
一维越界,也是越界。
int a[3][4]; 的行下标是 0~2,列下标是 0~3。
即使内存看起来挨着,也不能用 a[0][4] 代替 a[1][0]。
memset(先不看)¶
需要头文件 <cstring>。
-1、0x3f 的用法与一维数组相同,别把 memset 当成逐个整数赋值。