Use the preprocessor to: 1) define constants: #define DIM 25 2) include code (typically header files): #include 3) to conditionally include or exclude (comment out) code such as when debugging or to prevent the same typedef from appearing twice: #ifndef MYHEADER #define MYHEADER typedef struct xxx MYTYPE #endif 4) to define macros, but always bracket the expression and all parameters to prevent errors: #define SQR(x) ( (x) * (x) ) No space is allowed between SQR and ( in the #define, but elsewhere and in use spaces are allowed. WARNINGS: Macro expansion is not part of the syntax of the language - the preprocessor does not "understand" C, and so some strange looking things can be done with it. Avoid the temptation. Macros are not functions. Avoid using a macro on an argument that has side effects if the definition uses the argument more than once. SQR(a++) is really ((a++)*(a++)) which double increments "a". getc() is of this type - use fgetc() instead when side effect are possible. Never use the preprocessor to define macros for anything other than expressions, as errors can occur if you define statements because in statements a user may not know if nothing, ";" or "}" is the appropriate terminator for your macro. This can cause problems especially in connection with the "else" part of "if" statements. If conditionals are required, use the expression version ":?" not an if-else statement. DEBUGGING: Compile with the -E flag to see the output of the preprocessor. ARCANE: __FILE__ is file name __LINE__ is line number (there are other __ predefined macros) #name is stringification (turns name into a string) ## is concatenation (turns adjacent strings into a single token) For example, #define SOURCENAME(file) #file ## ".c" makes SOURCENAME(hello) into string "hello.c" Another example is assert(exp) which is a macro that evaluates expression "exp" and if false aborts the program with a message generated by function __assert(). The source location of the stament is printed. Here are two possible definitions for assert: #define assert(exp) ((expr) ? (void)0 : __assert(#expr,__FILE__,__LINE__)) #define assert(exp) ((void)((expr) || __assert(#expr,__FILE__,__LINE__))