C Programming/Flow Control

Completion status: Almost complete, but you can help make it more thorough.

Objective

edit
  • Familiarise yourself with control structures: branching and iteration
  • Learn how to use branching flow control with:
  1. if ... else statements
  2. switch statement
  3. goto statement
  • Learn how to use iteration flow control with:
  1. for loop.
  2. while loop
  3. do ... while loop
  • Learn how to use break and continue inside loop.

Branching

edit

if ... else

edit

Overview

edit

This structure lets the program perform one of two actions, depending on the value of an expression. Its basic structure is:

if (expression) {
    statements ...
} else {
    statements ...
}

The expression is also known as boolean logic. Boolean logic is a method for telling if an expression is true or false.

If a branch contains only one statement, the {} are optional. You can use an if without an accompanying else.

An example of if ... else in action:

if (x == true) {
    printf("True");
} else {
    printf("False");
}

Statement 2 can be an if statement, which can be used to create an if ... else if ... else structure, e.g:

if (a == 'h')
    printHelp();
else if (a == 'f')
    findWord();
else if (a == 'q')
    exit(0);
else
    printf("Unknown operation %c\n", a);

The comparisons that are usable as expression are as follows:

  • x == y is true if x and y are equal
  • x != y is true if x and y are not equal
  • x < y is true if x is less than y
  • x <= y is true if x is less than or equal to y
  • x > y is true if x is greater than y
  • x >= y is true if x is greater than or equal to y

Setting variable as the if else condition

edit

At first, note the difference between the double equal sign (==) and the single equals sign ( = ). The single equals is used for assignment and will not give you the desired results.

int a = 1, b = 2;
if (a = b) {
   printf("Set b to a\n");
}

Result: Print out "Set b to a" to the console.

In the above code snippet, there are 2 variables a, b which have different value. When then set the value of b to a, by the "=" operator. As b is different from a, setting it to variable returns true, i.e the if condition (a = b) is true.

Condition when setting variable can be false (0) when the variable is set to 0:

int a = 20, b = 0;

int main(){
    if (a=b) printf("true");
    else printf("false");
}

Result: Print out "false" to the console.

When number is a condition

edit

For conditional check, all number different from 0 returns the true condition. Only number 0 and NULL (ASCII code 0) returns the false condition.

if(1) printf("%s", "true"); // true
if(2) printf("%s", "true"); // true
if(-12) printf("%s", "true"); // true
if('a') printf("%s", "true"); // true

if(0) printf("%s", "true");
else printf("%s", "false");// false

if(NULL) printf("%s", "true");
else printf("%s", "false");// false

Using number as a condition is useful when we want to shorten the condition by using the NOT operator (!)

int a = 3, b = 0;

if(!a) printf("a is 0\n");
else printf("a isn't 0\n");// a isn't 0

if(!b) printf("b is 0\n");// b is 0
else printf("b isn't 0\n");

In this code snippet:

  • As a = 3, !a returns 0 so if (!a) is false.
  • As b = 0, !b returns 1 so if (!b) is true.

Combining expressions

edit

Frequently, you won't want to just know if two values are equal - you want to know if these two values are equal and if another two are equal. Or if another two are not equal, or some other combination. Revise the previous lesson on operators, there are three operators AND, OR and NOT that can help us with this:

AND

The AND operator takes two expressions and checks if both of them are true:

expression1 && expression2

OR

The OR operator returns true if either of the expressions is true, or if both of them are true. It's only false if both of the expressions are false:

expression1 || expression2

NOT

As mentioned earlier, the NOT expression is:

!expression1

Revise the previous lesson on operators, NOT operator ! changes the value which is equal to 0 to 1 and different from 0 to 0.

Order of Operations

edit

Its perfectly legal to chain as many ANDs, ORs, and NOTs as you want. For example, !(expression1 && (expression2 || expression3)) is perfectly legal. When you do this, the different parts of the chain are evaluated according to an order of operations, just like in math. The order of operation is NOT, AND, OR. Ties are done left to right. Also just like in math, you can use parenthesis to change the default order. For example,

a && b || c

This is true if a and b are true, or if c is true. If we change it to

a && (b || c)

This one is true if a and b are true, or if a and c are true. Notice the difference- in the first one, if a was false and c was true, the total value was true. Now it would be false. Be very careful of bugs like this. When in doubt, throw parenthesis everywhere.

For the order of operations, be careful with the "double conditions"

int a = 3;
if ((1 < a < 2)){
	printf(a);
}

Result: 3 is printed out

Explanation: As we expected with Math logical, (1 < a < 3) is to whether a is inside the (1, 3). However, C interprets it diffently from the expected Math logic.

In C, the expression (1 < a < 2) is interpreted differently than you might expect. It is evaluated in two steps:

  • 1 < a is evaluated first, which results in either 1 (true) or 0 (false).
  • The result from step 1 is then compared to 2 in the second comparison.

For a = 3, the expression (1 < a) evaluates to 1 (true), and then 1 < 2 is true, so the whole expression is true. Therefore, printf("%d\n", a) will be executed, printing 3.

To implement that logic, use that AND conditions instead:

int a = 3;
if ((1 < a) && (a < 2)){
	printf(a);// Won't be printed as failed condition
}

switch ... case ... default

edit

The switch statement will go to one of several locations, depending on the value of an expression. The last example can be written using a switch statement as:

switch (a) {
    case 'h':
        printHelp();
        break;
    case 'f':
        findWord();
        break;
    case 'q':
        exit(0);
        break;
    default:
        printf("Unknown operation %c\n", a);
}

A few notes:

  • The control statement (in this example the variable a) has to have integral type (character, short integer, integer bit-field, all of these signed or not, or an object of enumeration type); integral promotion will ensure the type is either int or unsigned int.
  • The break statement ensures execution does not fall through to the next statement.
  • Control passes to the default label if none of the other case constants match the value of the control expression; if there is no default statement, none of the sub-statement of the switch is executed.

goto

edit
#include <stdio.h>

int main(){
    goto LABEL_0;
	LABEL_0:
		printf("Label 0");
    LABEL_1:    
        printf("Label 1");
        printf("outside goto\n");

	return 0;
}

Result

Label 0
Label 1
outside goto

To enter only LABEL_0 in the above code snippet, use return:

goto LABEL_0;
	LABEL_0:
		puts("Label 0");
		return 0;		
    LABEL_1:    
        puts("Label 1");
        printf("outside goto\n");
		
	return 0;

Iteration

edit

for loops

edit

The for statement has the format:

for(variables; condition; step)
{
    statements ...
}

variables is usually variable initialization; condition is the condition that keeps the loop active, usually a relational expression; step is usually an increment or decrement of one or more variables. If the loop contains only one statement, the {} are optional. Here is an example of the for loop in action:

int i;
for (i = 1; i <= 10; i++)
    printf("i = %d\n", i);

Example: Increase the index i by 2

for (int i = 0; i <= 10; i=i+2) {
        printf("%d ", i);
} // Result: 0 2 4 6 8 10

variables, condition, and step can be omitted since these are optional. When condition is omitted, the condition is assumed permanently true. Although you can omit parts of a for statement, you'll still need to separate the omitted parts with a semicolon (;).

for(;;)
    printf("This is an infinite loop!\n");

Omit 1st expression

edit
int index = 0;
for(; index < 10; index++){
	printf("index: %d\n", index);
}

Result: Print out from 0 to 9.

Omit 2nd expression

edit

The 2nd expression now is true

for(int index = 0;;index++){
	printf("index: %d\n", index);// Infinite index count up by 1
}

Omit 3nd expression

edit
int index = 0;
for(int index = 0;index<10;){
	printf("index: %d\n", index);
}

Result: Print out 0 forever.

Omit 1st and 3rd expressions

edit
int index = 0;
for(;index < 10;){
	printf("index: %d\n", index);// index from 0 to 9
	index++;
}

while loops

edit

A while loop has the following format:

while(expression) {
    statement
}

expression is evaluated. If it is true (non-zero) the body of the loop, the statement, is executed; expression is then re-evaluated and if true the body is executed again. Only when expression is false (zero) will statement be skipped and the loop terminated. If the loop contains only one statement, the {} are optional.

for(;;) is equal to while(1).

do ... while loops

edit

This is the format of the do iteration statement:

do {
    statement
} while (expression);

statement is executed repeatedly as long as expression evaluates to anything but zero. If the loop contains only one statement, the {} are optional. Here is an example of a do...while loop in action:

do {
    printf("Press 'q' to exit: ");
    scanf("%s", &str);
} while (str[0] != 'q' && str[0] != 'Q');

This will loop repeatedly, asking for input, until either q or Q is entered.
Note: A do...while loop is guaranteed to run at least once.

break

edit

The break keyword will break the execution of its current loop.

for (i=0; i<10; i++){
	if(i==5) break;
	printf("i value is %d \n", i);
}

Result:

i value is 0 
i value is 1 
i value is 2 
i value is 3 
i value is 4

continue

edit

The continue keyword is used in loops, such as for and while loops, to skip the current iteration and proceed directly to the next iteration.

for (i=0; i<10; i++){
	if(i==5) continue;
	printf("i value is %d \n", i);
}

Result:

i value is 0 
i value is 1 
i value is 2 
i value is 3 
i value is 4 
i value is 6 
i value is 7 
i value is 8 
i value is 9

Assignments

edit

Assignments of this lecture includes:

  • 4 questions to check for students understanding of conditional statement
  • Pattern generation by using flow control:
  1. Draw a rectangle with dots
  2. Draw staircase
  • Calculate the sum of all integer numbers from 1 to n

Full assignment and Answer key with code snippet.