if
StatementAn if
statement conditionally executes another statement based on whether a specified condition is true. There are two forms of the if
: one with an else
branch and one without. The syntactic form of the simple if
is
if (condition)
statement
An if else
statement has the form
if (condition)
statement
else
statement2
In both versions, condition must be enclosed in parentheses. condition can be an expression or an initialized variable declaration (§ 5.2, p. 174). The expression or variable must have a type that is convertible (§ 4.11, p. 159) to bool
. As usual, either or both statement and statement2 can be a block.
If condition is true
, then statement is executed. After statement completes, execution continues with the statement following the if
.
If condition is false
, statement is skipped. In a simple if
, execution continues with the statement following the if
. In an if else
, statement2 is executed.
if else
StatementTo illustrate an if
statement, we’ll calculate a letter grade from a numeric grade. We’ll assume that the numeric grades range from zero to 100 inclusive. A grade of 100 gets an “A++,” grades below 60 get an “F,” and the others range in clumps of ten: grades from 60 to 69 inclusive get a “D,” 70 to 79 a “C,” and so on. We’ll use a vector
to hold the possible letter grades:
const vector<string> scores = {"F", "D", "C", "B", "A", "A++"};
To solve this problem, we can use an if else
statement to execute different actions for failing and passing grades:
// if grade is less than 60 it's an F, otherwise compute a subscript
string lettergrade;
if (grade < 60)
lettergrade = scores[0];
else
lettergrade = scores[(grade - 50)/10];
Depending on the value of grade
, we execute the statement after the if
or the one after the else
. In the else
, we compute a subscript from a grade by reducing the grade to account for the larger range of failing grades. Then we use integer division (§ 4.2, p. 141), which truncates the remainder, to calculate the appropriate scores
index.
if
StatementsTo make our program more interesting, we’ll add a plus or minus to passing grades. We’ll give a plus to grades ending in 8 or 9, and a minus to those ending in 0, 1, or 2:
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
else if (grade % 10 < 3)
lettergrade += '-'; // those ending in 0, 1, or 2 get a -
Here we use the modulus operator (§ 4.2, p. 141) to get the remainder and decide based on the remainder whether to add plus or minus.
We next will incorporate the code that adds a plus or minus to the code that fetches the letter grade from scores:
// if failing grade, no need to check for a plus or minus
if (grade < 60)
lettergrade = scores[0];
else {
lettergrade = scores[(grade - 50)/10]; // fetch the letter grade
if (grade != 100) // add plus or minus only if not already an A++
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
else if (grade % 10 < 3)
lettergrade += '-'; // grades ending in 0, 1, or 2 get a -
}
Note that we use a block to enclose the two statements that follow the first else
. If the grade
is 60
or more, we have two actions that we need to do: Fetch the letter grade from scores
, and conditionally set the plus or minus.
It is a common mistake to forget the curly braces when multiple statements must be executed as a block. In the following example, contrary to the indentation, the code to add a plus or minus happens unconditionally:
if (grade < 60)
lettergrade = scores[0];
else // WRONG: missing curly
lettergrade = scores[(grade - 50)/10];
// despite appearances, without the curly brace, this code is always executed
// failing grades will incorrectly get a - or a +
if (grade != 100)
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
else if (grade % 10 < 3)
lettergrade += '-'; // grades ending in 0, 1, or 2 get a -
Uncovering this error may be very difficult because the program looks correct.
To avoid such problems, some coding styles recommend always using braces after an if
or an else
(and also around the bodies of while
and for
statements).
Doing so avoids any possible confusion. It also means that the braces are already in place if later modifications of the code require adding statements.
Many editors and development environments have tools to automatically indent source code to match its structure. It is a good idea to use such tools if they are available.
else
When we nest an if
inside another if
, it is possible that there will be more if
branches than else
branches. Indeed, our grading program has four if
s and two else
s. The question arises: How do we know to which if
a given else
belongs?
This problem, usually referred to as a dangling else
, is common to many programming languages that have both if
and if else
statements. Different languages solve this problem in different ways. In C++ the ambiguity is resolved by specifying that each else
is matched with the closest preceding unmatched if
.
Programmers sometimes get into trouble when they write code that contains more if
than else
branches. To illustrate the problem, we’ll rewrite the innermost if else
that adds a plus or minus using a different set of conditions:
// WRONG: execution does NOT match indentation; the else goes with the inner if
if (grade % 10 >= 3)
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
else
lettergrade += '-'; // grades ending in 3, 4, 5, 6, or 7 get a minus!
The indentation in our code indicates that we intend the else
to go with the outer if
—we intend for the else
branch to be executed when the grade
ends in a digit less than 3
. However, despite our intentions, and contrary to the indentation, the else
branch is part of the inner if
. This code adds a '-'
to grades ending in 3
to 7
inclusive! Properly indented to match the actual execution, what we wrote is:
// indentation matches the execution path, not the programmer's intent
if (grade % 10 >= 3)
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
else
lettergrade += '-'; // grades ending in 3, 4, 5, 6, or 7 get a minus!
We can make the else
part of the outer if
by enclosing the inner if
in a block:
// add a plus for grades that end in 8 or 9 and a minus for those ending in 0, 1, or 2
if (grade % 10 >= 3) {
if (grade % 10 > 7)
lettergrade += '+'; // grades ending in 8 or 9 get a +
} else // curlies force the else to go with the outer if
lettergrade += '-'; // grades ending in 0, 1, or 2 will get a minus
Statements do not span block boundaries, so the inner if
ends at the close curly before the else
. The else
cannot be part of the inner if
. Now, the nearest unmatched if
is the outer if
, which is what we intended all along.
Exercise 5.5: Using an if
–else
statement, write your own version of the program to generate the letter grade from a numeric grade.
Exercise 5.6: Rewrite your grading program to use the conditional operator (§ 4.7, p. 151) in place of the if
–else
statement.
Exercise 5.7: Correct the errors in each of the following code fragments:
(a) if (ival1 != ival2)
ival1 = ival2
else ival1 = ival2 = 0;
(b) if (ival < minval)
minval = ival;
occurs = 1;
(c) if (int ival = get_value())
cout << "ival = " << ival << endl;
if (!ival)
cout << "ival = 0
";
(d) if (ival = 0)
ival = get_value();
Exercise 5.8: What is a “dangling else
”? How are else
clauses resolved in C++?