C++ precompilation processing

. Definition
Pre-compilation is also called pre-processing, it is to do some code text replacement work. Processing the instructions at the beginning of #, such as copying the file code contained in #include, replacing #define macro definitions, conditional compilation, etc., is the stage of preparatory work for compilation, mainly processing the precompiled instructions starting with #, the precompilation instructions indicate The operations performed by the compiler before the formal compilation of the program can be placed anywhere in the program and stored in a temporary file in the memory.
Preprocessing instructions are lines of code beginning with the # sign. The # sign must be the first character on the line except for any blank characters. After the # is the command keyword, any number of blank characters are allowed between the keyword and the # sign. The entire line of statements constitutes a preprocessing instruction, which will do some conversion to the source code before the compiler compiles it.
The following are some preprocessing instructions:

        指令             用途
         #           空指令,无任何效果
         #include    包含一个源代码文件
         #define     定义宏
         #undef      取消已定义的宏
         #if         如果给定条件为真,则编译下面代码
         #ifdef      如果宏已经定义,则编译下面代码
         #ifndef     如果宏没有定义,则编译下面代码,通常用于避免重复包含头文件
         #elif       如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
         #endif      结束一个#if……#else条件编译块
         #error      停止编译并显示错误信息

There are three main types of preprocessing commands provided by C++: file include commands (header files), macro definition commands, and conditional compilation commands.

1. File include command (header file) The
so-called "file include" means to merge the content of another source program into the source program. The C++ program provides the #include command to implement the operation of file inclusion. It has the following two formats:
●#include <file name>
●#include "File name" The
file name usually has an extension of ".h", so it is called As the "header file".
The first form uses "<>" to enclose the file name. These header files generally exist in the include subdirectory of the C++ system directory. After the C++ preprocessor encounters this command, it searches for the given file in the include subdirectory and embeds it in the current file. This form is also the standard form.
The second form uses double quotes to enclose the file name. After the preprocessor encounters the include command in this format, it first searches in the directory where the current file is located. If it cannot find it, it searches in the standard way. This method is suitable for user-written header files.
#include files can be nested, that is, one included file can include another file.

2. Macro definition command
C++ macro definition defines an identifier as a string, and the identifier in the source program is replaced by the specified string. Therefore, the semicolon is usually not added after the preprocessing command. This is not to say that semicolons cannot appear after all preprocessing commands. Since the macro definition simply replaces a string with the macro name, if a semicolon is added after the macro definition command, it will be replaced together with the semicolon. The
#define preprocessing directive is used to define the macro. The simplest format of this instruction is: First, deity an identifier, and then give the code represented by this identifier. In the source code that follows, these codes are used to replace the identifier. This kind of macro extracts some global values ​​to be used in the program and assigns them to some mnemonic identifiers.

#define      MIN(A, B)     ((A) <= (B)? (A):(B))

Note: The macro instruction is only for general replacement, and the replacement does not distinguish between types, such as:

#define ADD(x, y) x + y
#define MUL(x, y) x * y

int main ( int argc, char *argv[] )
{
    
    
   int a= 2, b = 3;
   printf ("\nProgram %d\n\n", MUL(ADD(a, b), 5) );  //被转换成2 + 3 * 5 注意 没有括号 故结果为17
   return 0;
} 

Use #define to define the advantages and disadvantages of the function:
Advantages: It can complete the function of function call, and can reduce system overhead and improve operating efficiency. Because it is macro expansion in the preprocessing stage, no conversion is required during execution, that is, it is executed locally.
Disadvantages: the target code space occupied is relatively large,
at the expense of space in exchange for time

3. Conditional compilation instructions
Conditional compilation instructions will determine which codes are compiled and which ones are not. The compilation conditions can be determined based on the value of the expression or whether a particular macro is defined.
1) #if instruction
#if instruction detects the constant expression following the creation of another keyword. If the expression is true, the following code will be compiled until #else, #elif or #endif appears; otherwise, it will not be compiled.
2) #endif instruction
#endif is used to terminate the #if preprocessing instruction.

#define DEBUG 0    //定义了一个宏
main()
   {
    
    
        #if DEBUG    //判断DEBUG的值,虽然已经定义,但是值是0
             printf("Debugging\n");
        #endif   //DEBUG 为0,endif成立
             printf("Running\n");
    }   
//由于程序定义DEBUG宏代表0,所以#if条件为假,不编译后面的代码直到#endif,所以程序直接输出Running。如果去掉#define语句,效果是一样的。

3) #ifdef and #ifndef

 #define DEBUG  //定义了一个宏
 main()
     {
    
    
          #ifdef DEBUG   //判断DEBUG是否定义,#ifdef是定义了
              printf("yes\n");
          #endif
          #ifndef DEBUG   //  判断DEBUG是否没定义
               printf("no\n");
          #endif
        }
       // #if defined等价于#ifdef; #if !defined等价于#ifndef

4) #else instruction
#else instruction is used after a certain #if instruction, when the condition of the previous #if instruction is not true, compile the code behind #else. #endif instruction will middle point to the above conditional block

#define DEBUG
main()
    {
    
    
       #ifdef DEBUG //是否定义DEBUG
            printf("Debugging\n");
       #else
             printf("Not debugging\n");
       #endif
             printf("Running\n");
       }
    //#else,#elif和endif是一样的

5) #elif instruction
#elif preprocessing instruction combines the functions of #else and #if instructions.

  #define TWO
        main()
        {
    
    
            #ifdef ONE
                printf("1\n");
            #elif defined TWO
                printf("2\n");
            #else
                printf("3\n");
            #endif
        }
       // 程序很好理解,最后输出结果是2。

6) Some other standard directives
#error directive will cause the compiler to display an error message and then stop compiling.
The #line directive can change the file number and line number used by the compiler to indicate warning and error messages.
The #pragma directive has no formal definition. The compiler can customize its purpose. Typical usage is to prohibit or allow certain annoying warning messages

Guess you like

Origin blog.csdn.net/qq_43530773/article/details/113826492