The preprocessor is a translator that converts a program written in one high-level
language into an equivalent program written in another high level language, i.e. a preprocessor converts a program written in C into an equivalent program in simplified C language.
The preprocessor is controlled by directives known as preprocessor directives. Important points for writing preprocessor directives: 1. The pound (#) symbol should be either the first character or the first non-white-space character in a line. 2. A new-line character ends a preprocessor directive. 3. The white-space characters that can appear in a preprocessor directive single-space or horizontal tab.
Some of the preprocessor directives in C language are: 1. Macro replacement directive (#define, #undef) 2. Source file inclusion directive (#include) 3. Conditional Compilation Directives (#if, #else, #elif, #endif, #ifdef, #ifndef)
Macro Replacement Directive: Using the macro replacement feature, a token can be replaced by a user-defined sequence of characters.
Types of Macro: 1. Object-like macros 2. Function-like macros
Object-like macros: The define directive in this case causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens present in the definition of the macro. Example: #include<stdio.h> #define PI 3.1416 void main() { int radius = 5; printf("Area of the circle is %f", PI*radius*radius); }
Function-like macros: A macro with arguments is called a function like macro. It is similar to a function call and its syntax is as follows: #define macro-name(parameter-list) replacement-list
Important points about function-like macros: 1. There should be no white-space character between the macro name and the left parenthesis of the parameter list in the definition of a function like macro. 2. In the definition of a macro, the replacement list must always be parenthesized to protect any lower precedence operator in it from a higher precedence operator. 3. There should be no semi-colon in a macro definition. Example: #include<stdio.h> #define SQR(x) ((x)*(x)) void main() { int val = 5; printf("SQUARE OF %d is %d", val, SQR(val)); }
Stringification/Token Replacement: The # and the parameter are replaced by a string literal. So this operation is known as stringification. Example: #include<stdio.h> #define STR(x) #x void main() { printf(STR(String Replacement)); // It will print String Replacement }
Concatenation: If a ## preprocessing token appears between two parameters, the parameters will be pasted to form one token. The ## operator is known as the concatenation operator. Example: #include<stdio.h> #define JOIN(x,y) x##y void main() { int JOIN(var,1) = 10; printf("The value of var1 is %d", var1); }
Source file inclusion directive: The source file inclusion directive include tells the preprocessor to replace the directive with the concatenation file specified. The different ways of including source file are: 1. #include<stdio.h> Searches all the pre-specified list of directories. 2. #includestdio.h Searches the present directory first. If the file is not found then it searches all the pre-specified list of directories.
Example: #include<stdio.h> #includeconio.h void main() { char ch; printf("Enter some character: "); ch = getch(); printf("The character entered is %c", ch); }
Conditional Compilation Directives: Conditional Compilation directives are compiled only if a certain condition comes out be true. The various conditional compilation directives are: #if, #else, #elif, #ifdef, #ifndef, #endif General Syntax: #if const-exp statements #elif const-exp statements #else statements #endif
Only if the constant expression is true will the compiler evaluate a given set of statements. If none of the expressions are true, the compiler will evaluate the #else part if present.
Example: #include<stdio.h> #define var 10 void main() { #if (var==5) printf("Executed the if part"); #elif (var==10) printf("Executed the elif part"); //This part will get executed #else printf("Executed the else part"); #endif }
#ifdef and #ifndef: #ifdef will execute a set of statements if a macro with the name specified by the identifier has been defined. The #ifndef does the opposite, i.e. it executes a set of statements if a macro by the name specified by the identifier has NOT been defined. General Syntax: #ifdef idenfifier//Can also be replaced by #ifndef, the syntax will remain the same statements #else statements #endif
Example: //for #ifdef #include<stdio.h> void main() { #ifdef MAX #define MIN 90 #else #define MIN 100 #endif printf("MIN number : %d", MIN); // Value of MIN will be 100 }
//for #ifndef #include<stdio.h> void main() { #ifndef MAX #define MIN 90 #else #define MIN 100 #endif printf("MIN number : %d", MIN); // Value of MIN will be 90 }