The counting for#
for (int i = 0; i < 5; i++) {
cout << i << " "; // 0 1 2 3 4
}
Start at 0, keep going while i < 5, add one each round. Those are exactly the valid positions of a collection of five items.
Range-based for#
When you want each item and not its position, C++ has a shorter loop:
vector<int> nums = {4, 8, 15, 16, 23, 42};
long long total = 0;
for (int x : nums) {
total += x;
}
for (char c : string("hey")) {
cout << c << "\n";
}
Read for (int x : nums) as "for each x in nums". Each x is a copy. To change the items, take a reference:
for (int &x : nums) x *= 2; // doubles every element in place
For large items such as strings, const auto & avoids copying without allowing changes:
for (const auto &word : words) cout << word << "\n";
while and do while#
int n = 4071, digits = 0;
while (n > 0) {
n /= 10;
digits++;
}
int x;
do {
cin >> x;
} while (x <= 0); // runs at least once
Something inside a while must change so it eventually stops.
break and continue#
break leaves the loop; continue skips to the next round:
for (int x : nums) {
if (x < 0) break;
if (x % 2 == 1) continue;
cout << x << "\n";
}
Comparing sizes#
v.size() is unsigned, so v.size() - 1 on an empty vector is not -1 but a huge number, and a loop like for (int i = 0; i < v.size() - 1; i++) misbehaves. Convert first:
int n = v.size();
for (int i = 0; i + 1 < n; i++) {
// compare v[i] with v[i + 1]
}
Cost#
Two nested loops over n items take n × n steps. Fine for a thousand items, far too slow for a hundred thousand. Most of algorithms is turning the second loop into something smarter.
Key points#
for (int i = 0; i < n; i++)counts;for (auto x : v)visits each item.- Use
&in a range-for to change items, andconst auto &to avoid copies. size()is unsigned: store it in anintbefore subtracting.breakleaves;continueskips ahead.
Next: functions, and passing by reference.