LEARNING · STAGE 00 · PROGRAMMING BASICS

Conditions: if, else, switch

In the previous lesson, bool appeared — the result of a comparison. But by itself, bool does nothing except store true/false. Conditional statements are what use that result to decide which code to run: if, else, and switch.

01What you will learn

  • How if uses a bool to execute a block of code conditionally
  • Chains of else if / else for multiple options
  • switch — an alternative for comparing one value against multiple options
  • The trap of a forgotten break in switch
  • When to use if and when to use switch

02Core idea: a fork in the road

Everything that if, else, and switch do is a fork: the program reaches a certain point and must choose which path to take next, depending on some condition. Until now, the code in this course executed strictly top to bottom, statement by statement, with no alternatives — like a straight road with no turns. Conditional statements are the first way to turn off that straight line: the same program, with different variable values, will take different paths and execute different code. if/else is a fork into two (or more) directions based on any condition; switch is the same principle, but for the special case where the fork is built around one specific value.

03if — conditional execution

The simplest form of a fork is "execute or don't execute," with no alternative. That is exactly what if does: it takes a bool expression in parentheses, and if it is true, it executes the { } block that follows. If it is false, the entire block is skipped as if it never existed, and the program continues with the next statement after it.

main.cppC++
int hp = 0;

if (hp == 0)
{
    std::cout << "Game over\n";
}

hp == 0 is exactly the comparison expression from the previous lesson — it is the condition. The { } block after if is the same compound statement as the body of main() (lesson three) — it is just now executed not always, but conditionally.

04else and else if

else adds an alternative branch — code that runs when the if condition turned out to be false. The easiest way to see this is step by step — from a simple if/else with two branches to a full chain over several conditions.

Step 1 — just else, two optionsC++
if (hp <= 0)
{
    std::cout << "Game over\n";
}
else
{
    std::cout << "You're fine\n";
}

Exactly two outcomes: either the condition hp <= 0 is true and the first branch runs, or it is false and else runs. There is no third option — else here literally catches "everything else."

Step 2 — add another level with else ifC++
if (hp <= 0)
{
    std::cout << "Game over\n";
}
else if (hp < 30)
{
    std::cout << "Low health!\n";
}
else
{
    std::cout << "You're fine\n";
}

else if is literally an else that immediately contains a new if: "if the first condition is not true, then check this one." Conditions are checked in order from top to bottom, and exactly one branch runs — the one whose first encountered condition turned out to be true (or the final else, if no condition matched). As soon as one branch runs, the remaining checks in that chain are skipped — even if the next condition would also have been true. The chain can be continued as long as you like — else if can be repeated, the final else is not mandatory, but without it some values may remain completely unhandled.

05switch — comparing one value against options

"Rank 1 — gold, rank 2 — silver, rank 3 — bronze," written with else if, looks like this: if (rank == 1) ... else if (rank == 2) ... else if (rank == 3) ... — the word rank is repeated three times in a row, even though the same thing is always being compared. For this special case (one value, several specific options), C++ has a more compact notation — switch. Again, step by step:

Step 1 — minimal switch, one case and defaultC++
int rank = 2;

switch (rank)
{
    case 1:
        std::cout << "Gold\n";
        break;
    default:
        std::cout << "No medal\n";
        break;
}

switch (rank) — which value we are comparing; case 1: — what we are comparing against; default: — what to do if no case matched (the analog of a final else). Right now rank == 2, no case matches, so default runs and prints "No medal".

Step 2 — add more optionsC++
int rank = 2;

switch (rank)
{
    case 1:
        std::cout << "Gold\n";
        break;
    case 2:
        std::cout << "Silver\n";
        break;
    case 3:
        std::cout << "Bronze\n";
        break;
    default:
        std::cout << "No medal\n";
        break;
}

Now rank == 2 matches case 2:, std::cout << "Silver\n"; runs, then break; stops execution of the entire switch — the remaining case 3 and default are not even checked. break; at the end of every branch is not a decorative element, but a mandatory part.

Step 3 — what happens if you remove break from case 1C++
int rank = 1;

switch (rank)
{
    case 1:
        std::cout << "Gold\n";
        // break; ← removed on purpose
    case 2:
        std::cout << "Silver\n";
        break;
    case 3:
        std::cout << "Bronze\n";
        break;
    default:
        std::cout << "No medal\n";
        break;
}
// output when rank == 1:
// Gold
// Silver     ← unexpected, and this is not a typo in the example

Without break; after case 1:, execution does not stop at its own branch — it falls through into the next one (case 2:) entirely, even though rank is not equal to 2. This is called fallthrough, and it is discussed separately in the "Common mistakes" section below — by default it is almost always a bug, not intent.

06Nested conditions: if and switch inside each other

The character program keeps growing: next to the already familiar hp appears difficulty — a difficulty level that affects what is displayed to the player. The body of an if/else is a { } block, and inside a block there can be any statement, including another if or an entire switch. There is nothing special here — it is the same nesting principle as with ordinary { } from the "else and else if" section, only now the block contains not just std::cout, but an entire conditional construct.

switch inside else — check difficulty only if the character is aliveC++
int hp = 60;
int difficulty = 2;

if (hp <= 0)
{
    std::cout << "Game over\n";
}
else
{
    switch (difficulty)
    {
        case 1:
            std::cout << "Easy mode - alive\n";
            break;
        case 2:
            std::cout << "Normal mode - alive\n";
            break;
        default:
            std::cout << "Hard mode - alive\n";
            break;
    }
}

The outer if answers one question ("is the character alive"), while the switch inside its else branch answers another ("what difficulty"), but only for the case where the character is indeed alive. There is no need to check difficulty when hp <= 0 — nesting allows you to avoid spending a separate check on that.

The same technique works in the opposite direction — if inside if: for example, first check hp <= 0, and inside that branch, another separate if (hasRevivePotion) to decide whether the game continues or it is a full game over. The rule is the same: the more levels of nesting, the harder the code is to read, so in practice it rarely makes sense to nest deeper than two or three levels — if there are more conditions, it is usually better to extract part of the logic into a separate function (more on that in one of the upcoming lessons).

07if or switch — a table

if / else ifswitch
Conditionany bool expression (ranges, combinations via &&/||)comparison of one value against specific constants
When more convenientranges (hp < 30), complex conditionsmany specific options of one value (rank, item type, command code)
Must not forgetcurly braces when there are multiple statements in a branchbreak; at the end of every case
Catch-all branchelse — optional, but without it some values may remain unhandleddefault: — the same, optional by syntax
Nestingany statement, including another if or switch, can be the body of a branchthe same — inside a case there can be an entire if/else
Example for rankif (rank == 1) ... else if (rank == 2) ... else if (rank == 3) ...switch (rank) { case 1: ... case 2: ... case 3: ... }

On the same example with rank, you can see where the gain from switch comes from: the word rank is repeated three times in the if variant (once per comparison), but only once in switch — at the very beginning.

08Worse → better: missing curly braces

The task is to print two lines when hp <= 0: "Game over" and "Restarting...". The indentation in the code looks identical in all three versions — but it is not indentation that decides what belongs to the if.

Worse — without { }, the second line is not conditionalC++
int hp = 50;

if (hp <= 0)
    std::cout << "Game over\n";
    std::cout << "Restarting...\n";

With hp = 50, the condition hp <= 0 is false — it would seem both lines should be skipped:

console (illustration)
./main Restarting... Expected: nothing. Got: "Restarting..." while hp is alive.

if without { } applies only to the single following statement — the second std::cout always runs, regardless of the condition, even though the indentation visually suggests otherwise.

Better — with curly bracesC++
int hp = 50;

if (hp <= 0)
{
    std::cout << "Game over\n";
    std::cout << "Restarting...\n";
}

Now both lines are part of the block, and with hp = 50 neither of them runs: there is no output at all, as intended.

Best — both cases explicit, nothing left "by default"C++
int hp = 50;

if (hp <= 0)
{
    std::cout << "Game over\n";
    std::cout << "Restarting...\n";
}
else
{
    std::cout << "Still alive\n";
}

The added else is not required to fix the bug — the braces fixed it. But else makes the code more robust in a different way: now both outcomes (hp ran out / hp still there) are written explicitly, and when reading the code there is no question of "what happens if the condition is false?" — the answer is immediately visible.

09Try changing it

  • In the example from the "else and else if" section, change hp to 50 — the else branch ("You're fine") will run.
  • In the example from the "switch" section, remove break; after case 1: — with rank = 1 the program will print both "Gold" and "Silver" in a row (fallthrough).
  • Add another case 4: with new text to the switch — the syntax is the same as the others.

10Live debugging: common mistakes

As in the previous lesson, none of these mistakes will stop compilation — all three only show up at runtime.

Forgotten break in switch (fallthrough)
int rank = 1;

switch (rank)
{
    case 1:
        std::cout << "Gold\n";
        // break; ← forgotten
    case 2:
        std::cout << "Silver\n";
        break;
}
console (illustration)
./main Gold Silver Expected only "Gold" — rank is 1, not 2.

Sometimes fallthrough is used intentionally (several cases in a row for the same code), but by default it is almost always a bug. Many compilers warn about this with a separate warning (-Wimplicit-fallthrough in g++/Clang).

Without curly braces — only the next statement is conditional

The full breakdown with an example output is in the "Worse → better" section above. The rule of this course: curly braces for if/else — always, even for a single statement inside.

= instead of == inside if
if (hp = 0)   // assignment instead of comparison — the same mistake as with operators

Here it is especially insidious: the result of the assignment (0) is converted to bool as false, so the if branch never runs, and hp is silently set to zero along the way. The compiler usually warns about this (warning), but does not always stop compilation.

11Check yourself

Three questions: predicting execution through a chain of conditions, diagnosing fallthrough, and choosing between if and switch.

Predict the result
What will this program print when hp = 25?
if (hp <= 0) { std::cout << "Game over"; }
else if (hp < 30) { std::cout << "Low health!"; }
else { std::cout << "You're fine"; }
Show explanation

It will print "Low health!". Conditions are checked in order: hp <= 0 is false (25 is not ≤ 0), so hp < 30 is checked — it is true (25 < 30), that branch runs, and else is skipped entirely without even being checked.

Find the bug
When rank = 1, this program prints both "Gold" and "Silver". How do you fix it?
switch (rank) {
  case 1: std::cout << "Gold\n";
  case 2: std::cout << "Silver\n"; break;
}
Show explanation

After case 1: there is no break; — execution does not stop at its own branch but falls through into the next one (case 2:) entirely, even though rank is not equal to 2. This is fallthrough (§05). The fix is to add break; immediately after std::cout << "Gold\n";.

if or switch?
Which is better for printing the name of a day of the week from a number between 1 and 7?
Show explanation

switch — one value (day number) is compared against specific constants 1..7, exactly the case switch was designed for (§05, §07). For comparison: the "cheap/medium/expensive" task based on price ranges (< 10, < 100) cannot be solved with switch at all — there you need if/else if, because ranges are being compared, not specific values.

12Practice

★★ Based on the value of hp, print "Game over" (hp == 0 or less), "Low health!" (hp less than 30), or "You're fine" — using if / else if / else.

★★ Based on the value of rank (1, 2, or 3), print "Gold", "Silver", or "Bronze" using switch, with break in every branch and default for other cases.

★★★ Based on the values of hp and difficulty, print the result using nested conditions, as in the "Nested conditions" section above: if hp <= 0 — print "Game over" and do not check anything further. Otherwise — using switch (difficulty) inside the else branch, print "Easy mode - alive" (1), "Normal mode - alive" (2), or "Hard mode - alive" (for the rest, via default).

13Terms

TermMeaning
Branchingexecuting different code depending on a condition — the general name for what if/else/switch do
Conditionan expression of type bool that determines which branch runs
Fallthroughexecution falling through from one case branch into the next due to a missing break;
Nestingplacing one conditional construct inside the body of another

14What you can do now

Before this lesson, code always executed the same way, top to bottom. Now the program can choose a path:

  • You can write an if/else if/else chain for several mutually exclusive options and predict exactly which branch will run for a given value.
  • You can choose between if and switch for a specific task — and explain why switch is not suitable for ranges.
  • You can find a missing break; in someone else's switch and explain what exactly the fallthrough will output.
  • You can nest one conditional construct inside another (switch inside else, if inside if) and explain why this avoids duplicating a check.
  • You can explain why missing curly braces for if are not a stylistic trifle, but the source of a real bug.

15Summary

  • if (condition) { ... } — executes the block only if the condition is true.
  • else if / else — a chain of alternatives; exactly one branch runs.
  • switch — a compact alternative for comparing one value against several constants; every case branch must end with break;, otherwise it falls through into the next one.
  • Curly braces for if/else — always, even for a single statement.
  • = instead of == inside a condition — not a compilation error, but a logical error (usually with a warning).

Conditions choose a path once per program pass. The next lesson is loops: the same "run or not" choice, but repeating again and again while the condition remains true.

🎮 How does this relate to Unreal Engine?

if/else/switch work in Unreal C++ without changes — they are part of the language, not the engine. In Blueprint (Unreal's visual scripting), they correspond to the Branch and Switch nodes — the same logic, only as a graph instead of text:

C++Blueprint nodeWhat it looks like
if (condition) { ... } else { ... }Branchone input with a bool condition, two output pins: True and False — execution continues along one of them, like the two branches of if/else
switch (value) { case ... }Switch on Int / Switch on Enumone input with a value, a separate output pin for each option plus a Default pin — the direct analog of case and default:

Nesting works exactly the same way: the True output of one Branch node can lead into the input of the next Branch or Switch — the visual analog of switch inside else from the "Nested conditions" section above. By the time the course reaches Blueprint integration, this parallel will already be familiar.