2. If Statements, Loops, Expressions and Functions
This tutorial introduces you to conditional statements (if statements) and loops. Along the way, you're also introduced to variable declarations, assignment statements, and expressions. The tutorial also introduces the concept of functions.
Assumed Background
It is assumed that you have undertaken tutorial 1 and, ideally, have read one of the associated readings.
Associated Reading
The following textbook sections are relevant:
- Kernigan & Ritchie (2nd ed.) - pages 8 to 14, sections 1.7 to 1.10, 4.1 to 4.4, 4.9 (we haven't covered all of these concepts yet)
- Harbison & Steele - second chapter (it covers much more than this tutorial - please read selectively), 4.1 to 4.6, 5.1 to 5.2, 7.1 to 7.12, 9.1 (we haven't covered all of these concepts yet)
Other material within this text is also relevant.
An online C Reference Manual (by Martin Leslie) is also available. Relevant sections include (but are not limited to):
- Data types
- if
- while
- for
- printf
- scanf
- Operators and Expressions
- Functions (ignoring the stuff about pointers for now)
- Void keyword
Start the Development Environment
Start the development environment as described in tutorial 1. You may wish to create a new project for this tutorial. You may type (cut and paste) each program in a separate C file or you may just use one C file and just overwrite your previous program each time.
Conditional statements
Most programs need to make decisions based on the data they're operating on. For example, consider the following program:
#include <stdio.h>
int main() {
int num;
/* Prompt for and read in number from user */
printf("Enter number: ");
scanf("%d", &num);
if((num % 2) == 1) {
printf("%d is odd\n", num);
} else {
printf("%d is even\n", num);
}
return 0;
}
You should type this program into the editor (or copy and paste it in) and run it. There are several new concepts illustrated in this program:
- if ...
- This is a conditional statement that takes the general form:
if(expression1) {
statement1;
}
else if (expression2) {
statement2;
}
...
else {
statementn;
} - If the first expression is true, then the first statement is executed. If the second expression is true then the second statement is executed, and so on. If no expression is true, the last statement is executed. Note that the else parts of the statement are optional. Note also that any of the statements can actually be multiple statements enclosed in braces. It is good programming style to always use the braces as in the example above. C interprets an expression of value 0 as false and any expression with non-zero value as true.
- num % 2
- The % or modulus operator returns the remainder of dividing the integer on the left by the integer on the right, i.e. x % y produces the remainder when x is divided by y (e.g. 11 % 3 is 2, 12 % 3 is 0). Other arithmetic operators include + (addition), - (subtraction), * (multiplication) and / (division). Note that / (division) applied to integers will produce the quotient - i.e. any remainder will be thrown away (e.g. 11/3 = 3). Use the % operator to obtain the remainder. The +, -, * and / operators can be applied to floating point numbers, however the % operator can not.
- (num % 2) == 1
- The == operator performs an equality comparison between the expression on the left (num % 2 in this case) and that on the right (1 in this case) and produces true (i.e. a non-zero value) if they're equal and false otherwise (i.e. 0).
- printf("%d is odd\n", num);
- We used printf() in tutorial 1 to print "Hello World" and other strings. The printf()
function takes a variable number of arguments. The first argument is a string
of characters (formatting string) to be printed with each % indicating where
the other arguments are to be substituted (and the character after the percent
indicating the type of the argument). For example, %d indicates an integer.
You must ensure that the type of the argument matches that specified in the
formatting string.
Note that printf() is not part of the C language - it's just a function defined in a standard library of functions. Not all implementations will have a printf() function. We'll see further examples of printf() statements below.
Exercise
1. Modify the program above to print whether a number is divisible by 7 or not.
Loops
A "loop" is a programming construct that lets you repeat a number of actions a certain number of times (or until a certain condition is true or false). We're going to look at several ways of writing loops in C.
Consider the following flowchart which illustrates how to add the integers 1 through 10 and output the result:

The C equivalent of this program is:
#include <stdio.h>
int main() {
int num, sum;
num = 1;
sum = 0;
while(num <= 10) {
sum = sum + num;
num = num + 1;
}
printf("Sum = %d\n", sum);
return 0;
}
You should type this program into the editor (or copy and paste it in) and run it. There are several new (as well as some already familiar) concepts illustrated in this program:
- int num, sum;
- Note that multiple variables of the same type can be declared on the same
line.
The declaration could have been written as two lines:
int num;
int sum; - num = 1;
- This line is an example of an assignment statement. The variable on the
left of the equals sign is assigned the value of the expression on the right.
Assignment statements take the form:
variable-name = expression; - while(num <= 10) {
...
} - This is a while-loop. The program will execute the statements within the
loop while the expression within the parentheses is true (i.e. in this case,
while the value of the variable num is less than or equal to 10). While-loops
take the form
while(expression) {
statement;
...
}
and result in the execution of the statements (called the body of the loop) until the expression becomes true. - The braces may be omitted if there is only one statement within the loop:
while(expression)
statement;
but it is usually safer to include them.
Note that it is conventional to indent the body of a loop to indicate the logical structure of the program, however, the C compiler doesn't care about indentation. - sum = sum + num;
num = num + 1; - These are further examples of assignment statements. The variable on the
left is assigned the value of the expression on the right. Because it is quite
common to add some value to a number, C has a special way of writing this. These
statements could be rewritten as:
sum += num;
num += 1;
Further, because adding one to a number is quite common in C, it is possible to rewrite num += 1 as
num++;
or
++num;
The ++ means increment by one and can be used as a postfix operator (after the variable name) or prefix operator (before the variable name). These can be used within expressions and have different values, e.g.
sum += (num++);
means
sum = sum + num;
num = num + 1;
whereas
sum += (++num);
means
num = num + 1;
sum = sum + num;
A similar operator (--) exists for decrementing (i.e. subtracting one).
Exercises
2. Modify the program above to calculate the factorial of 7 - i.e. multiply all
integers from 1 to 7. Note that the *= operator can also be used in a similar way
to the += operator.
3. Modify the program further so that it reads a number from the user and calculates
the factorial of that number. Try running this program multiple times and determine
the largest number for which you get a "reasonable" answer for the factorial. Why
do you stop getting "reasonable" answers at some point?
For Loops
Another way of writing loops is with a for-loop statement. Consider the following program (type this into the editor and run it):
#include <stdio.h>
int main() {
int num, sum;
sum = 0;
for(num = 0; num <= 10; num++) {
sum += num;
}
printf("Sum = %d\n", sum);
return 0;
}
This program does exactly the same thing as the while loop example above. For
loops take the form:
for(initialisation; test-expression;
increment)
statement
where statement can be replaced by any number of statements within braces.
There are three parts within the parentheses - separated by semicolons. The first
part is the initialisation - performed once before the loop is entered. The second
part is the test expression - the body of the loop is executed when this expression
is true. If the body of the loop is executed, the increment part is then executed
and the test expression is re-evaluated. (Note that the increment step does not
have to increment by 1 - any expression can be used here.
To add the odd numbers from 1 to 99, the for loop above could be modified to:
for(num=1; num <= 99; num
= num+2) {
sum += num;
}
Note that a for loop can always be written as a while loop:
initialisation;
while(test-expression) {
statement(s);
increment;
}
The choice between using a while loop and a for loop is somewhat arbitrary. Often
a for loop is used when a fixed sequence is being counted through.
Loops can be nested. Type the following into the editor and run it:
#include <stdio.h>
int main() {
int a, b;
int size;
size=10;
for(a=1; a <= size; a++) {
for(b=1; b<= size; b++) {
/* Print out the sum of a and b - using a field width of 3 */
printf("%3d ", a+b);
}
printf("\n");
}
return 0;
}
The only new concept here is the use of a field width in the printf function. %3d means print out an integer using a minimum field width of 3 characters - i.e. if the number will take fewer than 3 characters when printed then pad it out with spaces so that it takes 3 characters.
This program produces an addition table for the first 10 integers:
2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19 11 12 13 14 15 16 17 18 19 20
We can extend the program to add some headings. Work through this program to make sure you understand how it works.
#include <stdio.h>
int main() {
int a, b, i, size;
size=10;
/* Write out heading line */
printf("a+b| ");
for(b=1; b <= size; b++) {
printf("%3d ", b);
}
printf("\n");
/* Write out separator line (dashes) */
printf("---+-");
for(i=1; i <= size*4; i++) {
printf("-");
}
printf("\n");
for(a=1; a <= size; a++) {
printf("%2d | ", a);
for(b=1; b<= size; b++) {
printf("%3d ", a+b);
}
printf("\n");
}
return 0;
}
Exercises
4. Modify the program above to produce a multiplication table.
5. Try modifying the field width specifications so that the table is slightly more
spread out. What other lines have to change?
6. Modify the program to produce an addition table for numbers from -5 to 5 inclusive
(rather than 1 to 10)
7. Modify the program to use while loops instead of for loops.
Functions
A function is a self-contained part of a program which carries out some well-defined task. One function we've seen so far is printf() - for printing out formatted strings. This function has been provided for us in the Standard C library. In this tutorial we will look at functions written by the programmer.
Functions allow a program to be organised in well defined 'chunks'. Consider the following program which defines a function that calculates powers of integers (e.g. 3 to the power of 2). Type (or cut and paste) this in and run it.
#include <stdio.h>
int power(int base, int n) {
int p;
p = 1;
while(n > 0) {
p = p * base;
n--;
}
return p;
}
int main() {
int i;
int powOf2;
for (i=0; i < 10; i++) {
powOf2 = power(2,i);
printf("%d %d %d\n", i, powOf2, power(-3, i));
}
return 0;
}
Elements of this program are explained below:
- int power(int base, int n) {
- This line begins the function definition. The first "int" is the return type of the function (i.e. an integer). This is followed by the name of the function (power) and then a list of function arguments or parameters. In this case, the power function takes two arguments - both integers. The function definition includes a group of statements within braces {}.
- int p;
- This declares a variable - known as a local variable - it is only accessible within the function. Local variables come into existence when the function is called and are deallocated after the function returns. Local variables and the concept of scope are discussed further below. Note also that the argument variables (base and n) are local variables - they come into existence when the function is called.
- return p;
- This returns the value of p as the result of the function. (Note that it
is legal to have multiple return statements in a function - e.g. you might write
something like:
if (expression) {
return value_1;
} else {
return value_2;
} - power(2,i)
power(-3,i) - These are function calls - which cause the function to be evaluated using the values of the given arguments. In one case above (power of 2), we assign the value to a variable (powOf2) before passing it as an argument to printf. In the other case (power of -3), we pass the value directly to printf. The choice we have made is arbitrary.
In this example, the function power() is defined before it is used (within the main() function). This isn't always possible - so in these circumstances it is necessary to at least declare the function before it used. A function declaration (also called a function prototype) for power() would look like:
int power(int base, int n);
or
int power(int, int);
i.e. it specifies the name of the function, the types of the parameters and the return type. Note the semicolon at the end rather than opening braces to begin the function definition. (It is not necessary to include the parameter names - and they do not need to match the names used in the function definition. It is useful to include parameter names, however, as a reminder to the programmer as to what arguments are expected. For example, if we wanted to define the main() function before other functions (some programmers prefer to do this) then we'd need to include such a function prototype before main():
#include <stdio.h>
int power(int base, int exponent);
int main() {
int i;
int powOf2;
for (i=0; i < 10; i++) {
powOf2 = power(2,i);
printf("%d %d %d\n", i, powOf2, power(-3, i));
}
return 0;
}
int power(int base, int n) {
int p;
p = 1;
while(n > 0) {
p = p * base;
n--;
}
return p;
}
Exercises
9. Modify the program above so that it produces the same output, but does NOT
assign the power of 2 to a variable before printing it.
10. Write a program that asks the user for a number base (integer) and then prints
out the first 16 powers of that number (i.e. n0 to n15). You
should be able to reuse the power() function - this is why functions are useful.
Void
Some functions don't return anything - in which case they are declared with a return type of void. (We'll see an example below.) Also, in some circumstances, the return type of a function is ignored. For example, the printf() function always returns the number of characters output but because we don't do anything with the return value (e.g. we don't assign it to a variable) this value is lost.
Passing by Value
Note that when a function is called, the arguments are copied into new local variables - i.e. we pass the value of the argument to the function - rather than the variable itself. Any changes made to the local variable affect only that variable and not the original source of the argument, e.g. in the example above, we pass the value of variable i as the second argument to the power() function. Each time the function is called, this value is assigned to a new local variable (called n). Changes to n within the function do not cause the value of i (in the main() function) to change.
Finishing up
When you're finished, quit wedit by selecting Quit from the File menu.
Make sure you read through the introductory material (K&R or H&S) listed above.
