if and switch
So far, every line of a program has run, top to bottom. Real programs make choices: show "Pass" if the score is high enough, and nothing if it isn't. That is what if does.
1#include <iostream>2 3int main() {4 int score = 72;5 if (score >= 60) {6 std::cout << "Pass\n";7 }8 std::cout << "Score: " << score << '\n';9 return 0;10}
Pass Score: 72
The parentheses after if hold a condition. If it is true, the block in curly braces runs; if not, it is skipped. The last line is outside the if, so it always runs. Change 72 to 45 and run it again.
Comparisons
A condition is usually a comparison. C++ has six comparison operators:
| You write | Meaning |
|---|---|
a == b | equal to (two equals signs) |
a != b | not equal to |
a < b | less than |
a > b | greater than |
a <= b | less than or equal to |
a >= b | greater than or equal to |
A comparison gives a bool: true or false. When cout shows a bool, it shows 1 or 0 by default; send it std::boolalpha first and it shows the words:
1#include <iostream>2 3int main() {4 int price = 25;5 bool cheap = price < 30;6 std::cout << cheap << '\n';7 std::cout << (price == 30) << '\n';8 std::cout << std::boolalpha << cheap << '\n';9 return 0;10}
1 0 true
Note the parentheses on line 7: << is worked out before ==, so without them the compiler splits the line the wrong way. To show the result of a comparison with cout, put the comparison in parentheses.
A std::string can be compared with == and < too (lesson 5).
if and else
To do something when the condition is false as well, add else. Of the two blocks, exactly one runs:
1#include <iostream>2 3int main() {4 int stock = 0;5 if (stock > 0) {6 std::cout << "In stock: " << stock << " left\n";7 } else {8 std::cout << "Sold out\n";9 }10 return 0;11}
Sold out
Press Step and watch which lines the program skips.
else if
With more than two cases, ask one question after another with else if. Going from the top, the first condition that is true gets its block run, and the rest are not even looked at:
1#include <iostream>2 3int main() {4 int score = 84;5 if (score >= 90) {6 std::cout << "Excellent\n";7 } else if (score >= 75) {8 std::cout << "Good\n";9 } else if (score >= 60) {10 std::cout << "Pass\n";11 } else {12 std::cout << "Fail\n";13 }14 return 0;15}
Good
84 also meets score >= 60, but score >= 75 came true first, so only "Good" is shown. The order matters:
What does this program show?
1#include <iostream>2 3int main() {4 int score = 95;5 if (score >= 60) {6 std::cout << "Pass\n";7 } else if (score >= 90) {8 std::cout << "Excellent\n";9 }10 return 0;11}
The questions go from the top, and the very first one, score >= 60, is true. Only its block runs; the else if is never looked at. A wide condition placed first hides the ones after it, so go from the strictest to the widest.
And, or, not
Conditions can be combined:
| You write | Meaning | true when |
|---|---|---|
a && b | and | both are true |
a || b | or | at least one is true |
!a | not | a is false |
1#include <iostream>2 3int main() {4 int temp = 26;5 bool raining = false;6 if (temp >= 20 && temp <= 30) {7 std::cout << "Nice and warm\n";8 }9 if (temp > 35 || raining) {10 std::cout << "Stay home\n";11 }12 if (!raining) {13 std::cout << "No umbrella needed\n";14 }15 return 0;16}
Nice and warm No umbrella needed
The math way of writing it, 20 <= temp <= 30, is wrong in C++: it works out 20 <= temp first, gets true or false, and compares that with 30. Write two comparisons joined with &&.
Tip: If the left side of && is already false, the right side is not worked out; same for || when the left side is already true. So you can write count > 0 && total / count > 10: when count is 0, the division never happens.
= and ==
= assigns; == compares. Drop one equals sign from == in a condition and the program still compiles, but it means something else entirely:
1#include <iostream>2 3int main() {4 int stock = 5;5 if (stock = 0) {6 std::cout << "Sold out\n";7 } else {8 std::cout << stock << " left\n";9 }10 return 0;11}
0 left
stock = 0 stores 0 in stock, and the value of the whole thing is 0, which as a condition means false. So the program goes into the else and shows "0 left": the 5 that was in stock has been overwritten.
The compiler doesn't stop you: this is valid C++, and it compiles. You have to catch this bug yourself. When you compile on your own computer, add -Wall to get more warnings from g++, and it says suggest parentheses around assignment used as truth value. Change = to == and run it again.
switch
To compare one integer (or char) with several fixed values, switch is clearer:
1#include <iostream>2 3int main() {4 int day = 3;5 switch (day) {6 case 1:7 std::cout << "Monday\n";8 break;9 case 2:10 std::cout << "Tuesday\n";11 break;12 case 3:13 std::cout << "Wednesday\n";14 break;15 default:16 std::cout << "Some other day\n";17 }18 return 0;19}
Wednesday
switch finds the case equal to day and starts running there; break jumps out of the whole switch. If no case matches, default runs. A case takes only a fixed value: no conditions like day > 3, and no std::string.
Missing break
A case only decides where running starts. Without break, the program keeps falling through and runs the cases below too:
1#include <iostream>2 3int main() {4 char size = 'M';5 switch (size) {6 case 'S':7 std::cout << "Small\n";8 case 'M':9 std::cout << "Medium\n";10 case 'L':11 std::cout << "Large\n";12 }13 return 0;14}
Medium Large
It starts at case 'M', but there is no break, so "Large" shows too. Press Step to watch it fall through.
Sometimes falling through is just what you want: to do the same thing for several values, stack the cases:
1#include <iostream>2 3int main() {4 char grade = 'B';5 switch (grade) {6 case 'A':7 case 'B':8 std::cout << "Great\n";9 break;10 case 'C':11 std::cout << "OK\n";12 break;13 default:14 std::cout << "Keep going\n";15 }16 return 0;17}
Great
Practice
Write the code, then press Check. A hint costs nothing; the answer is there when you need it.
Shipping cost
✓Orders of 99 or more ship free; otherwise shipping is 10. total starts at 85 and is then changed to 120: in each blank line, write an if / else that shows the shipping cost.
Shipping: 10 Shipping: 0
1#include <iostream>2 3int main() {4 int total = 85;5 6 total = 120;7 8 return 0;9}
Can they come in?
✓Only people who are 18 or older and have a ticket can come in. The first person's age is 20 and has_ticket is false; the next one is 25 and has a ticket. In each blank line, check once: show Come in if they can, No entry if they can't.
No entry Come in
1#include <iostream>2 3int main() {4 int age = 20;5 bool has_ticket = false;6 7 age = 25;8 has_ticket = true;9 10 return 0;11}
Fix it: a switch that falls through
✓level is 2, so it should show only Medium difficulty, but an extra line shows up. Fix it.
Medium difficulty
1#include <iostream>2 3int main() {4 int level = 2;5 switch (level) {6 case 1:7 std::cout << "Easy\n";8 case 2:9 std::cout << "Medium difficulty\n";10 case 3:11 std::cout << "Hard\n";12 }13 return 0;14}
What you learned
- The comparison operators
==!=<><=>=give abool;coutshows it as1/0, andstd::boolalphamakes it showtrue/false. if/else if/elseask from the top and run only the first block whose condition is true; order matters.&&is and,||is or,!is not;20 <= x <= 30must be written as two comparisons.=instead of==in a condition assigns: it compiles, but gives the wrong result;g++ -Wallwarns about it.switchcompares one integer orcharwith fixed values; acaseonly says where to start,breakjumps out, anddefaultcatches the rest.