所谓的 “遍历数组”,指的就是把数组中的每一个元素按顺序访问一遍。如果一个数组里有几十个甚至上百个元素,我们总不能手动去写 arr[0]、arr[1]、arr[2]……那样写起来实在太麻烦了。
遇到这种情况,我们可以借助 for 循环来控制下标,让程序自动把数组中的所有元素依次访问一遍。如果只需要从头到尾读取或修改元素、不关心当前元素的下标位置,还可以使用更简洁的范围 for 循环,下一节我们就会专门介绍。
使用 for 循环遍历数组
使用下标 for 循环遍历数组时,我们可以灵活控制下标的变化方向,既可以从头到尾 “正序遍历”,也可以从尾到头 “倒序遍历”。
1. 正序遍历数组
在 C++ 中,最基础的遍历方式就是让循环变量 i 从下标 0 开始,每一轮循环后加 1,并在循环体内部通过 arr[i] 依次访问对应位置的元素。
语法:
for (int i = 0; i < 数组长度; i++) {
// 访问 数组名[i]
}说明:
假设数组的长度是 5,那么合法的下标范围就是 0 ~ 4。因此在编写 for 循环时,循环变量 i 要从 0 开始,并且循环条件要写成小于数组长度(如 i < 5)。
示例 1:按顺序遍历数组
#include <iostream>
int main() {
int arr[5] = {12, 24, 36, 48, 60};
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << '\n';
}
return 0;
}运行结果如下。
12
24
36
48
60分析:
在这个例子中,for (int i = 0; i < 5; i++) 让下标变量 i 从 0 依次变化到 4,一共执行 5 轮循环,按顺序打印出 arr[0] 到 arr[4] 的值。当第 5 轮结束后 i 变为 5,条件 5 < 5 返回 false,循环随之结束。
在示例 1 中,我们在循环条件里直接写死了数字 5。在实际开发中,我们更推荐先调用 std::size() 函数获取数组长度,再放进循环条件中。这样就算后面增删了初始元素,循环也会自动适应新的长度。
示例 2:结合 std::size() 遍历
#include <iostream>
#include <iterator>
int main() {
int arr[] = {12, 24, 36, 48, 60};
int len = std::size(arr);
for (int i = 0; i < len; i++) {
std::cout << arr[i] << ' ';
}
return 0;
}运行结果如下。
12 24 36 48 60分析:
int len = std::size(arr); 表示先算出数组 arr 的长度 5 并保存到变量 len 中,随后在 for 循环中使用 i < len 控制循环次数。同时,这里把循环体内的换行符 '\n' 换成了空格 ' ',让 5 个元素在同一行隔开显示。
在编写遍历数组的循环条件时,小伙伴们要特别注意:判断条件一定要写成小于号 <,而不能写成小于等于号 <=:
int len = std::size(arr);
// 正确方式
for (int i = 0; i < len; i++) {
std::cout << arr[i] << ' ';
}
// 错误方式
for (int i = 0; i <= len; i++) {
std::cout << arr[i] << ' ';
}为什么不能写成 i <= len 呢?因为当数组长度为 5 时,合法下标只有 0 ~ 4。如果写成 i <= len,最后一轮循环 i 会变成 5,去访问根本不存在的 arr[5],从而引发数组下标越界。
2. 倒序遍历数组
如果我们希望从最后一个元素开始,从后往前倒着输出整个数组,只需要让起始下标 i 从 len - 1 开始,每轮循环减 1,直到下标 0 为止。
示例 3:倒序遍历数组
#include <iostream>
#include <iterator>
int main() {
int arr[] = {12, 24, 36, 48, 60};
int len = std::size(arr);
for (int i = len - 1; i >= 0; i--) {
std::cout << arr[i] << ' ';
}
return 0;
}运行结果如下。
60 48 36 24 12分析:
int i = len - 1 表示将起始下标设为最后一个元素的下标 4,每轮循环结束后执行 i-- 让下标减 1。这样 i 就会依次取 4、3、2、1、0,刚好把数组从尾到头访问了一遍。
这里大家还要留意循环条件必须写成 i >= 0。如果漏掉了等号写成 i > 0,下标为 0 的第 1 个元素 arr[0] 就会被漏掉。
批量修改数组元素
在遍历数组的过程中,我们不仅可以读取 arr[i] 的值,还可以直接对 arr[i] 重新赋值,从而对数组中的所有元素进行批量修改。下面我们来看一个例子。
示例 4:批量修改数组元素
#include <iostream>
#include <iterator>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int len = std::size(arr);
// 将每个元素的值加 5
for (int i = 0; i < len; i++) {
arr[i] += 5;
}
// 输出修改后的结果
for (int i = 0; i < len; i++) {
std::cout << arr[i] << ' ';
}
return 0;
}运行结果如下。
15 25 35 45 55分析:
arr[i] += 5; 这句代码等价于 arr[i] = arr[i] + 5,作用是将下标 i 处的元素在原有值的基础上加 5。当第 1 个 for 循环执行完毕后,原数组中的 5 个元素就已经全部更新成了 15、25、35、45、55。
遍历数组的常见应用
在实际开发中,我们遍历数组往往不只是为了把元素打印出来,更多时候是为了对整组数据进行统计或查找,其中最常见的就是 “数组求和” 与 “找出最大值”。
1. 计算数组元素之和
想要计算数组中所有元素的总和,我们可以先在循环外部定义一个初始值为 0 的累加变量 sum,然后在循环中把每个元素依次加到 sum 上。
示例 5:计算数组元素之和
#include <iostream>
#include <iterator>
int main() {
int arr[] = {12, 24, 36, 48, 60};
int len = std::size(arr);
int sum = 0;
for (int i = 0; i < len; i++) {
sum += arr[i];
}
std::cout << "元素之和:" << sum;
return 0;
}运行结果如下。
元素之和:180分析:
进入循环之前,一定要先写 int sum = 0 将累加变量清零,避免里面残留随机的垃圾值。接着在每一轮循环中,通过 sum += arr[i] 把当前元素加到 sum 里。等 5 轮循环全部执行完毕,sum 保存的就是 5 个元素的总和 180。
2. 找出数组中的最大值
如何找出数组中的最大值呢?你可以把这个过程想象成 “打擂台”:先假设数组的第 1 个元素 arr[0] 是擂主,把它保存到变量 max 中。然后从下标 1 开始,依次拿后面的元素跟 max 比较,只要遇到比 max 更大的元素,就让它替换掉原来的 max。
示例 6:找出数组最大值
#include <iostream>
#include <iterator>
int main() {
int arr[] = {36, 42, 97, 64, 15, 84};
int len = std::size(arr);
int max = arr[0]; // 先假设第 1 个元素最大
// 从下标 1 开始依次比较
for (int i = 1; i < len; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
std::cout << "最大值:" << max;
return 0;
}运行结果如下。
最大值:97分析:
在这个例子中,int max = arr[0]; 先把第 1 个元素 36 作为初始的最大值,因此后面的 for 循环直接从下标 i = 1 开始比较即可,不需要再让 arr[0] 和自己比一次。整个比较过程如下:
- 当 i = 1 时:
arr[1]为 42,满足42 > 36,max更新为 42。 - 当 i = 2 时:
arr[2]为 97,满足97 > 42,max更新为 97。 - 当 i = 3 ~ 5 时:后面的 64、15、84 都不大于 97,条件不成立,
max最终保持为 97。
注意 在求数组最大值时,max 的初始值一定要设为数组的第 1 个元素 arr[0],千万不要随便写成 int max = 0。比如当数组里的元素全部是负数 {-12, -5, -28} 时,如果把初始值设为 0,就会得出最大值是 0 的错误结果。
