| < Day Day Up > |
|
Selection statements change the flow of program execution by evaluating the result of an expression, referred to as a condition. The if and switch statements are selection statements.
An if statement evaluates a condition and executes its associated statement if the condition is true. Otherwise it skips the statement and processing continues on to the next statement following the if.
Figure 6-1: if Statement Diagram
Figure 6-1 illustrates the if statement. The expression that formulates the condition must evaluate to either true or false. True is any non-zero integer value. The following code gives an example of a simple if statement:
Listing 6.1: if statement
1 int a = 0, b = 1; 2 if(a++ > b) 3 cout<<"a is greater than b"<<endl;
In this example the postfix ++ operator will increment a after the greater than comparison is made comparing a’s value with b’s value. This will result in the expression evaluating to false. However, after the if statement executes, a will be 1.
The expressions that form the condition can be simple or complex. I should warn you that the most common mistake novice programmers make with regards to selection statement conditions is using an assignment operator, =, where they really meant to use an equality operator, ==. The following example is perfectly legal in C++:
Listing 6.2: assignment
1 int a = 0; 2 if(a = 3) 3 cout<<"Assignment expressions can be conditions too!"<<endl;
The condition on line 2 evaluates to true because the result of the assignment is the value assigned to a, which is 3, which is a non-zero integer value and therefore considered true. The following example looks similar but is completely different from example 6.2:
Listing 6.3: equality
1 int a = 0; 2 if(a == 3) 3 cout<<"Assignment expressions can be conditions too!"<<endl;
In this example the condition on line 2 will evaluate to false because a is not equal to 3. This leads me to my first good piece of advice regarding selection statements:
Declarations can be part of the condition, in which case the scope of the declared variable are the statements controlled by the selection statement. Examine the following example:
Listing 6.4: declaration in condition
1 if(int a = 3) 2 cout<<"Declarations are allowed in the condition!"<<endl;
The scope of variable a would be up to the end of line 2.
Compound statements can be used with if statements. Examine the following example:
Listing 6.5: compound statements
1 int a = 0, b = 1; 2 3 if(++a == b){ 4 int c = 2; 5 cout<<"The value of a is: "<<a++<<endl; 6 cout<<"The value of b is: "<<b<<endl; 7 cout<<"The value of c is: "<<c<<endl; 8 cout<<"The value of a is: "<<a<<endl; 9 }
All the statements appearing between the opening and closing braces will be executed if the condition on line 3 evaluates to true which it will. The variable c declared on line 4 has block scope within the braces from its point of declaration up to the closing brace on line 9.
The if-else statement works like the if statement with one major difference. If the condition evaluates to false the statement following the else keyword will execute. A diagram of the if-else statement is shown in Figure 6-2.
Figure 6-2: if-else Statement Diagram
The following code gives an example of an if-else statement in action:
Listing 6.6: if-else
1 int a = 0; 2 3 if(a) 4 cout<<"True statement."<<endl; 5 else 6 cout<<"False statement."<<endl;
In this example the variable a is evaluated resulting in false since a is zero. Line 4 will be skipped and the statement on line 6 will execute.
The ! operator can be used to negate an expression. Examine the following example:
Listing 6.7: ! operator
1 int a = 0; 2 3 if(!a) 4 cout<<"True statement."<<endl; 5 else 6 cout<<"False statement."<<endl;
The statement is read, “if not a...”. Since a is zero, !a will evaluate to true causing the statement on line 4 to execute.
Compound statements can be used with if-else statements as illustrated by the following example:
Listing 6.8: compound statements with if-else
1 int a = 1; 2 3 if(!a){ 4 int b = 1; 5 cout<<"The value of a: "<<a++<<endl; 6 cout<<"The value of b: "<<b<<endl; 7 } 8 else{ 9 int b = 2; 10 cout<<"The value of a: "<<a<<endl; 11 cout<<"The value of b: "<<b<<endl; 12 }
On line 1 the variable a is initialized to 1 causing !a to evaluate to false. The variable a is in scope of the entire if- else statement while each variable b has only block scope within each compound statement.
Nesting if-else statements refers to putting one if-else statement within another or chaining them together. One method of nesting if-else statements is to follow the else keyword with another if-else statement. The following short program reads a character from the keyboard and prints a message to the screen based on the character entered:
Listing 6.9: nesting if-else
1 #include <iostream> 2 using namespace std; 3 4 int main(){ 5 6 cout<<"Enter the character a, b, or c: "; 7 char input; 8 cin>>input; 9 10 if(input == 'a') 11 cout<<"You entered a."<<endl; 12 else if(input == 'b') 13 cout<<"You entered b."<<endl; 14 else if(input == 'c') 15 cout<<"You entered c."<<endl; 16 else 17 cout<<"You entered the wrong character!"<<endl; 18 19 return EXIT_SUCCESS; 20 }
In this complete example a character is read from the input stream and assigned to the variable named input. The variable input is then compared to three different values in each if-else statement starting on line 10. If the character entered matches the compared value then the expression evaluates to true, otherwise it is false. If the input character is not an ‘a’, ‘b’, or ‘c’ then the final else is executed.
What is helpful to keep in mind is that almost anywhere a statement can be used, a selection statement can be used there as well. Examine the following complete program:
Listing 6.10: use of selection statements
1 #include <iostream> 2 using namespace std; 3 4 int main(){ 5 6 cout<<"Enter the character a, b, or c: "; 7 char input1; 8 cin>>input1; 9 10 cout<<"Enter the character u or p: "; 11 char input2; 12 cin>>input2; 13 14 if(input1 == 'a'){ 15 cout<<"You entered a."<<endl; 16 if(input2 == 'u') 17 cout<<"You entered u."<<endl; 18 else if(input2 == 'p') 19 cout<<"You entered p."<<endl; 20 else cout<<"You didn't enter u or p!"<<endl; 21 }else if(input1 == 'b'){ 22 cout<<"You entered b."<<endl; 23 if(input2 == 'u') 24 cout<<"You entered u."<<endl; 25 else if(input2 == 'p') 26 cout<<"You entered p."<<endl; 27 else cout<<"You didn't enter u or p!"<<endl; 28 }else if(input1 == 'c'){ 29 cout<<"You entered c."<<endl; 30 if(input2 == 'u') 31 cout<<"You entered u."<<endl; 32 else if(input2 == 'p') 33 cout<<"You entered p."<<endl; 34 else cout<<"You didn't enter u or p!"<<endl; 35 }else { 36 cout<<"You didn't enter a, b, or c!"<<endl; 37 if(input2 == 'u') 38 cout<<"You entered u."<<endl; 39 else if(input2 == 'p') 40 cout<<"You entered p."<<endl; 41 else cout<<"You didn't enter u or p!"<<endl; 42 } 43 return EXIT_SUCCESS; 44 }
In this example two character inputs are read from the keyboard and compared to character literals in the if statements. This example gives you a good idea of how messy nested if-else statements can become even if liberal indenting is used to improve readability. Luckily, there is an alternative to the nested if-else —the switch statement.
A switch statement evaluates a condition much like nested if-else statements. The condition must evaluate to either an integral value or enumeration value. Enumerations will be covered formally in chapter 10 but I will give you an example of their use with switch statements in this section. Figure 6-3 shows a diagram of the switch statement.
Figure 6-3: switch Statement Diagram
Execution will transfer to the statement whose case label constant expression matches the result of the condition evaluation.
Important!!! Execution of a case statement will fall through to the next case statement unless the keyword break is used to exit the switch statement. (Sometimes you want a case statement to fall through to the next case — and sometimes you do not) If a default label is present, and the result of the condition fails to match any of the cases, the default case will execute. Keep the following advice in mind when using switch statements:
Example 6.11 gives the switch statement version of the nested if-else statement shown in example 6.10:
Listing 6.11: switch statement
1 #include <iostream> 2 using namespace std; 3 4 int main(){ 5 6 cout<<"Enter the character a, b, or c: "; 7 char input1; 8 cin>>input1; 9 10 cout<<"Enter the character u or p: "; 11 char input2; 12 cin>>input2; 13 14 switch(input1){ 15 case 'a':{ 16 cout<<"You entered a."<<endl; 17 switch(input2){ 18 case 'u': cout<<"You entered u."<<endl; 19 break; 20 case 'p' : cout<<"You entered p."<<endl; 21 break; 22 default : cout<<"You didn't enter u or p!"<<endl; 23 } 24 break; 25 } 26 case 'b':{ 27 cout<<"You entered b."<<endl; 28 switch(input2){ 29 case 'u': cout<<"You entered u."<<endl; 30 break; 31 case 'p' : cout<<"You entered p."<<endl; 32 break; 33 default : cout<<"You didn't enter u or p!"<<endl; 34 } 35 break; 36 } 37 case 'c': { 38 cout<<"You entered c."<<endl; 39 switch(input2){ 40 case 'u': cout<<"You entered u."<<endl; 41 break; 42 case 'p' : cout<<"You entered p."<<endl; 43 break; 44 default : cout<<"You didn't enter u or p!"<<endl; 45 } 46 break; 47 } 48 49 default: { 50 cout<<"You didn't enter a, b, or c!"<<endl; 51 switch(input2){ 52 case 'u': cout<<"You entered u."<<endl; 53 break; 54 case 'p' : cout<<"You entered p."<<endl; 55 break; 56 default : cout<<"You didn't enter u or p!"<<endl; 57 } 58 } 59 }//end switch 60 61 return EXIT_SUCCESS; 62 63 } //end main()
The switch statement begins on line 14 and evaluates the character variable input1. There are four possible cases that can be executed. If the input1 evaluates to ‘a’ then the statements associated with case ‘a’: on line 15 execute. Case ‘a’ contains all the statements between the opening brace on line 15 to the closing brace on line 25. Notice that case ‘a’ also contains a nested switch statement that evaluates the variable input2. Case ‘b’ and case ‘c’ execute in similar fashion. The break statements in each case will exit the switch and prevent execution falling through to the next case. If none of the cases match the input then the default case is executed. The use of braces to enclose statements associated with a case label are optional.
As long as the default case is the last labeled statement in the switch statement then a break is not required; execution will fall through to the end of the switch. However, if another case label appears beneath the default label then use break to make sure you exit the switch normally. Here is another piece of advice to keep in mind when using a switch statement:
| < Day Day Up > |
|