Branching and looping are the core of every algorithm, and C++ has a few forms (range-for, init-statements) that make them safer.
if (cond) { ... } else if (other) { ... } else { ... } works as in most languages. Always use braces in real code; a dangling else or an added second line under an unbraced if is a classic bug.
Since C++17, if and switch can declare a variable scoped to the statement: if (auto it = m.find(k); it != m.end()) { ... }. The variable doesn't leak into the surrounding code.
switch jumps to a matching case label on an integer, char or enum value. Execution falls through into the next case unless you break; several labels can share code deliberately, and [[fallthrough]]; marks intentional fall-through so the compiler doesn't warn. default handles everything else. You can't switch on strings.
Loops:
while (cond) { ... }checks before each iteration;do { ... } while (cond);runs the body at least once.for (int i = 0; i < n; ++i)is the counting loop.- Range-based for,
for (int x : v), visits every element of a container or array. Usefor (const auto& x : v)to avoid copying big elements andfor (auto& x : v)to modify them.
break leaves the innermost loop or switch and continue jumps to the next iteration. There's no labelled break; to exit nested loops, move them into a function and return.
Prefer range-for whenever you don't need the index; it can't go out of bounds. When you do need an index into a container, use std::size_t (or C++20 std::ssize for a signed size) to avoid signed/unsigned warnings.
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> scores{90, 45, 72, 100, 58};
int passed = 0;
for (int s : scores) { // range-based for
if (s < 50) continue; // skip failures
++passed;
}
for (int i = 0; i < 3; ++i) std::cout << i << ' '; // 0 1 2
std::cout << '\n';
int n = 1;
while (n < 100) n *= 3; // 1 3 9 27 81 243
if (int best = scores[3]; best == 100) // C++17 if with initializer
std::cout << "perfect score\n";
char cmd = 'q';
switch (cmd) {
case 'a': std::cout << "add\n"; break;
case 'q':
case 'x': std::cout << "quit\n"; break; // two labels share code
default: std::cout << "unknown\n";
}
std::cout << passed << ' ' << n << '\n'; // 4 243
}Remember
- Use
for (const auto& x : c)to visit elements without copying switchfalls through withoutbreak; mark intentional cases with[[fallthrough]]if (init; cond)keeps helper variables scoped to the branch
Watch out for
- Forgetting
breakin a switch case, so the next case's code runs too.