Skip to content

Control Flow

Control flow statements allow your program to make decisions and repeat actions. Modern C++ introduces powerful features to make these safer and more expressive.

Conditional Statements

if and else

The standard if statement works as expected. C++17 introduced init-statements for if, allowing you to limit the scope of variables.

// Traditional
int status = check_sensor();
if (status == 0) {
    // ...
}

// C++17 Init-Statement (Preferred)
// 'status' is only visible inside the if/else block
if (int status = check_sensor(); status == 0) {
    std::cout << "Sensor OK";
} else {
    std::cout << "Error: " << status;
}

switch Statement

Useful for checking a variable against multiple constant values.

switch (command) {
    case 'A':
        start_motor();
        break; // Don't forget break!
    case 'B':
        stop_motor();
        break;
    default:
        std::cout << "Unknown command";
}

Fallthrough: If you omit break, execution continues to the next case. In C++17, use [[fallthrough]]; to indicate this is intentional.

if constexpr (C++17)

This is a compile-time conditional. The "false" branch is discarded during compilation. It is essential for template programming.

1
2
3
4
5
6
7
8
template <typename T>
void print_value(T value) {
    if constexpr (std::is_pointer_v<T>) {
        std::cout << "Pointer points to: " << *value << "\n";
    } else {
        std::cout << "Value: " << value << "\n";
    }
}

Loops

while and do-while

  • while: Checks condition before the loop body.
  • do-while: Checks condition after the loop body (guaranteed to run at least once).
1
2
3
4
5
6
7
while (is_running) {
    process_data();
}

do {
    input = read_key();
} while (input != 'q');

Standard for Loop

The classic C-style loop.

1
2
3
for (int i = 0; i < 10; ++i) {
    std::cout << i << " ";
}

Range-based for Loop (Modern C++)

This is the preferred way to iterate over arrays, vectors, and other containers. It eliminates off-by-one errors.

std::vector<int> pins = {17, 27, 22};

// Iterate by value (copies elements)
for (int pin : pins) {
    setup_pin(pin);
}

// Iterate by reference (modifies elements)
for (int& pin : pins) {
    pin = 0; // Reset all
}

// Iterate by const reference (read-only, no copy)
for (const auto& pin : pins) {
    std::cout << "Pin: " << pin << "\n";
}

Jump Statements

  • break: Exits the nearest loop or switch.
  • continue: Skips the rest of the current iteration and starts the next one.
  • return: Exits the function.
1
2
3
4
5
for (int i = 0; i < 100; ++i) {
    if (i % 2 == 0) continue; // Skip even numbers
    if (i > 50) break;        // Stop after 50
    std::cout << i << " ";
}