English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In this tutorial, we will introduce the C preprocessor and learn how to use #include, #define, and conditional compilation with the help of examples. The C preprocessor is a macro preprocessor (allowing you to define macros) that can be transformed before compiling the program. These transformations can include header files, macro expansion, etc. All preprocessing instructions start with the # symbol.
C PreprocessorIt is not part of the compiler, but it is a separate step in the compilation process. In short, the C preprocessor is just a text replacement tool that indicates to the compiler what preprocessing is needed before actual compilation. We will abbreviate the C preprocessor (C Preprocessor) as CPP.
All preprocessor commands start with the hash symbol (#). It must be the first non-empty character, and for readability, preprocessor instructions should start from the first column. The following lists all important preprocessor instructions:
Command | Description |
---|---|
#define | Define a macro |
#include | Include a source code file |
#undef | Cancel the defined macro |
#ifdef | Return true if the macro is already defined |
#ifndef | Return true if the macro is not defined |
#if | If the given condition is true, compile the following code |
#else | Alternative to #if |
#elif | If the condition given by the preceding #if is not true, and the current condition is true, compile the following code |
#endif | End a #if...#else conditional compilation block |
#error | Output an error message when encountering standard error |
#pragma | Use standardized methods to issue special commands to the compiler |
Analyze the following examples to understand different instructions.
#define MAX_ARRAY_LENGTH 20
This instruction tells CPP to replace all MAX_ARRAY_LENGTH with 20. Use #define Define constants to enhance readability.
#include <stdio.h> #include "myheader.h"
These instructions tell CPP to get fromSystem libraryObtain stdio.h and add text to the current source file. The next line tells CPP to get from the local directory. myheader.hand add content to the current source file.
#undef FILE_SIZE #define FILE_SIZE 42
This instruction tells CPP to cancel the already defined FILE_SIZE and define it as 42.
#ifndef MESSAGE #define MESSAGE "You wish!" #endif
This instruction tells CPP to define MESSAGE only when MESSAGE is not defined.
#ifdef DEBUG /* Your debugging statements here */ #endif
This instruction tells CPP to execute the processing statements if DEBUG is defined. When compiling, if you pass -DDEBUG Switches, this instruction is very useful. It defines DEBUG, which you can turn on or off at any time during compilation.
ANSI C defines many macros. You can use these macros in programming, but you cannot directly modify these predefined macros.
Macro | Description |
---|---|
__DATE__ | The current date, a character literal represented in the format "MMM DD YYYY". |
__TIME__ | The current time, a character literal represented in the format "HH:MM:SS". |
__FILE__ | This will include the current filename, a string literal. |
__LINE__ | This will include the current line number, a decimal constant. |
__STDC__ | When the compiler compiles with the ANSI standard, it is defined as 1. |
Let's try the following example:
#include <stdio.h> main() { printf("File :%s\n", __FILE__); printf("Date :%s\n", __DATE__); printf("Time :%s\n", __TIME__); printf("Line :%d\n", __LINE__); printf("ANSI :%d\n", __STDC__); }
When the above code (in the file test.c When the program is compiled and executed, it will produce the following results:
File :test.c Date :Jun 2 2012 Time :03:36:24 Line :8 ANSI :1
The C preprocessor provides the following operators to help you create macros:
Macro continuation operator (\)
A macro is usually written on a single line. However, if the macro is too long and cannot fit on a single line, you use the macro continuation operator (\). For example:
#define message_for(a, b) \"}} printf(#a " and " #b ": We love you!\n")
String literal tokenization operator (#)
In macro definitions, when you need to convert a macro parameter to a string literal, you use the string literal operator (#). The operator used in the macro has a specific parameter or parameter list. For example:
#include <stdio.h> #define message_for(a, b) \"}} printf(#a " and " #b ": We love you!\n") int main(void) { message_for(Carole, Debra); return 0; }
When the above code is compiled and executed, it will produce the following results:
Carole and Debra: We love you!
Token concatenation operator (##)
The token concatenation operator (##) within macro definitions merges two parameters. It allows two independent tokens to be combined into one token within macro definitions. For example:
#include <stdio.h> #define tokenpaster(n) printf("token" #n " = %d", token##n) int main(void) { int token34 = 40; tokenpaster(34); return 0; }
When the above code is compiled and executed, it will produce the following results:
token34 = 40
How is this happening because this example will produce the following actual output from the compiler:
printf("token34 = %d", token34);
This example demonstrates that token##n will be concatenated to token34 in which, we useString literal tokenization operator (#)andToken concatenation operator (##).
defined() operator
Preprocessor defined Operators are used in constant expressions to determine if an identifier has been defined using #define. If the specified identifier is defined, the value is true (non-zero). If the specified identifier is not defined, the value is false (zero). The following example demonstrates the usage of the defined() operator:
#include <stdio.h> #if !defined(MESSAGE) #define MESSAGE "You wish!" #endif int main(void) { printf("This is the message: %s\n", MESSAGE); return 0; }
When the above code is compiled and executed, it will produce the following results:
This is the message: You wish!
CPP has a powerful feature that allows the use of parameterized macros to simulate functions. For example, the following code calculates the square of a number:
int square(int x) { return x * x; }
We can rewrite the above code using macros as follows:
#define square(x) ((x) * (x))
Before using a macro with parameters, it is necessary to use #define Instruction definition. The parameter list is enclosed in parentheses and must be immediately followed by the macro name. There should be no space between the macro name and the left parenthesis. For example:
#include <stdio.h> #define MAX(x,y) ((x) > (y) ? (x) : (y)) int main(void) { printf("10to2The maximum value between 0 and %d\n", MAX(10, 20)); return 0; }
When the above code is compiled and executed, it will produce the following results:
10to2The maximum value between 0 and 20