Fundamental C - Program Structure
Written by Harry Fairhead   
Monday, 17 October 2016
Article Index
Fundamental C - Program Structure
The Flow of Control
Loops
Nesting

The Flow of Control

If you look at any list of instructions, i.e. any program in the widest possible sense, then there are only a few very ways that the instructions can be organised. In fact there are just three basic approaches to  presenting a list of instructions, even in a natural language:

  • You can write a one-after-the-other list.

  • You can write a conditional list for example, 
    "if it is raining then pick up the umbrella"

  • You can specify a repetition, for example, 
    keep stirring you coffee until the sugar dissolves.

 These three are the only three possible forms that a list of instructions can take and it can be proved that if you have these three forms then you can write any program that can exist. 

A language that has these three things is said to be "Turing complete", after the mathematician and early computer pioneer Alan Turing. You might be able to guess that C is indeed Turing complete and has all three forms. This observation was, and is, the basis of the structured programming philosophy that aims to restrict programming and programmers to just these three fundamental forms clearly expressed. While you can take other more complicated instructions these are the "programming atoms" from which all other programs can be constructed.

If you have a list of instructions in front of you then you can follow the order of execution of the instructions, or the "flow of control", simply by tracing your finger along the instructions in the order that they are carried out. The resulting shape is called the flow of control graph and it is fundamental to programming.

If you understand how to build a flow of control graph that does a particular job then you are a programmer and if you don't you aren't.

The three fundamental flow of control forms correspond to a straight line segment following the one after the other order of instructions, a branching structure that divides between alternative lists of instructions and a circular looping shape that indicates the repetition of instructions.

 

flow

 

All programming languages have instructions which are obeyed one after another. In C a sequence statements have to be separated by a semicolon. For example

instruction 1;
instruction 2;
instruction 3;

is a program that does instruction1, followed by 2 and finally 3. The semicolons are statement separators and they are the only thing C takes notice of - white space and new lines are just ignored. So you could write

instruction 1;instruction 2;instruction 3;

In most cases it is better to write one instruction per line and only group things together on a single line if it helps understanding.  For example;

a=b+c;
d=e+f;

is better over two lines as the two statements have nothing to do with each other, but

x=23;y=100;

make sense on the same line if x and y are the coordinates of a point.

This is something programmers can and do argue about. 

The most important thing is to try to write C that is maximally understandable and any formatting that you can use to make things clear is a good thing - but cramming everything on one line just to save space on the page is always a bad thing.

Executing one instruction after another is known as the default flow of control. As the program is executed only one instruction has the attention of the processor at any moment and this is the instruction that is said to be in "control" and control passes through the program from left to right and top to bottom in the usual order that English is read. 

As well as the default flow of control all computer languages have two other patterns of flow of control - the conditional and the loop. Let's see how C deals with each of these. 

The Conditional

In most computer languages the conditional is implemented using some construct involving the words if and else.

In C the simplest if statement is

if(condition) instruction;

The instruction is only carried out if the condition is true. 

For example:

if(x>10) y=5;

although we havn't covered very much C this should be understandable. The variable y is only set to five if x is greater than 10. The instruction is skipped if the condition isn't true. 

This simple form of if statement is enough for many situations, its is the one you will use the most, but sometimes you want to do instruction1 if the condition is true and instruction2 if it is false. In this case you need the else statement. 

if(condition) instruction1; else instruction2;

Now instruction1 is carried out if the condition is true and instruction2 if it is false. Notice that only one of instruction1 or instuction2 will be carried out. 

You write conditions in much the way that you would in arithmetic. For example x>10 is true if x is greater than 10. The comparison operators are:

>     greater than              
<     less than                 
>=    greater than or equal     
<=    less than or equal    
==    equal to                 
!=    not equal to   

Notice that == is a test of equality and = is an assignment. It is really important to make sure that you understand the difference. Even if you do understand the difference, you will occasionally use get things wrong. Notice that: 

a==0;

is true if a contains 0 and

a=0;

stores 0 in a. 

Once you know how to write a condition you can start using if statements. For example:

if(x>10) y=5; else y=0;

sets y to 5 if x is greater than 10 and sets y to 0 if it isn't. You can write the if..else construct on separate lines:

if(x>10) y=5;
else y=0;

Notice that: 

if(x>10) y=5; else y=0;

is not the same as: 

if(x>10) y=5;
y=0;

The first one sets y to 5 or 0 depending on the value of x. The second always sets y to 0 after sometimes setting it to 5. 

The Compound Statement

You may be wondering how C copes with the problem of conditionally executing any number of statements. The if and the else only let you write a single statement after them. This seems to be very limited, but C has a powerful idea that simplifies many things. You can use curly brackets to group any number of instructions together to make a compound statement. A compound statement is treated as if it was a single statement. 

That is:

{instruction1;instruction2;instruction3;}

is the same as

instruction1;
instruction2;
instruction3;

but it is treated as a single statement.

Notice that you don't need a semicolon at the end of a compound statement as the closing bracket signifies the end of the statement. It doesn't matter if you do put a semicolon at the end, however, as the compiler will ignore it.

So you can now write:

if (condition){instruction1;instruction2;instruction3;}

and instructions 1 through 3 will be carried out if and only if the condition is true. 

You can format this as:

if (condition){ 
 instruction1;
 instruction2;
 instruction3;
}

This is the way that NetBeans will format the if for you and it is the most common way to write an if, but there are many arguments about how it should be done. Notice that the indenting makes it easier to see the start and end of the if statement. 

To get NetBeans to format your program simply use the command Source,Format or right click and select Format. The shortcut is Alt-Shift-F.  Autoformattting is a suprisingly good way of finding errors in your code. If NetBeans doesn't format it the way you expect then you have entered something incorrectly.

Using compound statements in the if..else construct you can write things like:

if (condition){ 
 instruction1;
 instruction2;
 instruction3;
} else {
 instruction4;
 instruction5;
}

This will carry out instructions 1,2 and 3 if the condition is true and 4 and 5 if it is false. This too is the way NetBeans will format the code for you and again there are arguments that other ways are better. 

There are more advanced forms of the if statement but the simple if and the if..else cover most of the situations you encounter. 

More advanced conditionals are covered later.



Last Updated ( Tuesday, 11 September 2018 )