Practical C Programming Chapter 10
C need a facility for handling named constants, marcos, and include files.
==> C pre-processor
1. #define statement
All pre-processor commands begin with a hash mark (#) in column one.
the pre-processor knows nothing about C
A pre-processor directive terminates at the end-of-line
#define name substitute-text
name can be any valid C identifier and substitute-text can be anything
Hint: C allows you to run your program through the pre-processor and view the output. In UNIX, the command:
%cc -E prog.c
2. #define vs. const
the #define directive can only define simple constants
the const statement can define almost any type of C constant, including things like structure classes
the #define directive is, however, essential for things like conditional compilation and other specialized uses
3. conditional compilation
In theory, C code is portable; in actual practice, different operating systems have little quirks that must be accounted for.
An other portability problem is caused by the fact that the standard leaves some of the features of the language up to the implementers.
The pre-processor, through the use of conditional compilation, allows the programmer great flexibility in changing the code generated.
#ifdef DEBUG
printf("In compute-hash, value %d hash %d\n, value, hash);
#endif /* DEBUG */
NOTE: it's not necessary to put the /* DEBUG */ after the #endif; however, the entry is very useful as a comment
#define DEBUG /* Turn debugging on */
#undef DEBUG /* Turn debugging off */
#ifdef DEBUG
printf("Test version. Debugging is on\n");
#else DEBUG
printf("Production verison\n");
#endif /* DEBUG */
The compiler switch -Dsymbol allows symbols to be defined on the command line
The general form of the option is -Dsymbol or -Dsymbol=value
#undef DEBUG
will result in DEBUG being undefined whether or not you use -DDEBUG
Most C compilers automatically define some system-dependent symbols
4. include Files
The #include directive allows the program to use source code from another file
Files that are included in other programs are called header files. (Most #include directives come at the head of the program.)
The angle brackets (<>) indicate that the file is a standard file. On UNIX, these files are located in /usr/include
Standard include files define data structures and macros used by library routines.
Local include files may be specified by using double quotes ("") around the file name
The directive #ifndef symbol is true if the symbol is not defined. The directive is the reverse of #ifdef
5. Parameterized Marcos
#define SQR(x) ((x) * (x)) /* Square a number */
Note: No spaces must exist between the marco (SQR) and the parenthesis
6. Advanced Features
#if directive for conditional compilation
#pragma directive for inserting compiler-dependent commands into a file
7. Summary
The C preprocessor is very useful part of the C language. It has a completely different look and feel, though, and it must be treated apart from the main C complier
Problems in marco definitions often do not show up where the marco is defined, but result in errors much future down in the program. By following a few simple rules, you can decrease the chances of having problems:
Put parentheses () around everything. In particular, they should enclose #define constants and marco parameters
When defining a marco with more than one statement, enclose the code in curly braces ({})
The preprocessor is not C. Don't use = and ;. Finally, if you got this far, be glad that the worst is over.