C++ by Example
C++ by Example

Control Flow

2 min read

Control Flow

Control flow determines which code runs and when. C++ provides if/else, switch, and the ternary operator for branching.

if / else if / else

#include <iostream>

int main() {
    int score = 75;

    if (score >= 90) {
        std::cout << "A\n";
    } else if (score >= 80) {
        std::cout << "B\n";
    } else if (score >= 70) {
        std::cout << "C\n";
    } else {
        std::cout << "F\n";
    }
}

The condition must be a boolean expression. Any non-zero integer evaluates to true, but relying on this is bad style — write explicit comparisons.

if with initializer (C++17)

You can declare a variable in the if condition. Its scope is limited to the if block:

#include <map>
#include <string>
#include <iostream>

int main() {
    std::map<std::string, int> scores = {{"Alice", 95}, {"Bob", 82}};

    if (auto it = scores.find("Alice"); it != scores.end()) {
        std::cout << "Alice: " << it->second << "\n";
    }
    // it is not accessible here
}

This pattern avoids leaking the iterator into the surrounding scope.

switch

switch compares one integer or enum value against multiple constants:

#include <iostream>

int main() {
    int day = 3;

    switch (day) {
        case 1: std::cout << "Monday\n";    break;
        case 2: std::cout << "Tuesday\n";   break;
        case 3: std::cout << "Wednesday\n"; break;
        case 4: std::cout << "Thursday\n";  break;
        case 5: std::cout << "Friday\n";    break;
        default: std::cout << "Weekend\n";  break;
    }
}

break exits the switch. Without it, execution falls through to the next case. Fallthrough is occasionally intentional — grouping cases that share a body — but always mark it explicitly to avoid confusion:

switch (cmd) {
    case 'q':
    case 'Q':   // intentional fallthrough
        quit();
        break;
}

C++17 adds [[fallthrough]] to silence compiler warnings about intentional fallthrough:

case 'q':
    [[fallthrough]];
case 'Q':
    quit();
    break;

Ternary operator

A compact inline conditional:

int x = 10;
std::string label = (x > 0) ? "positive" : "non-positive";
std::cout << label << "\n";

Use it for simple expressions. Avoid nesting ternaries — they become unreadable quickly.

Short-circuit evaluation

Logical operators && and || short-circuit: the right operand is not evaluated if the result is already determined by the left:

int* p = nullptr;

// Safe: p != nullptr is checked first; *p is never read if p is null
if (p != nullptr && *p > 0) {
    std::cout << "positive\n";
}

This property is relied on heavily for null pointer checks and condition guards.

C++ by Example
C++ by Example

Learn modern C++ through working code. Each chapter introduces one concept — variables, functions, classes, templates, smart pointers, concurrency — with a clear example, a line-by-line explanation, and notes on how it applies in real programs.

View book →