AQart's notebook: the C programming language

Unless otherwise specified on a case by case basis, these notes have been taken upon reading Kernighan B, W and D. M. Ritchie. Le langage C, Norme ANSI., 2nd edition. Translated into French (original title: The C programming language) by J.-F. Groff and E. Mottier. Masson, Paris and Prentice Hall, London, 1997.

Variable types

There are four basic variable types:

Sizes of these different types are platform-dependent (check <limits.h> and <float.h> for more information).

One can use suffixes on numerical constants to force types: u or U for unsigned, l or L for long, f or F for float. For example: 3.2F (decimal constant are of type double by default).

Order of precedence

The following table is a simplified version of the one that can be found in Kernighan & Ritchie.

OperatorAssociativity
() [] -> .left to right
! ~ ++ -- *(dereferencing) &(referencing) (type) sizeofright to left
* / %left to right
+ -left to right
< <= > >=left to right
== !=left to right
&&left to right
||left to right

Pointers

0 is the only integer that can be assigned to or compared with a pointer. It is never a valid address, so it can be used to indicate an invalid pointer. It is better to use NULL for invalid pointers though. NULL is defined in <stdio.h>.

The only arithmetic operations that are allowed with pointers are:

Enumerations

By default, enumerated variables are given values 0, 1, 2, etc. In the following example, FALSE will be set to 0 and TRUE will be set to 1.

enum {FALSE, TRUE}

One can change the starting value, for example (FEBRUARY will be set to 2, and so on):

enum {JANUARY=1, FEBRUARY, MARCH, etc.}

Structures

The size of a struct is not necessarily equal to the sum of the sizes of its individual components, because the system may pad (within the memory) some of its individual components for alignment reasons.

Common or tricky sources of errors

Order of evaluation

The arguments in a function call are evaluated in arbitrary order. For example, the behavior of the second statement in what follows is undefined:

n = 2;
printf("%d %d", ++n, n*n)

It may print "3 4" (if n*n is evaluated before ++n), or "3 9" in the other case.

Similarly, the order of evaluation of the operands of mathematically commutable operators (e.g. addition, multiplication) is arbitrary. The same kind of undefined behavior can occur if operands have side effects (such as incrementing a variable that is used in the other operand).

Switch and break

In a switch/case statement, use break at the end of each clause to make sure that no other clause is executed. Otherwise, several clauses may be executed.