1.2 Compiling and program structure
1.2.1 Quick start
It is well-known that one starts to learn a new programming language by writing a program to print “hello world”. This example was given in K&R with the following C program.
Listing 1: Hello world.
Above program contains the main function, in which a printf
function is called to print “hello, world”. Let’s start our hands-on work with this hello world program. Open a text editor say notepad (or notepad++ if it is installed), type in the program, and save it as a text file with a name that ends in “.c”, such as hello.c
. Then open a command console, cd to the directory, where hello.c
is saved. Type the following command to compile (assuming that the GCC compiler was installed).
gcc hello.c
The compiling will create an executable program named a.exe
in the same folder under Windows OS, or a.out
in Linux or macOS. Under Windows, we run a.exe
by command: a.exe
or simply a
. Under Linux, we run a.out
by command: ./a.out
or simply ./a
. The output on the console will be:
hello, world
Now you have created, compiled, and run your first C program.
1.2.2 Compiling and execution
Command gcc hello.c -o hello.exe
creates the same executable program of file name hello.exe
as specified by the output option -o
in command line.
What happens with compiling?
The compiling converts a C source code program to an executable program. The compiler does the compiling in order of the following steps:
Compiler options
GCC compilers have options to do compiling. Command gcc --help
will list available options for gcc. The following options are commonly used.
Option | Purpose | Example |
---|---|---|
-std=c99 | Use C99 standard for compiling | Command gcc –std=c99 hello.c will use the C99 compliant compiler to compile. |
-c | Suppress linking step, just generate an object file | gcc –c hello.c will create the object program file hello.o |
-g | Embed diagnostic information into the object file for debugging | gcc –g hellow.c |
-o | Specify output file name | gcc –o hello.exe hello.c creates hello.exe file. |
-S | Suppress the assemble and linking steps and output the assembly program file. | gcc –S hello.c will create assembly program file hello.s |
-O? | Optimization level: 0 off, 1 default, 2, 3, 6 higher level | gcc –O3 hello.c |
-Wall | Give compiling warning | gcc –Wall hello.c |
C programming has the following file name extension convention.
Extension | File type |
---|---|
.c | C program source code file, e.g. hello.c |
.h | C program header file, e.g., sdtio.h |
.exe | Default executable program file for Windows OS, .out for Linux and macOS. |
.o | Object file, e.g. hello.o |
.s | Assembly program source file, e.g., hello.s |
.lib | Static library of object modules (.a for UNIX/Linux/macOS) |
.dll | Dynamic library file for Windows OS (.so for UNIX/Linux/macOS) |
What happens when running an executable program?
When issuing command hello.exe
in the command console, the console starts a new process which loads the executable program hello.exe into the main memory, and starts the execution of the program from the first instruction of the main function.
At execution, an instruction is read from memory to CPU. CPU does the operation according to the instruction. After the instruction execution is complete, program flow control gets the next instruction, which can be the instruction after the previous one, or an instruction in another location.
The execution terminates at the end of the main function. The process of running the program exits and the console returns the prompt for next command input.
1.2.3 C program structures
To build an executable program, a main function must be presented in the source code program file. That defines the starting point of the program. The main function contains a sequence of statements. A statement may contain a function call, i.e., calling to run another function.
Generally, a function contains a sequence of statements, and a function can call other functions including itself. Statements (sometimes called commands) are executed strictly one after the other. In computer science, such kind of programming is called imperative programming and further organizing statements into functions is called procedural programming.
The function based program construction defines the C program structure. A C program is organized as a collection of functions, one of them is the main function. A function contains a sequence of statements. A statement may call another function. Functions are related by calling relations.
Function A is dependent on function B, if function B is called in function A, and function B must be presented (declared or defined) when function A calls it. Otherwise the compiler will be confused by the function name. Thus the appearances of functions in source code program must be in right ordering . This adds difficulties in managing C functions. To avoid the issues caused by the function ordering, a common practice in C programming is to declare all functions before they are defined and used. In this way, the ordering of function definitions/implementations does not matter any more. The following is a general model of C program structures.
[preprocessor directives] [global variables] [function declarations] main( arguments ) { [statements] } [function definitions]
Here, we use [] to represent a list of items. The following C program example uses the above C program structure model.
Listing 2: C program structure example.
/*
C program structure example
*/
#include<stdio.h> // preprocessor directive include
int a; // global variable declaration
int add(int, int); // function declaration
int minus(int, int); // function declaration
int main() // main function
{
a=1; // assign/set value 1 to global variable a
int b=2; // declare local variable b and initialize/set it to value 2
printf("a+b=%d\n", add(a, b)); // function calls
printf("a-b=%d\n", minus(a, b)); // function calls
return 0;
}
// definition/implementation of function add(int, int)
int add(int x, int y) // function header
{
return x+y; // function body
}
// definition/implementation of function minus(int, int)
int minus(int x, int y) // function header
{
return x-y; // function body
}
In the main function, statement printf("a+b=%d\n",add(a,b));
calls the stdio library format print function printf
. The printing format is specified by format argument “a+b=%d”, where %d
will be replaced by the integer string of the return value of function call add(a, b)
. Save the above program file file, say testmain.c
, compile and run the program in command line console:
gcc testmain.c -o testmain.exe testmain.exe
We have output:
a+b=3 a-b=-1
1.2.4 C program organization
A C program gets big and complex when the number of functions increases. To manage the complexity of a C program, a C program is often decomposed into several files including function header program files, i.e. files with .h extension, and function implementation program files, i.e. files .c extension). A function implementation program includes a group of function header files if the its functions call the functions given in the header files. A function implementation program can be compiled separately into object programs by using the -c option. A function implementation program may not contain the main function. The set of object programs (one of them must contain the main function) can be linked together to create an executable program.
The following code lists show an example of decomposing the above program into three files.
Listing 3: C header file
/**
* addsub.h
* header file contains function headers
*/
#ifndef ADDSUB_H // set compiling condition to avoid redefinition
#define ADDSUB_H
/**
* @param x - int value
* @param y - int value
* @return - sum of x and y, int value
*/
int add(int x, int y);
/**
* @param x - int value
* @param y - int value
* @return - subtract y from x, int value
*/
int minus(int x, int y);
#endif
Listing 4: C header implementation
Listing 5: C main program
The following command compile all necessary programs to create the executable program.
gcc addsub.c addsub_main.c -o testmain.exe
The following commands show the partial comiling and linking to create the executable program.
gcc addsub.c -c gcc addsub_main.c -c gcc addsub.o addsub_main.o -o testmain.exe
The first two commmands create object programs addsub.o
and addsub_main.o
respectively. The last command links the two object programs to create the executable program testmain.exe
1.2.5 Exercises
Self-quiz
Take a moment to review what you have read above. When you feel ready, take this self-quiz which does not count towards your grade but will help you to gauge your learning. Answer the questions posed below.