- Modern C++:Efficient and Scalable Application Development
- Richard Grimes Marius Bancila
- 411字
- 2021-06-10 18:27:53
Using Conditional Statements
The most frequently used conditional statement is if. In its simplest form, the if statement takes a logical expression in a pair of parentheses and is immediately followed by the statement that is executed if the condition is true:
int i;
std::cin >> i;
if (i > 10) std::cout << "much too high!" << std::endl;
You can also use the else statement to catch occasions when the condition is false:
int i;
std::cin >> i;
if (i > 10) std::cout << "much too high!" << std::endl;
else std::cout << "within range" << std::endl;
If you want to execute several statements, you can use braces ({}) to define a code block.
The condition is a logical expression and C++ will convert from numeric types to a bool, where 0 is false and anything not 0 is true. If you are not careful, this can be a source of an error that is not only difficult to notice, but also can have an unexpected side-effect. Consider the following code, which asks for input from the console and then tests to see if the user enters -1:
int i;
std::cin >> i;
if (i == -1) std::cout << "typed -1" << endl;
std::cout << "i = " << i << endl;
This is contrived, but you may be asking for values in a loop and then performing actions on those values, except when the user enters -1, at which point the loop finishes. If you mistype, you may end up with the following code:
int i;
std::cin >> i;
if (i = -1) std::cout << "typed -1" << endl;
std::cout << "i = " << i << endl;
In this case, the assignment operator (=) is used instead of the equality operator (==). There is just one character difference, but this code is still correct C++ and the compiler is happy to compile it.
The result is that, regardless of what you type at the console, the variable i is assigned to -1, and since -1 is not zero, the condition in the if statement is true, hence the true clause of the statement is executed. Since the variable has been assigned to -1, this may alter logic further on in your code. The way to avoid this bug is to take advantage of the requirement that in an assignment the left-hand side must be an lvalue. Perform your test as follows:
if (-1 == i) std::cout << "typed -1" << endl;
Here, the logical expression is (-1 == i), and since the == operator is commutative (the order of the operands does not matter; you get the same result), this is exactly the same as you intended in the preceding test. However, if you mistype the operator, you get the following:
if (-1 = i) std::cout << "typed -1" << endl;
In this case, the assignment has an rvalue on the left-hand side, and this will cause the compiler to issue an error (in Visual C++ this is C2106 '=' : left operand must be l-value).
You are allowed to declare a variable in an if statement, and the scope of the variable is in the statement blocks. For example, a function that returns an integer can be called as follows:
if (int i = getValue()) {
// i != 0 // can use i here
} else {
// i == 0 // can use i here
}
While this is perfectly legal C++, there are a few reasons why you would want to do this.
In some cases, the conditional operator ?: can be used instead of an if statement. The operator executes the expression to the left of the ? operator and, if the conditional expression is true, it executes the expression to the right of the ?. If the conditional expression is false, it executes the expression to the right of the :. The expression that the operator executes provides the return value of the conditional operator.
For example, the following code determines the maximum of two variables, a and b:
int max;
if (a > b) max = a;
else max = b;
This can be expressed with the following single statement:
int max = (a > b) ? a : b;
The main choice is whichever is most readable in the code. Clearly, if the assignment expressions are large it may well be best to split them over lines in an if statement. However, it is useful to use the conditional statement in other statements. For example:
int number;
std::cin >> number;
std::cout << "there "
<< ((number == 1) ? "is " : "are ")
<< number << " item"
<< ((number == 1) ? "" : "s")
<< std::endl;
This code determines if the variable number is 1 and if so it prints on the console there is 1 item. This is because in both conditionals, if the value of the number variable is 1, the test is true and the first expression is used. Note that there is a pair of parentheses around the entire operator. The reason is that the stream << operator is overloaded, and you want the compiler to choose the version that takes a string, which is the type returned by the operator rather than bool, which is the type of the expression (number == 1).
If the value returned by the conditional operator is an lvalue then you can use it on the left-hand side of an assignment. This means that you can write the following, rather odd, code:
int i = 10, j = 0;
((i < j) ? i : j) = 7;
// i is 10, j is 7
i = 0, j = 10;
((i < j) ? i : j) = 7;
// i is 7, j is 10
The conditional operator checks to see if i is less than j and if so it assigns a value to i; otherwise, it assigns j with that value. This code is terse, but it lacks readability. It is far better in this case to use an if statement.