class: center, middle ### COMP26020 Programming Languages and Paradigms Part 1: C Programming *** # Conditionals and Loops ??? - Hello everyone, we will see different control flow statements in C: conditionals, loops, and functions. --- # Control Flow - Statements end with `;` and are **executed sequentially** ```c #include
int main() { printf("hello!\n"); // print hello first printf("goodbye!\n"); // then print goodbye return 0; // then return } ``` ??? - So until now all the programs we wrote had purely sequential statements executing one after the other. - This program prints, hello, then goodbye, then exits. - Control flow statements allow to alter that order in a structured fashion. --- class: inverse, middle, center # Conditionals ??? - Let's start with conditionals --- # Conditionals ```c if (x == 50) { printf("The value of x is 50\n"); } ``` ```c if (x == 50) { printf("The value of x is 50\n"); } else { printf("The value of x is not 50\n"); } ``` ```c if(x < 50) { printf("The value of x is strictly less than 50\n"); } else if (x == 50) { printf("The value of x is exactly 50\n"); } else { printf("The value of x is strictly more than 50\n"); } ``` .codelink[
`06-conditionals-loops/conditional.c`
] - Condition: `<`, `<=`, `>`, `>=`, `==` (equality), `!=` (difference) - **Do not use `=` for equality!** ??? - To create a conditional we use the if statement. - If the condition within the parentheses is true the code within the braces will be executed. - If the condition is false, the if body is not executed and execution resumes right after. - This will call printf only if x is equal to 50. - We can use else to define a block of code that is executed only if the condition is false. - And finally we can chain the if statement as presented on the slide. - On this example, only one of the three printf statements will be executed according to the value of x. - To write the condition you can use various operators. - Note the use of == for the equality. - Do not mix it with a single =, this can produce nasty bugs. --- # Conditionals - "false" is `0`, "true" is everything but `0` - Boolean operations: `&&` (logical AND), `||` (logical OR), `!` (negation) ```c int one = 1; int zero = 0; if (one) { /* will take this branch */} if (zero) { /* won't be taken */} if (!one) { /* won't take */} if (one || zero) { /* will take */ } if (one && zero) { /* won't take */ } if (one && zero || one && zero) { /* won't take, && evaluated before || */ } if (one && (one || zero)) { /* will take */} ``` .codelink[
`06-conditionals-loops/bool-in-conditional.c`
] - Beware of operators precedence: - `!` first, then `&&`, then `||` - Use parentheses to modify/clarify evaluation order .small[See complete list: https://en.cppreference.com/w/c/language/operator_precedence] ??? - There is no boolean type in C - A condition is false if it evaluates to 0 - And it is true if it evaluates to anything but 0 - We have the following boolean operators: logical and, logical or, as well as the negation. - Here are a few examples of usage - The negation operator is placed before the expression you want to negate - The or and and operators in between two expressions - Be careful about operator precedence, which is the order of priority of evaluation - The negation has the highest priority, then comes the logical and, then the or. - For example in this line the two ands are evaluated first, the the or - To modify the evaluation order you can use parentheses, like in this example where the OR is evaluated first --- # Switch Statement - Test the equality of an integer against a list of values ```c switch(x) { case 1: printf("x is 1\n"); break; case 2: printf("x is 2\n"); break; case 3: printf("x is 3\n"); break; default: printf("x is neither 1, nor 2, nor 3\n"); } ``` .codelink[
`06-conditionals-loops/switch.c`
] - Use `break` to avoid fall through in cases below - `default` path taken when none of the other cases matches ??? - When you have to write a long if else chain checking a given integer value, the switch statement is quite practical - You put the condition to evaluate or a variable after the switch between parentheses - Then you write a series of case blocks where the execution will jump according to the condition value - For example here let's say x is equal to two - The code will jump to case 2, do the printf - When encountering a break statement the code will exit the switch - Don't forget your breaks otherwise all the cases below the one taken will be executed - There is a special case named default that is taken if none of the other match - Note that the switch condition needs to evaluate to an integer --- class: center, middle, inverse # Loops ??? - Now let's talk about loops --- # While Loop Keep executing loop body while condition is true ```c int x = 10; printf("------ while loop:\n"); while (x > 0) { printf("x is %d\n", x); x = x - 1; } x = 10; printf("------ do ... while loop:\n"); do { printf("x is %d\n", x); x = x - 1; } while (x > 0); ``` .codelink[
`06-conditionals-loops/while.c`
] `while ...` checks the condition before entering the loop body and `do ... while` checks after a first iteration ??? - The while loop keeps executing its body as long as a given condition is true. - In this first example the code will keep printing and decrement x as long as x is superior to 0 - You have two flavors of the while loop - The first in which the condition is checked before entering the loop - And the other with do while, where the condition is checked after the loop body --- # While Loops ```c int x = -1; while (x > 0) { /* won't enter the loop body, condition checked before */ printf("x is %d\n", x); x = x - 1; } do { printf("x is %d\n", x); x = x - 1; } while (x > 0); // still does one iteration, condition checked after the // loop body ``` .codelink[
`06-conditionals-loops/do-while.c`
] ??? - This is illustrated here - In the first while loop the condition is not met so the body will never be executed. - In the second one, although the condition is also not met, it is only checked after one iteration -- What about this: ```c while(1) { printf("hello\n"); } ``` .codelink[
`06-conditionals-loops/infinite-loop.c`
] Use
ctrl
+
C
to kill a stuck program ??? - Now let's try this - It's an infinite loop, the condition is always true - If a program gets stuck, you can hit control c to kill it --- # For Loops - `for (
;
;
) {}` - `init stmt` executed once before the first iteration - `cond` checked before each iteration - `update stmt` executed after each iteration ```c int i; for(i = 0; i<10; i = i + 1) { printf("i is %d\n", i); } /* we can declare the iterator as part of the loop header */ for(int j = 0; j<10; j = j + 1) { printf("j is %d\n", j); } ``` .codelink[
`06-conditionals-loops/for.c`
] ??? - Very often we use some kind of iterator within a loop - The for loop is perfect for that - In the header of the loop you have 3 things - An initial statement executed once at the beginning of the loop - A condition checked before each iteration of the loop - If true, the loop continues, if false, it exits - And a last statement executed after each iteration, generally used to update the iterator - In this example we set i to 0 before starting the loop, which runs for as long as i is inferior to 10 - After each iteration, we increment i by one - The iterator can also be declared in the loop header - If we try to run this, we see that i and j go from 0 to 9, when they reach 10 the condition is no longer true and the loop exits --- # For and While Loops: Break and Continue - `break` within a loop body simply exits the loop ```c for(int i = 0; i < 10; i = i + 1) { printf("iteration %d\n", i); if(i == 5) { break; } } ``` .codelink[
`06-conditionals-loops/break.c`
] ??? - If you use the break statement within a loop body, it directly exits the loop - In this example the loop will iterate until i reaches 5 -- - `continue` within a loop body directly goes to the next iteration ```c int i = 0; while(i < 10) { i = i + 1; if(i == 5) { continue; } printf("iteration %d\n", i); } ``` .codelink[
`06-conditionals-loops/continue.c`
] ??? - Use the continue statement within a loop body to directly go to the next iteration - In this example we print all numbers from 0 to 9, except 5 --- # Loops and Arrays ```c int my_array[4]; for(int i=0; i<4; i = i +1) { my_array[i] = 100 + i; printf("index %d contains: %d\n", i, my_array[i]); } int my_2d_array[3][2]; for(int i=0; i<3; i++) { for(int j=0; j<2; j++) { my_2d_array[i][j] = i*j; printf("Index [%d][%d] = %d\n", i, j, my_2d_array[i][j]); } } ``` .codelink[
`06-conditionals-loops/loop-array.c`
] ??? - Loops are great to manipulate arrays - Here we fill and print an array within a loop, using the iterator as index - To iterate over a multi dimensional array we can use nested loops - On this 3 by 2 array we use a first loop doing 3 iterations and inside a second loop doing 2 iterations. - If we execute this code we can see the content of the arrays --- # Back on Command Line Argument ```c #include
int main(int argc, char **argv) { printf("Number of command line arguments: %d\n", argc); for(int i=0; i
\n", argv[0]); exit(-1); } /* Sum the two integers passed as command line integers */ int main(int argc, char **argv) { int a, b; if(argc != 3) print_help_and_exit(argv); a = atoi(argv[1]); b = atoi(argv[2]); printf("%d + %d = %d\n", a, b, a+b); return 0; } ``` .codelink[
`cmdline-args-conditional.c`
] ??? - Here is another nice example were the program is expecting two command line arguments - If the number of argument differs - Before exiting we print a line on the console indicating how to correctly call the program - We can try this --- # Braces in Conditionals and Loops - Conditional/loop body is a single statement? can omit the braces ```c if (x) printf("x is non null\n"); else printf("x is 0\n"); for (int i = 0; i<10; i = i +1) printf("i is %d\n", i); ``` - **Warning: if adding a second statement, put the braces back** - See the Apple bug: [https://bit.ly/3ktvgF4](https://bit.ly/3ktvgF4) - **Also, ambiguity:** ```c if(one) if(two) foo(); else // whose else is this? bar(); ``` ??? - When a conditional/loop body is comprised of a single statement, we can omit the braces - That being said, be careful if later you want to add more statements, you need to put the braces back - Forgetting to do so can lead to nasty bugs - With nested conditionals omitting the braces can also lead to ambiguity about the else clauses, as depicted in the example - Modern compiler will generally issue a warning in that case --- # Summary - Conditionals: `if`, `switch` - Loops: `while`, `for` ---- .center[Feedback form: https://bit.ly/3jxgOxf]
??? - Let's wrap up - We saw about conditionals with the if and switch statement - We also talked about the while and the for loops - In the next video, we will look at functions