The C Preprocessor is not part of the compiler but it extends the power of C programming language. All preprocessor directives begin with a # symbol.
The preprocessor step comes before compilation of source code and it instruct the compiler to do required pre-processing before actual compilation.
- Preprocessor directives are processed before compilation of source code.
- All preprocessor directives begin with a # symbol.
- Preprocessor directives do not ends with semicolon.
- Macro Substitution
- Conditional Compilation
- File Inclusive
Directive | Description |
---|---|
#include | It includes header file inside a C Program. |
#define | It is substitution macro. It substitute a constant with an expression. |
#if | It include a block of code depending upon the result of conditional expression. |
#else | It is complement of #if |
#elif | #else and #if in one statement. It is similar to else if ladder. |
#endif | It flags the end of conditional directives like #if, #elif etc. |
#undef | Undefines a preprocessor macro. |
#ifdef | Returns true If constant is defined earlier using #define. |
#ifndef | Returns true If constant is not defined earlier using #define. |
#pragma | Issues special commands to the compiler. |
#error | Prints error message on stderr. |
#include Preprocessor Directives
#inclide Preprocessor Directives is used to include header file inside C Program. It checks for header file in current directory, If path is not mentioned. To include user defined header file we use double quote instead of using triangular bracket.
For Example#include// Standard Header File #include "myHeaderFile.h" // User Defined Header File
First line tells the preprocessor to replace this line with content of string.h header file.
Second line tells the preprocessor to get myHeaderFile.h from the current directory and add the content of myHeaderFile.h file.
#define Preprocessor Directives
It is simple substitution macro. It substitute all occurrences of the constant and replace them with a expression.
- #define : It is preprocessor directive used for text substitution.
- identifier : It is an identifier used in program which will be replaced by value.
- value : This is the value to be substituted for identifier.
#define PIE 3.141 #define ZERO 0
C Program to show use of #define Preprocessor Directives
#include <stdio.h> #define PI 3.141 int main(){ int radius; float circumference; printf("Enter the radius of circle\n"); scanf("%d", &radius); circumference = 2*PI*radius; printf("Circumference of Circle = %f", circumference); return 0; }
Output
Enter the radius of circle 5 Circumference of Circle = 31.410000
#define macro substitution with arguments
#define Preprocessing directive can be used to write macro definitions with parameters.
- Whenever a macro identifier is encountered, the arguments are substituted by the actual arguments from the c program.
- No data type defined for macro arguments. You can pass any numeric like int, float etc.
- Argument macro is not case sensitive.
#define circumference(r) (2*3.141*(r))
C Program to show Macro Substitution with Arguments
#include <stdio.h> #define circumference(r) (2*3.141*(r)) int main(){ int radius; float c; printf("Enter the radius of circle\n"); scanf("%d", &radius); c = circumference(radius); printf("Circumference of Circle = %f", c); return 0; }
Output
Enter the radius of circle 5 Circumference of Circle = 31.410000#if, #else and #endif Conditional Compilation Preprocessor Directives
The Conditional Compilation Directives allow us to include a block of code based on the result of conditional expression.
statements;
#else
statements;
#endif
Condition_Expression must be only constant expression.
C program to show Conditional Compilation using #if, #else and #endif
#include <stdio.h> #define COUNT 5 void main(){ #if(COUNT > 1) printf("Enter %d numbers\n", COUNT); #else printf("Enter a number\n"); #endif return 0; }
Output
Enter 5 numbers
Predefined Macros in C Language
C Programming language defines a number of macros. Below is the list of some commonly used macros.
Macro | Description |
---|---|
NULL | Value of a null pointer constant. |
EXIT_SUCCESS | Value for the exit function to return in case of successful completion of program. |
EXIT_FAILURE | Value for the exit function to return in case of program termination due to failure. |
RAND_MAX | Maximum value returned by the rand function. |
__FILE__ | Contains the current filename as a string. |
__LINE__ | Contains the current line number as a integer constant. |
__DATE__ | Contains current date in "MMM DD YYYY" format. |
__TIME__ | Contains current time in "HH:MM:SS" format. |
C Program to print value of Predefined Macros
#include <stdio.h> #include <stdlib.h> int main(){ printf("NULL : %d\n", NULL ); printf("EXIT_SUCCESS : %d\n", EXIT_SUCCESS ); printf("EXIT_FAILURE : %d\n", EXIT_FAILURE ); printf("RAND_MAX : %d\n", RAND_MAX ); printf("File Name : %s\n", __FILE__ ); printf("DATE : %s\n", __DATE__ ); printf("Line : %d\n", __LINE__ ); return 0; }
Output
NULL : 0 EXIT_SUCCESS : 0 EXIT_FAILURE : 1 RAND_MAX : 32767 File Name : PreProcessorMacro.c DATE : Jan 27 2015 Line : 12
Best Practices for Using Preprocessor Directives
- Limit Use of Macros : Excessive utilization of macros can complicate the readability and troubleshooting of code. Employ them prudently in situations when they truly enhance the comprehensibility of the code.
- Avoid Complex Macros : Macros that involve several statements or side effects might be prone to errors and difficult to troubleshoot. It is advisable to utilize inline functions instead when dealing with more intricate jobs.
- Use Header Guards : It is vital to incorporate header guards in your header files to avert the occurrence of duplicate inclusions. This guarantees that your header files are included just once.
- Be Mindful of Code Portability : Certain preprocessor directives and macros may lack compatibility across different compilers or systems. Take into consideration the potential problems related to mobility while utilizing them.
- Document Your Code : Thoroughly document the intended function and application of macros and preprocessor directives. Documenting your code enhances comprehensibility and facilitates efficient maintenance for fellow developers.
Conclusion
In conclusion, preprocessor directives in C provide a powerful mechanism for code customization, organization, and optimization. Understanding the basics, common directives, and advanced features such as macros, file inclusion, and predefined macros empowers developers to write more flexible and maintainable code.