Basic principles of C

History of C

C has existed since 1972. Its current standard is C11 (published in 2011), but only a few details have changed since the 1989 standard (C89, also known as ANSI C). It is an extremely standardised language; different operating systems provide different libraries with different functions, but the syntax of the language is very simple. At its core, C is a very small language; there are only a handful of keywords offering basic notions such as basic types (e.g. int and float) and control structures (e.g. for and switch). The basic language is supplemented with the standard library which provides functions for basic operations, such as input and output, string handling and mathematical functions.

C is the precursor of many modern programming languages, and has influenced many others. Hence, if you are familiar with any of C++, C#, Java, Perl, PHP or Python, then you will be familiar with many aspects of C’s syntax.

Compilation and linking

C is a compiled language. Raw C code is stored in source files or header files. In order to produce an executable application, the source files must be compiled into object files, and then the object files must be linked. (Traditionally, source files have extension .c, header files have extension .h, and the object file produced by compiling foo.c is called foo.o.) The combined process of compiling and linking is called building. Sometimes, the term compiling is used to mean both compiling and linking.

Often, the same functions will need to be used by many different applications: in particular, the standard library functions. It would be wasteful for each C programmer to implement their own exp function, but exp (and other basic mathematical functions) are provided in the standard library. When writing your own program foo, all you need to do before you can use exp is to tell the compiler that exp is a function that takes in a floating-point number and returns another floating-point number. This is a declaration. For a standard library function such as exp, the declaration is included in a standard header file, here math.h, which you include into your source file foo.c:


Somewhere in math.h is a line that looks like

double exp(double);

which is the declaration of exp. You then compile foo.c and produce an object file foo.o. At this point, foo.o does not contain any details about what exp actually does; all it knows is what arguments exp takes in and what it returns. Hence you cannot run foo.o; you must link it with another object file, probably called something like math.o, where the actual implementation of exp is given.

There are two advantages to doing things this way. One is that the implementation of a function like exp can be used by millions of different programmers. The other is that your usage of a function is independent of its implementation; different systems or machines will often provide different implementations, but your part of the code will work with any of them.

In practice

The build processes require a number of commands. When building a large project, it is common to automate the build processes using a number of tools—not actually part of the C language, but important parts of its ‘culture’. GNU Make, which will be the subject of a future post, is one such tool; many projects distribute their source code along with a ‘makefile’ which contain instructions for automating the build process.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.