UP | HOME

4. Control Flow

Table of Contents


Loops

One of the most useful properties of progammable computers is that you can ask them to repeat a calculation and/or operation many many times, and they will not (usually) complain. The looping constructs in C allow us to repeatedly execute a block of code many times, without having to manually re-type or re-list the code by hand.

As a simple example, let's say we want to compute the cumulative sum of integers between 1 and 100. We could write code like the following:

int cumsum = 0;
cumsum = cumsum + 1;
cumsum = cumsum + 2;
cumsum = cumsum + 3;
...
cumsum = cumsum + 100;

As you can see, not very efficient. As a general rule of programming, any time you find yourself copying and pasting code bits many times over, you should be thinking to yourself, there must be a better way, there must be a way to specify this code more abstractly so that it's more compact and reusable. Here, we can use a for-loop to achieve what we need.

For Loop

A generic for-loop looks like this:

for (init_expression; loop_condition; loop_expression) {
  program_statements
}

The three expressions inside the round brackets set up the environment for the loop. The init_expression is executed before the loop starts and is typically where you define some initial value that will change each time through the loop. The loop_condition is an expression that determines whether the loop should continue, or stop. Of course if you don't specify a condition under which the loop should stop, it never will, and you will have an endless loop and your program will never terminate. The loop_expression specifies code that is executed each time through the loop, after the body of the loop is executed. This is all very abstract, so let's see a concrete example, by coding a loop to implement the cumulative sum as above.

#include <stdio.h>

int main() {
        int cumsum = 0;
        int i;
        for (i=1; i<=100; i++) {
                cumsum = cumsum + i;
        }
        printf("the cumulative sum up to 100 is %d\n", cumsum);
}
the cumulative sum up to 100 is 5050

Let's go through the code for the for-loop and understand what is happening. On lines 4 and 5 we declare the integer variables cumsum and i, and we initialize the value of cumsum to 0. On line 6 we declare the for-loop. The first expression in the round brackets is a statement which initializes the value of the i variable to be 1. This is executed before the loop starts. The next expression is a conditional which is TRUE if i is less than or equal to 100 and is FALSE otherwise. This expression is evaluated prior to each iteration of the loop. When this expression is FALSE the loop terminates, otherwise the loop iterates again. Finally the third expression in the round brackets, i++ is executed after each iteration of the loop. In this case, we increment the i variable by one.

On line 7 is the code block that forms the body of the loop. This is code that is executed on each iteration of the loop. In this case we add the current value of i (which changes each time through the loop) to the cumsum variable. On line 8 the closing bracket } specifies the end of the body of the loop. On line 9 we print to the screen the value of the cumsum variable.

As you can see, the use of a for-loop enables us to write the code for incrementing the cumsum variable just once, and place it inside a loop, that is constructed so that it executes that code 100 times, and each time, uses a different value of i.

While Loop

The while-loop is another looping construct that you might find more appropriate than a for-loop under some circumstances. A while-loop looks like this:

while (conditional_expression) {
   program_statements;
}

The while-loop will first check the value of the conditional_expression, and if it is not FALSE (i.e. if the expression returns a non-zero (non-FALSE) result, the program_statement (or multiple statements) will be executed once. Afterwards the conditional_expression will be evaluated again, and if it returns a non-zero result, the program_statment (or multiple statements) will be executed again, and so on. The while-loop will stop only when the conditional_expression returns zero.

Here is a simple program that demonstrates the use of a while-loop:

#include <stdio.h>

int main() {
        int number = 0;
        while(number != 999) {
                printf("Enter an integer or 999 to stop: ");
                scanf ("%i", &number);
                printf("%d x 10 = %d\n", number, number*10);
        }
}

The program asks the user to enter an integer, and then the program prints to the screen the value of the integer multiplied by 10. If the user enters 999 then the program terminates. Enter it into your code editor and compile and run it, to see how it works.

Do-While Loop

There is another version of a while-loop that is essentially the same as a while-loop but it reverses the order of the program_statement and conditional_expression:

#include <stdio.h>

int main() {
        int number = 0;
        do {
                printf("Enter an integer or 999 to stop: ");
                scanf ("%i", &number);
                printf("%d x 10 = %d\n", number, number*10);
        }
        while (number != 999);
}

The choice of a for-loop, a while-loop, or a do-while-loop, is up to you and the best one to use may differ depending on circumstance.

Conditionals

One of the most important constructs in programming is the ability to execute (or not execute) pieces of code, or execute different pieces of code, depending on the outcome of some decision or question about data. The if-else construct lets us to this in C.

If Statement

The basic if statement looks like this:

if (conditional_expression) {
   program_statements;
}

The program_statements are only executed if the conditional_expression returns a non-zero value, i.e. if it returns a value that is not FALSE (FALSE = zero).

For example, here is a simple program that loops through the integers between 1 and 10 and prints to the screen the integers that are odd (that are not divisible by 2 with zero remainder):

#include <stdio.h>

int main() {
  int i;
  for (i=1; i<=10; i++) {
    if ((i % 2) != 0) {
      printf("%d is odd\n", i);
    }
  }
}
1 is odd
3 is odd
5 is odd
7 is odd
9 is odd

Else

We can add an else to our if statement, to execute a different code block if the value of the conditional_expression is zero:

#include <stdio.h>

int main() {
  int i;
  for (i=1; i<=10; i++) {
    if ((i % 2) != 0) {
      printf("%d is odd\n", i);
    }
    else {
      printf("%d is even\n", i);
    }
  }
}
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even

Else If

You can string together several conditional tests and execute different pieces of code by using the else if construct. Here is a simple program that asks the user to enter an integer, and prints to the screen whether that integer is positive, negative, or zero:

#include <stdio.h>

int main() {
        int number;
        printf("enter an integer: ");
        scanf ("%i", &number);
        if (number < 0) {
                printf("the integer %d is negative\n", number);
        }
        else if (number > 0) {
                printf("the integer %d is positive\n", number);
        }
        else if (number == 0) {
                printf("the integer %d is zero\n", number);
        }
        else {
                printf("this statement should never be executed!\n");
        }
}
enter an integer: 123
the integer 123 is positive

The Conditional Operator

There is a convenient shorthand for simple if-else constructs, using the so-called conditional operator:

condition ? expression1 : expression2

It enables you to shorten your code a bit, but that's all. It doesn't give you any additional functionality, it's just a shorthand:

#include <stdio.h>

int main() {
  int i;
  for (i=1; i<=10; i++) {
        (i % 2) ? printf("%d is odd\n", i) : printf("%d is even\n", i);
  }
}
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even

Switch

The case of multiple if-else statements strung together to test for different values, and execute different code, is common enough that there is a special construct called the switch statment that is provided for this case:

switch (expression)
{
   case value1:
              program statement;
              program statement;
              ...
              break;
   case value2:
              program statement;
              program statement;
              ...
              break;
   case value3:
              program statement;
              program statement;
              ...
              break;
   default:
              program statement;
              program statement;
              ...
              break;
}

This is equivalent to the following series of if-else statements:

if (expression == value1) {
   program statement;
   program statement;
   ...
}
else if (expression == value2) {
   program statement;
   program statement;
   ...
}
else if (expression == value3) {
   program statement;
   program statement;
   ...
}
else {
   program statement;
   program statement;
   ...
}

From my point of view the decision to use a switch statement versus a series of if-else statements is purely stylistic and is up to you. They accomplish the same thing.

Break & Continue

There is a special statement in C called break that allows you to exit from a loop other than by testing at the top or bottom. As we saw above in switch statements we also use break to exit from each case.

The continue statement is not used very often. It causes the next iteration of a loop to begin. You can think of it as a sort of a statement to "do nothing, just continue".

Exercises

  • 1 FizzBuzz : Write a program that prints the numbers from 1 to 100. For multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".
  • 2 Write a program to estimate the square root of 612 using Newton's method, using 5 iterations.
  • 3 Write a program that displays a triangle with height \(n\) and width \(2n-1\). The output for \(n=6\) would be:
     *
    ***
   *****
  *******
 *********
***********

Solutions


Paul Gribble | Summer 2012
This work is licensed under a Creative Commons Attribution 4.0 International License
Creative Commons License