Chapter 10 Control Structures Chapter 10: Control Structures 1 Flow of Control Sequence Selection Repetition No action-1 condition Yes action-2 action Yes condition No Selection structure Chapter 10 Flow of Control Repetition structure 2 Selection: ‘if’ construct Syntax: if (expression) statement ; expression is the condition for the ‘if’ construct. If expression is evaluated to non-zero (true), statement is executed. If expression is evaluated to zero (false), statement is skipped. Chapter 10 Selection: ‘if’ construct 3 ‘if’ construct Syntax: if (expression) statement ; fine = 20; if (speed > 50) fine += 10; printf("Fine is %d\n", fine); Chapter 10 'if’ construct 4 Compound-statement Action Syntax: if (expression) { compound-statement ; } if (a > b) max = a; if (a > b) printf("%d is larger than %d\n", a, b); if (a > b) { max = a; printf("%d is larger than %d\n", a, b); } Chapter 10 Compound-statement Action 5 Flags Flag: an integer variable that simulates a Boolean variable. Contains 0 (false) or 1 (true). if (attended == 1) attendance++; if (attended == 0) { absentees++; printf("One more absentee.\n"); } Chapter 10 or or Flags if (attended) attendance++; if !(attended) { absentees++; printf("One more absentee.\n"); } 6 Naming a Flag Appropriate naming is desirable. Example: a flag ‘attended’ implies ‘attended’ if it contains 1 (true) ‘did not attend’ if it contains 0 (false) Chapter 10 Naming a Flag 7 Nested ‘if’ statement Example: if (exam >= 80) if (project >= 90) grade = 'A'; Above could be rewritten as: if (exam >= 80 && project >= 90) grade = 'A'; Chapter 10 Nested ‘if’ statement 8 Short-circuit evaluation Evaluation stops as soon as value of expression is known. Evaluation is from left to right. For logical AND (&&), if the partial expression is false, the whole expression is false. For logical OR (||), if the partial expression is true, the whole expression is true. Chapter 10 Short-circuit evaluation 9 Short-circuit evaluation Example: if (bank_bal < 0.0 || expenses > 100.0) printf("Red alert!\n"); Chapter 10 Short-circuit evaluation 10 Complementing a Condition Comlementing or negating a logical expression means changing the polarity. Examples: !(a == 30) is equivalent to (a != 30) !(a > b) is equivalent to (a <= b) Chapter 10 Complementing a Condition 11 DeMorgan’s Theorem NOT(a AND b) same as NOT(a) OR NOT (b) NOT(a OR b) same as NOT(a) AND NOT(b) In C: !(expr1 && expr2) same as !(expr1) || !(expr2) !(expr1 || expr2) same as !(expr1) && !(expr2) Chapter 10 DeMorgan’s Theorem 12 DeMorgan’s Theorem Example: !(age > 25 && (status == 'S' || status == 'D')) (age <= 25) || (status != 'S' && status != 'D')) Chapter 10 DeMorgan’s Theorem 13 Common Mistakes Do not use == and != on floating-point numbers. Mixing up == with =. Wrong placament of semi-colon, resulting in empty statement: if (a > b); printf("a is larger than b\n"); printf() is outside ‘if’ construct. Chapter 10 Common Mistakes 14 Common Mistakes Translating condition in English to C: if (lower <= x <= upper) ... Let lower be 10, and upper be 30. If x is 20, (lower <= x) is true, so it is evaluated to 1. Since (1 <= upper) is also true, condition is true! Chapter 10 Common Mistakes 15 Common Mistakes Wrong condition: if (lower <= x <= upper) ... Correct method: if (lower <= x && x <= upper) which is equivalent to this (since <= has a higher precedence than &&): if ((lower <= x) && (x <= upper)) Chapter 10 Common Mistakes 16 Common Mistakes Wrong condition: if (x && y > z) Correct method: Chapter 10 if (x > z && y > z) Common Mistakes 17 Common Mistakes Forgetting the braces for compound statements: if (a > b) max = a; printf("%d is larger than %d\n", a, b); Correct method: Chapter 10 if (a > b) { max = a; printf("%d is larger than %d\n", a, b); } Common Mistakes 18 ‘if-else’ construct Syntax: if (expression) statement1 ; else statement2 ; Chapter 10 if (expression) { compound-statement1 ; } else { compound- statement2 ; } ‘if-else’ construct 19 ‘if-else’ construct May be used to avoid redundant code: if (count == 0) ave = 0.0; if (count != 0) ave = (float) total/count; Use ‘if-else’ construct: Chapter 10 if (count == 0) ave = 0.0; else ave = (float) total/count; ‘if-else’ construct 20 ‘if-else’ construct Another example: if (score1 < score2) { better_score = score2; printf("score2 is better\n"); } else { better_score = score1; printf("score1 is better\n"); } Chapter 10 ‘if-else’ construct 21 Style Two common styles: if (expression) { compound-statement1 ; } else { compound- statement2 ; } Chapter 10 Style if (expression) { compound-statement1 ; } else { compound- statement2 ; } 22 Removing common statements Common statements in the ‘then’ and ‘else’ parts should be moved out of the ‘if’ construct, if appropriate: Chapter 10 if (a < 0) { count++; neg++; printf("Enter an integer: "); scanf("%d", &k); } else { count++; pos++; printf("Enter an integer: "); scanf("%d", &k); } Removing common statements 23 Removing common statements After moving common statements out of ‘if’ construct: Chapter 10 count++; if (a < 0) neg++; else pos++; printf("Enter an integer: "); scanf("%d", &k); Removing common statements 24 Logical assignment for Flags Example: if (age >= 65) snr_citizen = 1; else snr_citizen = 0; ‘if-else’ statement may be replaced by an assignment statement. snr_citizen = (age >= 65); Chapter 10 Logical assignment for Flags 25 Logical assignment for Flags Another example: if (n % 2 == 0) even = 1; else even = 0; even = (n % 2 == 0); even = !(n % 2); Chapter 10 Logical assignment for Flags 26 Nested ‘if-else’ statements Example: if (marks < 50) grade = 'F'; else if (marks < 70) grade = 'B'; else grade = 'A’; Chapter 10 Nested ‘if-else’ statements 27 Nested ‘if-else’ statements Which ‘if’ is the ‘else’ associated with? if (a == 1) if (b == 2) printf("***\n"); else printf("###\n"); ‘else’ is associated with nearest ‘if’. if (a == 1) if (b == 2) printf("***\n"); else printf("###\n"); Chapter 10 Nested ‘if-else’ statements 28 Nested ‘if-else’ statements To override default association, use braces to mark out block. if (a == 1) { if (b == 2) printf("***\n"); } else printf("###\n"); Chapter 10 Nested ‘if-else’ statements 29 Nested ‘if-else’ statements Example: Chapter 10 if (a == 0) if (b == 0) printf("Both a and b are zeros.\n"); else c = b/a; if (a == 0) { if (b == 0) printf("Both a and b are zeros.\n"); } else c = b/a; Nested ‘if-else’ statements 30 Nested ‘if-else’ statements Example: if (marks < 50) grade = 'F'; else if (marks < 60) grade = 'D'; else if (marks < 70) grade = 'C’; else if (marks < 80) grade = 'B'; else grade = 'A'; Chapter 10 if (marks < 50) grade = 'F'; else if (marks < 60) grade = 'D'; else if (marks < 70) grade = 'C’; else if (marks < 80) grade = 'B'; else grade = 'A'; Nested ‘if-else’ statements 31 Common Mistakes Wrong matching of ‘else’ with ‘if’. Wrong placement of semi-colon. Chapter 10 if (a == b) { a++; b--; }; else a = b; Common Mistakes 32 Conditional Operator (?:) Ternary operator: condition ? expr1 : expr2 First operand is condition. If condition is true, take value of expr1; otherwise, take value of expr2. Chapter 10 Conditional Operator (?:) 33 Conditional Operator (?:) Example: max = (a > b ? a : b); equivalent to: if (a > b) max = a; else max = b; Chapter 10 Conditional Operator (?:) 34 Conditional Operator (?:) Example: printf("%s\n", grade < 50 ? "Failed" : "Passed"); equivalent to: if (marks < 50) printf("Failed\n"); else printf("Passed\n"); Chapter 10 Conditional Operator (?:) 35 ‘switch’ construct Multi-way selection statement: switch (expression) { case v1: s1 ; break; case v2: s2 ; break; ... default: sn ; break; /* optional break */ } Chapter 10 ‘switch’ construct 36 ‘switch’ construct May only test constant integral expressions, i.e., expressions that evaluate to integers or characters. The vi’s are integral values; the si’s are compound statements. After expression is evaluated, control jumps to appropriate ‘case’ label. ‘break’ statements are inserted to avoid falling through. Chapter 10 ‘switch’ construct 37 ‘switch’ construct Example: switch (class) { case 'B': case 'b': printf break; case 'C': case 'c': printf break; case 'D': case 'd': printf break; case 'F': case 'f': printf break; default : printf ("Battleship\n"); ("Cruiser\n"); ("Destroyer\n"); ("Frigate\n"); ("Unknown ship class %c\n", class); } Chapter 10 ‘switch’ construct 38 Repetition Structure Counter-controlled repetiton: number of iterations known. Sentinel-controlled repetiton: iterate until a sentinel value is entered, or terminating condition is true. Chapter 10 Repetition Structure 39 ‘while’ construct Loop structure with pre-test condition. while (expression) statement ; expression is loop condition. If expression is true, statement in loop body is executed, and expression tested again. If expression is false, loop terminates. Chapter 10 ‘while’ construct 40 ‘while’ construct Example: Print n asterisks. count_star = 0; while (count_star < n) { printf("*"); count_star++; } count_star = 0; while (count_star++ < n) printf("*"); count_star is the loop control variable. Chapter 10 ‘while’ construct 41 ‘while’ construct Example: Compute sum of first 100 positive integers. int num = 1; int total = 0; /* declaration and */ /* initialisation */ while (num <= 100) { total += num; num++; } Chapter 10 ‘while’ construct 42 ‘while’ construct Which of these is/are same as previous code? int num = 1; int total = 0; while (num <= 100) { total += num; ++num; } Chapter 10 int num = 1; int total = 0; while (num <= 100) total += num++; int num = 1; int total = 0; while (num <= 100) total += ++num; ‘while’ construct 43 ‘while’ construct Loop control variable. Initialisation: before the loop is entered, the variable must be initialised. Testing: condition involving the loop control variable is tested before the start of each loop iteration; if condition is true, loop body is executed. Updating: loop control variable is updated during each iteration (usually at the beginning or the end of the loop body). Chapter 10 ‘while’ construct 44 Counter-control repetition A counter is used to keep track of number of #define N 10 iterations. . . . total = 0; count = 1; while (count++ <= N) { printf("Enter score: "); scanf("%d", &score); total += score; } avg = (float) total / N; printf("Average is %.2f\n", avg); Chapter 10 Counter-control repetition 45 Sentinel-control repetition A sentinel is used to denote end of data. #define SENTINEL –1 . . . total = 0; count = 0; printf("Enter score, –1 to end: "); scanf("%d", &score); while (score != SENTINEL) { total += score; count++; printf("Enter score, –1 to end: "); scanf("%d", &score); } if (count) { avg = (float) total/count; printf("Average is %.2f\n", avg); } else printf("No scores were entered\n"); Chapter 10 Sentinel-control repetition 46 ‘do-while’ construct Loop structure with post-test condition. do statement ; while (expression); Loop body is executed at least once. Chapter 10 ‘do-while’ construct 47 ‘do-while’ construct Examples: count = 1; do { printf ("%d ", count); } while (++count <= 10); do { printf("Enter a letter A thru E: "); scanf("%c", &letter); } while (letter < 'A' || letter > 'E'); Chapter 10 ‘do-while’ construct 48 Flag-controlled loops When loop condition is complex, flags may be used. valid = 1; while (valid) { printf("Enter a letter A thru E: "); scanf("%c", &letter); valid = (letter >= 'A' && letter <= 'E'); } Chapter 10 Flag-controlled loops 49 ‘for’ construct Another pre-test loop structure. Provides more compact form for countercontrolled loops. for ( initialisation-expression; loop-condition; update-expression ) statement; Chapter 10 ‘for’ construct 50 ‘for’ construct The ‘for’ construct is similar to this ‘while’ construct. initialisation-expression; while ( loop-condition ) { statement; update-expression; } Chapter 10 ‘for’ construct 51 ‘for’ construct Example: for (count_star = 0; count_star < N; count_star++) printf ("*"); Chapter 10 ‘for’ construct /* init */ /* condition */ /* update */ 52 ‘for’ construct The initialisation-expression and updateexpression are often comma-separated lists of expressions. The comma operator evaluates the list from left to right. for (x = 1, total = 0; x <= 100; x++) total += x; Chapter 10 ‘for’ construct 53 ‘for’ construct Any of the three expressions in the ‘for’ header may be omitted, but the semi-colons must stay. If initialisation-expression is omitted, you must perform necessary initialisation before loop. x = 1; total = 0; for (; x <= 100; x++) total += x; Chapter 10 ‘for’ construct 54 ‘for’ construct If update-expression is omitted, you must ensure that necessary update operations are done in loop body. for (x = 1, total = 0; x <= 100;) { total += x; x++; } Chapter 10 ‘for’ construct 55 ‘for’ construct If loop-condition is omitted, then the test is always true. This loop is infinite: for (x = 1, total = 0; ; x++) total += x; Chapter 10 ‘for’ construct 56 Common Mistakes Wrong placement of semi-colon. for (x = 1; x <= 10; x++); printf("%d\n", x); x = 1; while (x <= 10); printf("%d\n", x++); Chapter 10 Common Mistakes 57 Common Mistakes Omitting semi-colons in ‘for’ header. Mixing up semi-colons with commas in ‘for’ header. Off-by-one error, where the loop executes one more or one fewer iteration than intended. How many iterations does this loop execute? for (count = 0; count <= n; ++count) sum += count; Chapter 10 Common Mistakes 58 ‘break’ statement Used in loops, ‘break’ causes execution to break out of the loop that contains the statement. #include <stdio.h> main() { int x; for (x = 1; x <= 10; x++) { if (x == 5) break; /* break loop only if x == 5 */ printf("%d ", x); } printf("\nBroke out of loop at x == %d\n", x); return 0; } 1 2 3 4 Broke out of loop at x == 5 Chapter 10 ‘break’ statement 59 ‘continue’ statement The ‘continue’ statement causes execution to skip remaining loop body and proceed to next #include <stdio.h> iteration. main() { int x; for (x = 1; x <= 10; x++) { if (x == 5) continue; /* skip remaining code in loop only if x == 5 */ printf("%d ", x); } printf("\nUsed 'continue' to "); printf("skip printing the value 5\n"); return 0; } 1 2 3 4 6 7 8 9 10 Used 'continue' to skip printing the value 5 Chapter 10 'continue’ statement 60 Nested loops & combined structures An example of nested ‘for’ loops. for (i = 1; i <= 4; ++i) { for (j = 1; j <= 6; ++j) printf("*"); printf("\n"); } ****** ****** ****** ****** Chapter 10 Nested loops & combined structures 61 Nested loops & combined structures Example 2: for (i = 1; i <= 4; ++i) { for (j = 1; j <= i; ++j) printf("*"); printf("\n"); } * ** *** **** Chapter 10 Nested loops & combined structures 62 Nested loops & combined structures Example 3: for (i = 1; i <= 6; ++i) { if (i <= 3) printf("%d", i); else for (j = 1; j <= i; ++j) printf("*"); printf("\n"); } Chapter 10 Nested loops & combined structures 1 2 3 **** ***** ****** 63 Homework Try exercises behind chapter 10. Chapter 10 Homework 64