第 5 课
数组
一句话答案:数组是一排同类型的盒子,在内存里挨着放,编号从 0 开始。int a[5] 给你五个 int,名字叫 a[0] 到 a[4]。
声明、填充、打印
#include <iostream>
using namespace std;
int main() {
int a[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
cout << "a[" << i << "] = " << a[i] << endl;
}
return 0;
}
注意循环边界:i < 5,因为合法下标是 0..4。写成 i <= 5 就会读到 a[5],它并不存在。
把输入读进数组
数组最擅长「先知道长度、再读一串值」的场景 —— 先读 n,再读 n 个数:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int a[100];
for (int i = 0; i < n; i++) cin >> a[i];
int sum = 0;
for (int i = 0; i < n; i++) sum += a[i];
cout << "sum = " << sum << endl;
return 0;
}
数组开得比需要的更大(100),因为 C++ 的数组长度在编译时就固定了 —— 不能改大小。这正是数组最大值和奇偶统计的形状。
滚动最大值模式
你会写上一百遍的最有用数组模式:一边走一边带着当前最优值。
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int a[100];
for (int i = 0; i < n; i++) cin >> a[i];
int best = a[0];
for (int i = 1; i < n; i++) {
if (a[i] > best) best = a[i];
}
cout << "max = " << best << endl;
return 0;
}
用 a[0](而不是 0)给 best 做种子,才让全负数输入也能正确。用 0 做种子是最大值类问题最常见的 bug —— 换成 0 试试,这段输入立刻出错。
二维数组
行和列需要两个下标:a[row][col]。
#include <iostream>
using namespace std;
int main() {
int g[2][3] = {{1, 2, 3}, {4, 5, 6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << g[i][j] << " ";
}
cout << endl;
}
return 0;
}
约定很重要:第一个下标是行。写反了,网格就会以转置的样子打印出来 —— 见矩阵转置。
三个数组 bug
- 差一。把
<写成<=,就会读到末尾之外。C++ 不会拦你。 - 开得太小。声明
int a[10]却读 20 个值,会写到不属于你的内存里。 - 求和没初始化。
int sum; for (...) sum += a[i];是往垃圾值上加。写int sum = 0;。