この章では、C++における「拡張for文(range-based for)」の使い方を学びます。配列やベクタのすべての要素に対して繰り返し処理を行うとき、より簡潔に記述できます。また、後半ではイテレータの概要にも触れます。
// 18_for_vs_range.cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {10, 20, 30, 40};
// 通常のfor文
for (int i = 0; i < nums.size(); i++) {
cout << nums[i] << " ";
}
cout << endl;
// 拡張for文(範囲for)
for (int n : nums) {
cout << n << " ";
}
cout << endl;
return 0;
}
for (データ型 変数名 : コンテナ名) {
// 処理
}
| 書き方 | 用途 |
|---|---|
for (int n : nums) |
値のコピーで読み取り(元の値は変わらない) |
for (const int& n : nums) |
参照で読み取り専用(効率的・安全) |
for (int& n : nums) |
参照で値を変更したいとき |
for (auto n : nums) |
型推論(型を省略して書ける) |
for (const int& n : nums) { ... } // 読み取り専用
for (int& n : nums) { ... } // 値を変更したい場合
// 18_range_modify.cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {1, 2, 3, 4, 5};
for (int& n : nums) {
n *= 2; // すべて2倍
}
for (int n : nums) {
cout << n << " ";
}
cout << endl;
return 0;
}
vector や list のようなコンテナは、要素を順にたどるために「イテレータ」という仕組みを持っています。範囲for文の内部では、自動的にイテレータが使われています。
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " ";
}
*it で要素、++it で次の要素へ進みます。C++のSTLでは頻繁に使われる概念です。
次のコードは何を出力しますか?
vector<int> data = {3, 6, 9};
for (const int& d : data) {
cout << d * 10 << " ";
}
const int& は参照ですが変更は禁止されています。出力は "30 60 90 " です。
次のコードを実行した後、nums の内容はどうなりますか?
vector<int> nums = {1, 2, 3};
for (int n : nums) {
n = n * 10;
}
for (int n : nums) cout << n << " ";
for (int n : nums) は値のコピーです。n = n * 10 はコピー変数を変更するだけで、元の nums は変わりません。元の値を変更したい場合は for (int& n : nums) と参照にする必要があります。
次のコードを実行したとき、出力はどれですか?
vector<int> nums = {1, 2, 3};
for (int& n : nums) {
n += 5;
}
for (int n : nums) cout << n << " ";
for (int& n : nums) は参照なので、元の要素を直接変更します。1+5=6、2+5=7、3+5=8 となり、出力は "6 7 8" です。
イテレータを使った次のコードと同等の範囲for文はどれですか?
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " ";
}
for (auto n : vec) は内部でイテレータを使っており、vec.begin() から vec.end() まで順番に要素を取り出す処理と同等です。コードが簡潔になります。
// main.cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> scores = {70, 80, 90, 60, 85};
for (int s : scores) {
cout << s << " ";
}
cout << endl;
int total = 0;
for (int s : scores) {
total += s;
}
cout << "平均: " << (double)total / scores.size() << endl;
return 0;
}
18_01_RangeFor の main.cpp をコピーして 18_02_RangeForMod に貼り付け、次の変更を加えてみましょう:
int& を使う)int&)で扱うconst int& が安全