I don’t touch upon preprocessor directives in deep detail in the book. The
#define directives are mentioned, but they’re only two of many preprocessor directives available in the C Language.
What’s a Preprocessor Directive?
A preprocessor directive is given to the compiler before the C code is compiled. The compiler works through the preprocessor directives first, making substitutions, inclusions, and even decisions before the source code is translated into object code.
Here are the various preprocessor directives:
The place you’ll see most of these directives used are in the various header files. In fact, I recommend you peruse the header files to explore the possibilities of how these directives are put to work. That’s because most of your code probably won’t use these guys.
#include directive brings in code from another file, typically a header file. The directive is followed by a filename. When the filename is enclosed in angle brackets:
the compiler looks for that file in the
/usr/include (or similar) directory. Otherwise, when the filename is enclosed in double quotes:
the file is looked for in the current directory.
In the book, I describe how
#define is used to create constants and make substitutions. It’s official definition is “macro substitution.” It creates shortcuts. When the compiler encounters this preprocessor directive, it works through the code and makes substations as necessary. For example:
#define ROWS 5
Above, the compiler would search for any instance of
ROWS and replace it with the value 5.
You can include variables in the macro expansions, which is done for the definition of
putchar() in the stdio.h header file
#define putchar(x) putc(x,stdout)
Be careful when making such expansions, however, as sometimes the compiler may expand the macro twice.
#undef preprocessor directive un-defines something previously created by the
#define directive. This is an example of a directive you’ll often find in a header file, but not necessarily in your code.
#if directive evaluates a condition. When the condition is true, the statements that follow
#if are executed, up until the
#endif directive. I’ve actually used this directive in my code a long, long time ago. I created a constant to determine whether the computer was capable of displaying color text or not:
#define COLOR 1
#if directives examined that constant to determine whether color information was compiled into the code or not:
/* color code goes here */
Of course, I had to manually set the
COLOR value. That was okay; it allowed me to use one source code file to generate two different versions of the program, one for color systems and one for monochrome.
Remember that the
#endif directive is required to terminate a block of
These two directives correspond to
else if and
else items in an C language if decision tree. They allow you to construct complex decisions using preprocessor directives.
These directives form specific if conditions based on whether something is defined or not yet defined. The value of what’s defined doesn’t matter, just whether the item has been defined or not. For example:
#define BLORFUS 64
#endif /* BLORFUS */
The above example creates the constant
BLORFUS if it hasn’t yet been defined. You’ll see lots of those examples inside the header files, if you choose to peruse them. Read my February 21 2015 Lesson for a specific example of how to use these directives.