C is unusual in that it has a pre-processor. This comes from its
Unix origins. As its name might suggest, the preprocessor is a phase
which occurs prior to compilation of a program. The preprocessor has two
main uses: it allows external files, such as header files, to be
included and it allows macros
to be defined. This useful feature
traditionally allowed constant values to be defined in Kernighan and
Ritchie C, which had no constants in the language.
Pre-processor commands are distinguished by the hash (number) symbol
#
. One example of this has already been encountered for the
standard header file stdio.h
.
#include <stdio.h>
is a command which tells the preprocessor
to treat the file stdio.h
as if it were the actually part of the
program text, in other words to include it as part of the program to
be compiled.
Macros are words which can be defined to stand in place of
something complicated: they are a way of reducing the amount of typing
in a program and a way of making long ungainly pieces of code into
short words. For example, the simplest use of macros is to give
constant values meaningful names: e.g.
#define TELEPHNUM 720663
This allows us to use the word TELEPHNUM
in the program
to mean the number 720663. In this particular case, the word is
clearly not any shorter than the number it will replace, but it is
more meaningful and would make a program read more naturally than if
the raw number were used. For instance, a program which deals with
several different fixed numbers like a telephone number, a postcode
and a street number could write:
printf("%d %d %d",TELEPHNUM,postcode,streetnum);
instead of
printf("%d %d %d",720663,345,14);
Using the macros instead makes the actions much clearer and allows the
programmer to forget about what the numbers actually are. It also
means that a program is easy to alter because to change a telephone
number, or whatever, it is only necessary to change the definition,
not to retype the number in every single instance.
The important feature of macros is that they are not merely numerical
constants which are referenced at compile time, but are strings which
are physically replaced before compilation by the preprocessor! This
means that almost anything can be defined:
#define SUM 1 + 2 + 3 + 4
would allow SUM
to be used instead of 1+2+3+4
. Or
#define STRING "Mary had a little lamb..."
would allow a commonly used string to be called by the identifier
"string" instead of typing it out afresh each time. The idea of a
define statement then is:
#define macroname definition on rest of line
Macros cannot define more than a single line to be substituted into a
program but they can be used anywhere, except inside
strings. (Anything enclosed in string quotes is assumed to be complete
and untouchable by the compiler.)
Some macros are defined already in the file stdio.h
such as:
EOF
- The end of file character (= -1 for instance)
NULL
- The null character (zero) = 0