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

This is an introduction to the very basics of programming in C. It covers the least you have to know to begin creating a program - variables, conditionals and loops. If you are already a C programmer then move along because there is nothing to see here. If you are a beginner then read on. 

Fundamental C: Getting Closer To The Machine

Now available as a paperback and ebook from Amazon.

  1. About C
      Extract Dependent v Independent
                  & Undefined Behavio
  2. Getting Started With C Using NetBeans
  3. Control Structures and Data
  4. Variables
      Extract Variables
  5. Arithmetic  and Representation
      Extract Arithmetic and Representation
  6. Operators and Expression
      Extract: Expressions
      Extract Side Effects, Sequence Points And Lazy Evaluation
      First Draft of Chapter: Low Down Data
  7. Functions Scope and Lifetime
  8. Arrays
      Extract  Simple Arrays
      Extract  Ennumerations
  9. Strings
      Extract  Simple Strings
    Extract: String I/O ***NEW!!
  10. Pointers
      Extract  Starting Pointers
      Extract  Pointers, Cast & Type Punning
  11. Structs
      Extract Basic Structs
      Extract Typedef
  12. Bit Manipulation
      Extract Basic Bits
      Extract Shifts And Rotates 
  13. Files
     Extract Files
    Extract Random Access Files 
  14. Compiling C – Preprocessor, Compiler, Linker
     Extract Compilation & Preprocessor

Also see the companion volume: Applying C









Which dialect of C?

The first question facing the new C programmer is which dialect of C you are going to use. You have a choice of C89, C99 or C11 plus  some slightly different versions of C that are close to these standards but with additional features. Of the main standards C89, also known as C90, is the most widely supported and often the front runner for this reason. You can spend a lot of time worrying about which version of C to use but if you are writing code for embedded systems and the IoT you have a lot more to worry about in variations in the libraries you will use. The differences between C89, C90 and C11 are mostly minor.  

In the rest of this book we will use C99 simply because some of its extra features make life easier. However, the differences are minor and come down to the ability to use single line comments and declare variables in for loops.  

Variables, assignment and expressions

Before we can move on and look at instructions - the verbs of the program - we have to have something for them to work with  - the nouns of the program.

The fundamental entity in C is the variable.

A variable is roughly speaking a chunk of storage that you have given a name to. What you can store there depends on what you specify when you create the variable.

For example, in C, and most modern languages you can store an integer (whole number) value in an int variable (int is just short for integer).

So for example

int a;

creates a variable called a that you can store an integer in.

How do you store a value in a variable?

You use the assignment operator "=". For example:


isn't a statement that a is equal to ten, it is an instruction to store the value 10 in the variable a.

Understanding what is going on becomes much easier if you always read the equals as "assign to" as in "assign 10 to a" or "store in" as in "store 10 in a". (The point is never read it as "a equals 10" because this could be a statement or a question.)

A variable can only store one value at a time so if you store another value in it then the anything already stored is lost.

For example:


stores 20 in a and any record of the 10 previously stored is lost.

Most programmers who have been working with variables quickly forget that there is any other way it could be done and might even wonder why I'm bothering to tell you all this. 

If you are happy with these basic ideas then we can add two more observations. You can both create and store a value in a variable at the same time. That is instead of writing:

int a;

you can write

int a=1;

as a shorthand.

The second idea is slightly more complicated. You can use a variable on both sides of an assignment. For example,


retrieves the value stored in b and stores it in a. After this instruction a and b store the same value. (Again it is important not to read this as "a equals b" but "store the contents of b in a". Remember that it is a command not a description.)

You can also write things like:


Here the right hand side, an arithmetic expression, will be worked out and stored in a. Notice you can use variables on the right hand side and their values will be retrieved and used in the calculation. 

You can generally write arithmetic expressions as you would normally but notice that the multiplication sign is * (an asterisk) and the division sign is /. Also feel free to use parenthesis to make sure things are worked out in the correct order. More on arithmetic and other types of expression in a later chapter. C has a very large number of operators that go well beyond the well known operations of arithmetic.

An expression can be thought of as a mini-program. It is a recipe for how to combine values stored in variables and constants to produce a new value. 

An arithmetic expression that causes a lot of problems when you first see it is:


Which if you read it as "a equals a plus 1" sounds like nonsense. What is does is to increase the value stored in a by one - i.e. its increments the value in a. If you read it as "retrieve the value in a, add one to it and store the result back in a" - then all should be clear.

Adding one to a variable is so common that C has a special command for it:


is the same as a=a+1;

There are lots of different types of data that can be stored in a variable but for the moment integer variables will serve well as an example.

Now we have something to write instructions about lets see what sort of things we can do. 

Program Structure

The first thing we need to look at it what makes a minimum program in C. If you start a new project in NetBeans, the system automatically generates a file containing:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
 return (EXIT_SUCCESS);

This is the most basic of C programs. It is simple but it contains features that will  only become clear after we have looked at quite a lot more C. 

The #includes are instructions to include the files specified, i.e. stdio.h and stdlib.h. These files are read into your program file as if you had written what they contain into your file. This is the standard way of getting library files into your program. There is more to say about this, but for the moment all that matters is that you understand that #including a file is a way to access existing code contained in the standard C libraries or third party libraries. 

Using libraries is important in C because the language itself is very simple and has few facilities. It is a minimalist language so many of features that you need to make C a useful language are provided by its libraries. For example, C has no statements or commands that relate to I/O - no print or input commands. These are simply not part of the C language and in this sense they are not "standard" - however the I/O functions that you find in the standard library might as well be part of the language because they are what every C programmer uses.

C makes use of a function called main to determine where to start executing your program. You can specify the name of the function where you want your program to start using an argument passed to the compiler, but most C programs start at main.

The only complication with main are its parameters. The first, int argc is easy, it is the number of parameters passed to main from the command line. The second is slightly more difficult to explain this early, but it is essentially an array containing the command line parameters specified by the user. We can return to this when we have explained how arrays work in C.

The main program always returns an integer to indicate success or failure. A zero is success and any other value is considered to be an error code.  This is what return EXIT_SUCCESS does for you - it returns a zero to indicate that everything has works. Notice that we use the constant EXIT_SUCCESS. Again this is not part of the language but it is defined in stdlib. You could just as well write

return 0;

Last Updated ( Tuesday, 11 September 2018 )