if, else if, else#
int marks = 72;
char grade;
if (marks >= 90) {
grade = 'A';
} else if (marks >= 75) {
grade = 'B';
} else if (marks >= 60) {
grade = 'C';
} else {
grade = 'F';
}
Conditions are checked in order and only the first true branch runs, which is why the order matters: put >= 60 first and every pass becomes a C.
Always write the braces, even for one line. Without them, a second indented line looks like part of the if but always runs.
Combining conditions#
if (age >= 18 && hasTicket) { ... }
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') { ... }
if (!found) { ... }
A variable just for the if#
C++17 lets an if declare a variable that exists only inside it, which keeps names from leaking:
if (auto pos = s.find("needle"); pos != string::npos) {
cout << "found at " << pos << "\n";
}
// pos does not exist here
The ternary operator#
int larger = (a > b) ? a : b;
cout << (n % 2 == 0 ? "even" : "odd") << "\n";
Use it for a short choice between two values, and a full if for anything more.
switch#
One value compared against fixed alternatives:
switch (day) {
case 1:
cout << "Monday\n";
break;
case 6:
case 7:
cout << "Weekend\n";
break;
default:
cout << "Weekday\n";
}
Without break, execution falls through into the next case. That is deliberate for 6 and 7 above and a bug almost everywhere else. switch works on integers, characters and enums, not on strings.
Doubles#
Never compare computed doubles with ==:
double x = 0.1 + 0.2;
if (abs(x - 0.3) < 1e-9) { ... } // true
Handling special cases first#
Returning early from the odd cases keeps the main logic unindented:
int digits(int n) {
if (n == 0) return 1;
int count = 0;
while (n != 0) { n /= 10; count++; }
return count;
}
Key points#
- Only the first true branch of an
ifchain runs; order the checks carefully. - Always use braces.
if (init; condition)scopes a variable to theif.switchneedsbreak, and does not work on strings.
Next: loops, including the range-based for.