C++ for Beginners Part 3: Control Flow — Conditions and Loops
Learn how to make decisions in C++ with if/else and switch statements, and how to repeat code with for, while, and do-while loops. Covers nested loops, break, continue, and the ternary operator, with practical examples including a grade calculator and FizzBuzz.
C++ for Beginners: A Complete Guide
An eight-part beginner-friendly journey through C++: from writing your first program and understanding variables, through control flow, functions, and arrays, to the heart of C++ — pointers, classes, inheritance, and polymorphism. Each article is self-contained and builds on the previous, giving you both a quick reference and a progressive path to mastery.
- 1 C++ for Beginners Part 1: Your First C++ Program
- 2 C++ for Beginners Part 2: Variables, Data Types, and Operators
- 3 C++ for Beginners Part 3: Control Flow — Conditions and Loops
- 4 C++ for Beginners Part 4: Functions
- 5 C++ for Beginners Part 5: Arrays, Strings, and std::vector
Table of Contents
- Making decisions: if and else
- else if — multiple branches
- Omitting braces (be careful)
- Ternary operator — compact if/else
- switch — matching one value against many cases
- The break — don't forget it
- Grouping cases
- Loops: repeating code
- for loop — when you know how many iterations
- while loop — repeat while a condition holds
- do-while loop — run at least once
- break and continue
- break — exit the loop immediately
- continue — skip to the next iteration
- Nested loops
- Range-based for loop (C++11)
- Practical example: FizzBuzz
- Practical example: grade calculator
- Key takeaways
Making decisions: if and else
The if statement runs a block of code only when a condition is true:
#include <iostream>
int main() {
int age = 17;
if (age >= 18) {
std::cout << "You may vote.
";
} else {
std::cout << "You cannot vote yet.
";
}
}
else if — multiple branches
int score = 74;
if (score >= 90) {
std::cout << "Grade: A
";
} else if (score >= 80) {
std::cout << "Grade: B
";
} else if (score >= 70) {
std::cout << "Grade: C
";
} else if (score >= 60) {
std::cout << "Grade: D
";
} else {
std::cout << "Grade: F
";
}
// Output: Grade: C
Branches are evaluated top-to-bottom. The first condition that's true runs; the rest are skipped.
Omitting braces (be careful)
if (score > 50)
std::cout << "Pass
"; // Only this line is in the if
std::cout << "Done
"; // This ALWAYS runs — not part of the if!
Always use braces {} even for single-line bodies. It prevents this class of bug.
Ternary operator — compact if/else
int x = 10;
std::string result = (x % 2 == 0) ? "even" : "odd";
std::cout << result; // even
Read it as: condition ? value-if-true : value-if-false
Good for simple assignments; avoid nesting ternaries — readability drops fast.
switch — matching one value against many cases
When you're comparing one variable against several exact values, switch is cleaner than a chain of else if:
int day = 3;
switch (day) {
case 1:
std::cout << "Monday
";
break;
case 2:
std::cout << "Tuesday
";
break;
case 3:
std::cout << "Wednesday
";
break;
case 4:
std::cout << "Thursday
";
break;
case 5:
std::cout << "Friday
";
break;
default:
std::cout << "Weekend
";
}
// Output: Wednesday
The break — don't forget it
Without break, execution falls through to the next case:
int n = 1;
switch (n) {
case 1:
std::cout << "One
";
// no break — falls through!
case 2:
std::cout << "Two
";
break;
}
// Output:
// One
// Two
Fallthrough is occasionally useful (grouping cases), but almost always a bug if unintentional.
Grouping cases
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
std::cout << "Weekday
";
break;
case 6:
case 7:
std::cout << "Weekend
";
break;
}
switch only works with integer-like types (int, char, enum) — not float, double, or std::string.
Loops: repeating code
for loop — when you know how many iterations
for (int i = 0; i < 5; i++) {
std::cout << i << " ";
}
// Output: 0 1 2 3 4
The three parts of the for header:
- Initializer — runs once before the loop:
int i = 0 - Condition — checked before each iteration:
i < 5 - Increment — runs after each iteration:
i++
Counting down
for (int i = 10; i >= 1; i--) {
std::cout << i << " ";
}
// Output: 10 9 8 7 6 5 4 3 2 1
Stepping by 2
for (int i = 0; i <= 20; i += 2) {
std::cout << i << " ";
}
// Output: 0 2 4 6 8 10 12 14 16 18 20
while loop — repeat while a condition holds
int count = 0;
while (count < 5) {
std::cout << count << " ";
count++;
}
// Output: 0 1 2 3 4
The condition is checked before each iteration. If it's false from the start, the body never runs.
Reading input until valid
int number;
std::cout << "Enter a positive number: ";
std::cin >> number;
while (number <= 0) {
std::cout << "Invalid. Try again: ";
std::cin >> number;
}
std::cout << "You entered: " << number << "
";
do-while loop — run at least once
int choice;
do {
std::cout << "Enter 1 to continue, 0 to quit: ";
std::cin >> choice;
} while (choice != 0 && choice != 1);
The body runs first, then the condition is checked. Useful for menus and input validation where you always need at least one execution.
break and continue
break — exit the loop immediately
for (int i = 0; i < 100; i++) {
if (i == 5) break;
std::cout << i << " ";
}
// Output: 0 1 2 3 4
continue — skip to the next iteration
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue; // skip even numbers
std::cout << i << " ";
}
// Output: 1 3 5 7 9
Nested loops
A loop inside another loop. The inner loop completes fully for each iteration of the outer:
for (int row = 1; row <= 3; row++) {
for (int col = 1; col <= 4; col++) {
std::cout << row << "×" << col << "=" << row*col << " ";
}
std::cout << "
";
}
// 1×1=1 1×2=2 1×3=3 1×4=4
// 2×1=2 2×2=4 2×3=6 2×4=8
// 3×1=3 3×2=6 3×3=9 3×4=12
Range-based for loop (C++11)
When iterating over a collection, the range-based for is much cleaner:
#include <vector>
std::vector<int> scores = {85, 92, 78, 96, 88};
for (int s : scores) {
std::cout << s << " ";
}
// Output: 85 92 78 96 88
We'll cover vectors in detail in Part 5; for now, think of them as resizable arrays.
Practical example: FizzBuzz
A classic programming exercise — print numbers 1–100, but replace multiples of 3 with "Fizz", multiples of 5 with "Buzz", and multiples of both with "FizzBuzz":
#include <iostream>
int main() {
for (int i = 1; i <= 100; i++) {
if (i % 15 == 0) {
std::cout << "FizzBuzz
";
} else if (i % 3 == 0) {
std::cout << "Fizz
";
} else if (i % 5 == 0) {
std::cout << "Buzz
";
} else {
std::cout << i << "
";
}
}
}
Note the order: check i % 15 first. If you check % 3 first, 15 would print "Fizz" instead of "FizzBuzz".
Practical example: grade calculator
#include <iostream>
int main() {
int numStudents;
std::cout << "How many students? ";
std::cin >> numStudents;
double total = 0;
for (int i = 1; i <= numStudents; i++) {
double score;
std::cout << "Score for student " << i << ": ";
std::cin >> score;
total += score;
}
double average = total / numStudents;
std::cout << "Class average: " << average << "
";
std::string grade;
if (average >= 90) grade = "A";
else if (average >= 80) grade = "B";
else if (average >= 70) grade = "C";
else if (average >= 60) grade = "D";
else grade = "F";
std::cout << "Class grade: " << grade << "
";
}
Key takeaways
if/else if/elsehandles multiple conditions; always use{}braces.switchis cleaner when matching one variable against exact values — don't forgetbreak.foris for a known count;whilefor an unknown count;do-whilefor at least one execution.breakexits a loop;continuejumps to the next iteration.- The range-based
forloop is the idiomatic C++ way to iterate collections.
Next up: functions — how to organise code into reusable, named blocks.