Control Flow
By the end of this lesson you'll be able to make your C++ programs decide what to do — branching with if / else if / else , choosing values with the ternary ?: , matching exact values with switch , and combining conditions with && , || and ! .
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free C++ course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Control flow is the signpost at a fork in the road . Your program walks up to a junction, reads a condition ( "is it raining?" ), and takes the matching path. An if / else if / else chain is a row of signs checked in order — you follow the first one that points your way and ignore the rest. A switch is the departures board at a station: it looks up your exact destination and sends you straight to the right platform. Without these signposts, the program can only ever walk in one straight line.
1. if / else if / else
An if statement runs a block of code only when a condition is true . The condition goes in (parentheses) and must evaluate to true or false . Add else for a fallback, and chain else if for extra options. The chain is checked top to bottom and the first true branch wins — every branch below it is skipped — so put your most specific conditions first. Read this worked example, run it, then you'll write your own.
⚠️ Always use braces {' '} . Without them, only the single line after the if is conditional — the next line runs every time, which is a classic, silent bug.
2. The Ternary Operator ?:
The ternary is a compact if / else that returns a value . The shape is condition ? valueIfTrue : valueIfFalse . Because it produces a value, you can assign it directly ( string s = ok ? "yes" : "no"; ) or drop it inside a bigger expression. Reach for it on short either/or choices; if a branch needs several statements, a normal if / else reads more clearly.
Your turn. Fill in the two ___ blanks using the hints in the comments, then run it.
3. switch / case / break / default
When you're comparing one value against many exact options , a switch is cleaner than a long else if chain. It works with int , char and enum (not strings or ranges). Each case ends with break to jump out of the switch; default is the catch-all, like else . If you omit break , execution falls through into the next case — handy when you deliberately stack cases ( case 6: case 7: sharing one block), but a bug when you forget it.
Now you try. This vending machine is missing the keyword that stops fall-through and the catch-all label. Fill in the two blanks:
4. Nesting, Logic & if -with-Initializer
Real decisions often depend on several things at once. Combine conditions with the logical operators: && (AND — both must be true), || (OR — either is enough), and ! (NOT — flips true and false). You can also nest an if inside another to make a second decision only when the first passed. Finally, C++17's if -with-initializer lets you declare and test a variable together — if (int x = f(); x 0) — keeping x scoped to just that if / else .
No blanks this time — just a brief and a blank canvas (with an outline to keep you on track). Build it, run it, and check your output against the example in the comments. This combines an if / else if chain with a ternary, exactly like real code.
Practice quiz
In an if / else if / else chain, which branch runs?
- All branches whose condition is true
- Only the else branch
- The first branch whose condition is true
- The last branch whose condition is true
Answer: The first branch whose condition is true. The chain is checked top to bottom and the first true branch wins; the rest are skipped.
What is the shape of the ternary operator?
- condition ? valueIfTrue : valueIfFalse
- condition : a ? b
- if condition then a else b
- condition && a || b
Answer: condition ? valueIfTrue : valueIfFalse. The ternary is condition ? valueIfTrue : valueIfFalse and returns a value.
Which types can a switch statement compare against exact cases?
- Only std::string
- Only double
- Any type including ranges
- int, char and enum
Answer: int, char and enum. switch works with int, char and enum — not strings or ranges.
What happens in a switch case that has no break?
- The program crashes
- Execution falls through into the next case
- It jumps to default
- Nothing prints
Answer: Execution falls through into the next case. Without break, execution falls through into the next case's code.
What role does 'default' play in a switch?
- It is the catch-all when no case matched (like else)
- It runs first
- It must come before all cases
- It stops fall-through
Answer: It is the catch-all when no case matched (like else). default runs when no case matched, like an else clause.
Why does 'if (x = 5)' always run its block?
- 5 is special
- if always runs once
- = assigns 5 to x and the non-zero value is treated as true
- It compares x to 5 and they match
Answer: = assigns 5 to x and the non-zero value is treated as true. = is assignment; it stores 5 in x and any non-zero value counts as true.
What is the key advantage of the ternary over a plain if/else?
- It is faster at runtime
- It returns a value you can assign
- It allows more statements
- It works on strings only
Answer: It returns a value you can assign. The ternary returns a value, so you can assign it: string s = ok ? "yes" : "no";.
Given int score = 82, which grade prints in the lesson's if/else if chain (A>=90, B>=80, C>=70)?
- Grade: A
- Grade: C
- Grade: F
- Grade: B
Answer: Grade: B. 82 >= 80 is the first true branch, so Grade: B prints (A was skipped).
What does an if-with-initializer 'if (int x = f(); x > 0)' give you (C++17)?
- A faster loop
- x scoped to just that if/else
- A global variable x
- Automatic break
Answer: x scoped to just that if/else. The variable declared in the initializer only exists inside that if/else, keeping it tightly scoped.
When stacking 'case 6: case 7:' with one block and a break, what does it achieve?
- A compile error
- Only 7 runs the code
- Both values 6 and 7 share the same code
- It skips both cases
Answer: Both values 6 and 7 share the same code. Deliberate fall-through lets several case values share one block of code.