Program flow is the order in which individual programming statements are evaluated. In C, execution starts at the beginning of the main() function and ends when the end of main() is reached however the C language includes a variety of program control statements that control the order of program execution.
The if Statement
The if statement evaluates an expression and executes statement(s) based on the outcome of this evaluation. These statement(s) are only executed if the condition evaluates to true. If the condition evaluates to false, execution is skipped and the program control passes to the statement following the if statement. Control over program execution is through the use of these compound statements which are blocks of code enclosed in brackets
The syntax of the if statement is
if (condition)
{
statement 1;
statement 2;
}
The if-else Statement – causes one of the two possible statement(s) to execute, depending upon the outcome of the predefined condition.
The syntax of the if…else statement is
if (condition)
{
// code block if condition is true
Statement 1;
}
else
{
// code block if condition is not true
Statement 2;
}
If the expression evaluates to true, statement1 is executed. If the expression evaluates to false, control passes to the else statement and statement2 is executed.
Nested if-else – contains one or more if-else statements and is validated against several different conditions, which themselves may be dependent on the evaluation of a previous condition
if( expression1 ) // code block if expression 1 is true statement1; else if( expression2 ) // code block if expression 2 is true and expression 1 is false statement2; else // code block if previous conditions are all false statement3;
If expression1 is evaluated to true, statement1 is executed before the program continues. If expression1 is not true, expression2 , is checked and if it evaluates to true statement2 is executed. If both expression1 and expression2 are false, statement3 is executed. Only one of the three statements is executed.
One-line statement – If there is only one statement to execute after the if condition the use of curly braces is optional. If there are multiple statements without curly braces then only the statement after the if condition gets conditionally executed; the rest of the statement will get executed separately and not as part of the expression. It is therefore considered good practice to use curly braces to prevent confusion and cover the possibility that the programmer may add statements to the block.
Switch Statement
The conditional statement evaluates an expression and compares its value with a number of possible constant values. When a matching switch-case case is found, the statements associated with that case are executed.
Each case can be ended with a break statement. The break statement causes execution to exit the switch statement and continue with the statement following it.
If a break statement is not used at the end of a matching case, execution falls through to the next case and continues executing the statements below it, regardless of whether those subsequent case values match the original expression.
The following is the syntax of a switch-case construct:
switch(expression)
{
case optionA:
DoSomething;
break;
case optionB:
DoSomethingElse;
break;
default:
CatchAllWhenExpressionIsNotHandledAbove;
break;
}
Looping
Many tasks in a program are accomplished by carrying out a repetitive series of instructions, either a fixed number of times or until a specific condition is met. A block of code that is repeatedly executed is called a loop. Each pass through the loop is called an iteration. When multiple statements are grouped within a loop, they can be enclosed in curly braces { } to form a compound statement (block).
The For Statement
The for statement is an iterative control-flow statement that allows a block of code to be executed repeatedly. It is commonly used when the number of iterations is known in advance.
The for statement consists of three expressions:
Iteration expression – executed after each iteration, usually to update the loop-control variable.
Initialization – executed once before the loop begins, usually to initialise a loop-control variable.
Condition – evaluated before each iteration. If the condition is true, the loop body is executed. If it is false, the loop terminates.
for ( init; condition; increment )
{
statement(s);
}
The optional initialization step is executed first, and only once. It allows the programmer to declare and initialise any loop-control variables. If no initialisation is specified, the semicolon must still be included.
Following initialization, the condition is evaluated. If the condition is true, the body of the loop is executed. If the condition is false, the loop body is not executed and program flow moves to the statement immediately following the for loop.
After the body of the for loop has been executed, program flow moves to the iteration expression. This usually updates the loop-control variable. The condition is then evaluated again. The process is repeated until the condition becomes false, at which point the loop terminates.
In the code below, the for loop is declared and the variable i is initialised to 0. The condition i < 10 is then evaluated. If the condition is true, the body of the loop is executed. At the end of the loop, the variable i is incremented by 1. The condition is then checked again and the process repeats until i < 10 becomes false, at which point the loop terminates.
#include <stdio.h>
int main( void )
{
for (int i = 0; i < 10; i++)
{
printf("%i",i);
}
return 0;
}
Leaving any parameter blank in a for-next declaration means the condition will start with a null value. You can create an infinite loop by using for(;;)
Advanced for Loops – Multiple loops can be executed by separating each statement with a comma. –
for (int a = 0, b = 0; a < 10; a++, b++)
This loop has two variable initialisations: a and b, each separated by a comma. The loop’s test section tests whether a < 10 and both integer variables are incremented.
Nested Loops – Loops can be nested with one loop sitting in the body of another. The inner loop will be executed in its entirety for every execution of the outer loop.
for ( init; condition; increment )
{
for ( init; condition; increment )
{
statement(s);
}
statement(s);
}
While Loops
A while loop causes a block of code to be executed repeatedly as long as a specified condition remains true. The while keyword is followed by an expression enclosed in parentheses.
Before each iteration, the expression is evaluated. If the expression evaluates to true, the statements inside the loop body are executed. After the loop body has executed, the expression is evaluated again. This process continues until the expression evaluates to false.
If the condition is false when it is first evaluated, the loop body is not executed and program flow moves to the statement immediately following the loop.while
while(condition)
{
statement(s);
}
Do-While Loops
A do-while loop is a control-flow statement that executes a block of code at least once.
In contrast to a while loop, which evaluates its condition before the loop body is executed, a do-while loop evaluates its condition after the loop body has been executed.
This means that even if the condition is false when it is first evaluated, the loop body will still execute once.
The syntax of a do-while loop is:
do
{
statement(s);
}
while(condition);
Ending Loops Early
The break Statement – The break statement causes a loop to end immediately, instead of waiting for its condition to become false. When a break statement is encountered inside a loop, the loop is immediately terminated and program control resumes at the next statement following the loop.
The continue Statement – The continue statement skips the remaining statements in the current iteration and causes the next iteration of the loop to begin.
In a while loop, continue causes the loop condition to be evaluated again. In a do-while loop, it causes the condition at the end of the loop to be evaluated. In a for loop, the iteration expression is executed before the condition is evaluated again.
Thus, continue allows the program to skip the remaining code in the current iteration and proceed with the next iteration of the loop.
#include <stdio.h>
int main ()
{
int a = 0;
do {
a++;
if( a == 5) //check if a equals 5, skip to end of loop
continue;
if (a==8)//if a equals 8, terminate loop
break;
printf("%i ",a);
} while( a < 20 );
return 0;
}
The Goto Statement
The goto statement performs a one-way transfer of control to another point in the program. It causes an unconditional jump, ignoring the normal sequential flow of the program, including any surrounding control structures such as loops and conditional statements. It does not automatically adjust the stack.
The destination point is identified by a label, which is specified as the target of the goto statement. A label consists of a valid identifier followed by a colon (:).
The use of goto statements can make program flow difficult to understand and maintain. Excessive or inappropriate use can result in spaghetti code, where the execution path becomes difficult to follow. It can also make the program’s behaviour and variable states harder to reason about.
For these reasons, goto statements should be used with caution and are generally best avoided when structured control statements such as if, for, while, and switch can be used instead.
The syntax for the goto statement is
{
Start: // Called a label
UserCode;
goto Start;
}
Exiting the Program
Under normal circumstances, a C program terminates when execution reaches the closing brace of the main() function.
Program termination can also be initiated by the program by calling the library functions exit() and abort(). The atexit() function can be used to register a function that is called automatically when the program terminates normally.
To use these functions, a program must include the stdlib.h header file.
Exit Function
The exit() function terminates a C program immediately. The argument supplied to exit() is returned to the operating system as the program’s exit status.
Conventionally, an exit status of 0 indicates that the program terminated successfully, while a non-zero value indicates that the program terminated with an error or an abnormal condition.
void exit ( int status );
In addition, the header file also defines two constants for use as arguments to the exit() function:
define EXIT_SUCCESS define EXIT_FAILURE
Abort Function
The abort function terminates the program immediately bypassing run-time termination processing. The syntax for the atexit() function is
void abort ();
Atexit Function
The atexit function is used to specify actions that execute before the program terminates. The syntax for the atexit() function is
int atexit (void (*func)(void));
The following short program demonstrates how to call a function before closing the program
#include <stdio.h>
#include <stdlib.h>;
void closing()
{
printf ("Program closure successful");
}
int main()
{
int x;
x = atexit(closing);
if (x != 0)
{
printf ("Program Failure");
exit(1);
}
printf ("Program successful \n");
return 0;
}