210 likes | 301 Views
Selection structures in C (II) H&K Chapter 4. Instructor – Gokcen Cilingir Cpt S 121 (June 30 , 2011) Washington State University. You try it!. What will be the output of the code below? int x = 0; if (x = 3) printf (“x is %d<br>”, x); else printf (“x is %d<br>”, x);. You try it!.
E N D
Selection structures in C (II)H&K Chapter 4 Instructor – GokcenCilingir Cpt S 121 (June 30, 2011) Washington State University
You try it! • What will be the output of the code below? intx = 0;if (x = 3)printf(“x is %d\n”, x); else printf(“x is %d\n”, x);
You try it! • Explain the difference between the statements on the left and the statements on the right. What will x be in each situation given that its initial value was 1? if (x >= 0) x = x + 1; else if (x >= 1) x = x + 2; if (x >= 0) x = x + 1; if (x >= 1) x = x + 2;
Nested if statements (1) • Consider the following scenario: A high school baseball team awards merit points to players based on their offensive performance. A single (encoded 's') is worth 1 point, a double (encoded 'd') is worth 2 points, a triple (encoded 't') is worth 3 points, and a home run (encoded 'h') is worth 4 points. Any at-bat that leads to an out (encoded 'o') worth 0 points. Write a C statement that, given an at-bat character, properly awards points.
Nested if statements (2) • We can write a nested if statement to handle this situation: char at_bat; int points; printf("Enter the at-bat code (s,d,t,h,o): "); scanf(" %c",&at_bat); if (at_bat == 's') /* single */ { points = 1; } else if (at_bat == 'd') /* double */ { points = 2; } else if (at_bat == 't') /* triple */ { points = 3; } else if (at_bat == 'h') /* home run */ { points = 4; } else /* out */ { points = 0; }
Nested if statements (3) • Consider the following updated scenario: A high school baseball team awards merit points to players based on their offensive performance and the class standing ('f' = freshman, 'o' = sophomore, 'j' = junior, and 's' = senior). In particular, freshmen and sophomores earn an extra point for home runs, whereas juniors and seniors do not earn any points for singles. Write a C if-statement that, given an at-bat character and a class standing character, properly awards points.
Nested if statements (4) • We can write an even more nested if statements to handle this situation: char at_bat, class_standing; int points; ... if (at_bat == 's') /* single */ { if (class_standing == 'f') || (class_standing == 'o') points = 1; else points = 0; } else if (at_bat == 'd') /* double */ { points = 2; } else if (at_bat == 't') /* triple */ { points = 3; } else if (at_bat == 'h') /* home run */ { if (class_standing == 'j') || (class_standing == 's') points = 4; else points = 5; } else /* out */ { points = 0; }
Nested if statements (3) • Nested if statements vs. compound conditionals • Consider the following scenario: The National Weather Service would like to identify hourly weather reports in which the relative humidity is low (below 20%, the temperature is pleasant (between 75 and 85), and the winds are calm (0 to 10 m.p.h.). Assuming that the variables humidity, temp, and wind_speed hold those values, write an if statement that prints out a message when the conditions are met.
Nested if statements (4) • Nested if statements vs. compound conditionals (cont.) • Alternative 1: Nested if if (humidity < 20) if (temp >= 75) if (temp <= 85) if (wind_speed <= 10) printf("Perfect conditions!\n"); • Alternative 2: Compound if conditionalif ((humidity < 20) && (temp >= 75) && (temp <= 85) && (wind_speed <= 10)) printf("Perfect conditions!\n");
‘Dangling else’ problem • To which if statement does the else belong to? if(y != 0 ) if (x != 0) result = x/y; else printf(“Error: y is equal to 0\n”);
Nested if statements (5) • Important to note that the C compiler always matches an else with the most recent incomplete if • Example: if (humidity < 20) if (temp <= 32) printf("It's a cool, dry day.") if (wind < 10) printf("Luckily, the winds are calm."); else printf("The humidity is low, it's above freezing."); else if (humidity < 60) if (temp <= 32) printf("It's cold, with moderate humidity."); else printf("It's above freezing, with moderate humidity."); • Do you see a problem here? How would you fix it?
Nested if statements (6) • Guidelines for using nested if statements • Use braces to enclose all if branches, even if they contain only one statement • This will help you avoid the problem of mismatching if and else branches • If possible, structure conditions so each alternative falls on false branch of previous condition (else if…) • If each if branch contains a return statement, there's no need for an else clause, and you can avoid deep nesting • In conditionals, don't mistake = for == • The C compiler won't be able to catch this error, and you're condition will always evaluate to true!
Nested if statements (7) • Example: Nested if with return statements int get_points(char at_bat) { if (at_bat == 's') /* single */return 1; /* assertion: at_bat != 's' */ if (at_bat == 'd') /* double */ return 2; /* assertion: at_bat != 's' && at_bat != 'd' */ if (at_bat == 't') /* triple */ return 3; /* assertion: at_bat != 's' && at_bat != 'd' && at_bat != 't' */ if (at_bat == 'h') /* home run */ return 4; /* assertion: at_bat != 's' && at_bat != 'd' && at_bat != 't' && at_bat != 'h' */ return 0; /* out */ }
switch Statements (1) • One issue with nested if statements is readability • The deeper the nesting, the more difficult it can be to figure out what's happening • Another issue is that the programmer could mistakenly "mis-nest" if statements, as in the previous example • In cases in which the nesting is based on the value of a single variable, a switch statement may be a better alternative
switch Statements (2) • Let's revisit the previous baseball scenario: A high school baseball team awards merit points to players based on their offensive performance. A single (encoded 's') is worth 1 point, a double (encoded 'd') is worth 2 points, a triple (encoded 't') is worth 3 points, and a home run (encoded 'h') is worth 4 points. Any at-bat that leads to an out (encoded 'o') worth 0 points. Write a C statement that, given an at-bat character, properly awards points.
switch Statements (3) • The switch statement provides a cleaner way to handle this scenario: char at_bat; int points; points = 0; printf("Enter the at-bat code (s,d,t,h,o): "); scanf(" %c",&at_bat); switch (at_bat) { case 's': /* single */ points = points + 1; break; case 'd': /* double */ points = points + 2; break; case 't': /* triple */ points = points + 3; break; case 'h': /* home run */ points = points + 4; break; case 'o': points = points + 0; break; default: /* Anything but 's','d','t','h', 'o' */ printf("Unrecognized at-bat code."); break; } Don't forget the begin and end curly braces Don't forget to end each case with break If at_bat does not match any other case labels, the default case is executed
switch Statements (4) • What if we also want to allow capital letter codes? switch (at_bat) { case 's': /* single */ case 'S': points = points + 1; break; case 'd': /* double */ case 'D': points = points + 2; break; case 't': /* triple */ case 'T': points = points + 3; break; case 'h': /* home run */ case 'H': points = points + 4; break; case 'o': case 'O': points = points + 0; break; default: /* Anything but 's','d','t','h' */ printf("Unrecognized at-bat code."); break; } A single case can contain an arbitrary number of case labels
switch Statements (5) • Let's revisit the following scenario: A high school baseball team awards merit points to players based on their offensive performance and the class standing ('f' = freshman, 'o' = sophomore, 'j' = junior, and 's' = senior). In particular, freshmen and sophomores earn an extra point for home runs, whereas juniors and seniors do not earn any points for singles. Write a C if-statement that, given an at-bat character and a class standing character, properly awards points.
switch Statements (6) • We can write this more clearly as a switch statement with embedded if statements : switch (at_bat) { case 's': /* single */ if (class_standing == 'f') || (class_standing == 'o') points = 1; break; case 'd': /* double */ points = 2; break; case 't': /* triple */ points = 3; break; case 'h': /* home run */ if ((class_standing == 'f') || (class_standing == 'o')) points = 5; else points = 4; break; case 'o': points = 0; break; default: /* Anything but 's','d','t','h' */ printf("Unrecognized at-bat code."); break; }
switch Statements (7) • Notes on switch statements • You can only switch based on a value of char or int. You cannot switch based on the value of a double. double era = 1.67; switch (era) { … /* can't do this */ • An arbitrary number of statements can follow a case label • It's a good idea always to define a defaultcase • A common mistake is to forget to end a case with break. If a break is forgotten, execution "falls" through to the next case label! (C can be cruel.)
References • J.R. Hanly & E.B. Koffman, Problem Solving and Program Design in C (6th Ed.), Addison-Wesley, 2010 • P.J. Deitel & H.M. Deitel, C How to Program (5th Ed.), Pearson Education , Inc., 2007.