What? You still don't know what the C++ preprocessor is? It is enough to read this article~

Table of contents

C++ preprocessor

#define preprocessing

parameter macro

conditional compilation

# and ## operators

Predefined macros in C++

final knowledge point

write at the end


C++ preprocessor

Preprocessors are directives that tell the compiler what preprocessing to do before actual compilation.

All preprocessor directives begin with a pound sign (#), and only space characters can appear before a preprocessor directive. Preprocessing directives are not C++ statements, so they do not end with a semicolon (;).

We have seen that there are #include  directives in all the previous examples  . This macro is used to include header files into source files.

C++ also supports many preprocessing directives, such as #include, #define, #if, #else, #line, etc. Let us take a look at these important directives.

#define preprocessing

The #define preprocessing directive is used to create symbolic constants. This symbolic constant is usually called a macro , and the general form of the instruction is

#define macro-name replacement-text 

When this line of code appears in a file, all subsequent macros appearing in the file will be replaced with replacement-text before the program is compiled. For example:

#include <iostream>
using namespace std;
 
#define PI 3.14159
 
int main ()
{
 
    cout << "Value of PI :" << PI << endl; 
 
    return 0;
}

Now, let's test this code and see the result of preprocessing. Assuming that the source code file already exists, then use the -E option to compile and redirect the result to test.p. Now, if you look at the test.p file, you'll see that it already contains a lot of information, and that the values ​​at the bottom of the file have been changed to the following:

...
int main ()
{
 
    cout << "Value of PI :" << 3.14159 << endl; 

    return 0;
}

parameter macro

You can use #define to define a macro with parameters like this:

#include <iostream>
using namespace std;
 
#define MIN(a,b) (a<b ? a : b)
 
int main ()
{
   int i, j;
   i = 100;
   j = 30;
   cout <<"较小的值为:" << MIN(i, j) << endl;
 
    return 0;
}

When the above code is compiled and executed, it produces the following result:

Smaller value: 30

conditional compilation

There are several directives that can be used to selectively compile portions of program source code. This process is called conditional compilation.

The structure of the conditional preprocessor is very similar to the if selection structure. Consider the following preprocessor code:

#ifdef NULL
   #define NULL 0
#endif

You can compile only when debugging, the debug switch can be implemented with a macro like this:

#ifdef DEBUG
   cerr <<"Variable x = " << x << endl;
#endif

If the symbolic constant DEBUG has been defined before the directive #ifdef DEBUG, the cerr statement in the program will   be compiled. You can comment out part of a program with a #if 0 statement, like so:

#if 0 
   code that does not compile 
#endif

Let's try the following example:

#include <iostream>
using namespace std;
#define DEBUG
 
#define MIN(a,b) (((a)<(b)) ? a : b)
 
int main ()
{
   int i, j;
   i = 100;
   j = 30;
#ifdef DEBUG
   cerr <<"Trace: Inside main function" << endl;
#endif
 
#if 0
   cout << MKSTR(HELLO C++) << endl;
#endif
 
   cout <<"The minimum is " << MIN(i, j) << endl;
 
#ifdef DEBUG
   cerr <<"Trace: Coming out of main function" << endl;
#endif
    return 0;
}

When the above code is compiled and executed, it produces the following result:

Trace: Inside main function
The minimum is 30
Trace: Coming out of main function

# and ## operators

The # and ## preprocessing operators are available in both C++ and ANSI/ISO C. The # operator converts the replacement-text token into a quoted string.

Please see the following macro definition:

#include <iostream>
using namespace std;
 
#define MKSTR( x ) #x
 
int main ()
{
    cout << MKSTR(HELLO C++) << endl;
 
    return 0;
}

When the above code is compiled and executed, it produces the following result:

HELLO C++

Let's see how it works. Not surprisingly, the C++ preprocessor puts the following line:

cout << MKSTR(HELLO C++) << endl;

converted to:

cout << "HELLO C++" << endl;

The ## operator is used to concatenate two tokens. Here is an example:

#define CONCAT( x, y )  x ## y

When CONCAT appears in a program, its arguments are concatenated and used instead of the macro. For example, CONCAT(HELLO, C++) in the program will be replaced with "HELLO C++", as shown in the example below.

#include <iostream>
using namespace std;
 
#define concat(a, b) a ## b
int main()
{
   int xy = 100;
   
   cout << concat(x, y);
   return 0;
}

When the above code is compiled and executed, it produces the following result:

100

Let's see how it works. Not surprisingly, the C++ preprocessor puts the following line:

cout << concat(x, y);

converted to:

cout << xy;

Predefined macros in C++

C++ provides some predefined macros as shown in the following table:

macro describe
__LINE__ This includes the current line number when the program compiles.
__FILE__ This will include the current filename when the program is compiled.
__DATE__ This will contain a string of the form month/day/year representing the date the source file was converted to object code.
__TIME__ This will contain a string of the form hour:minute:second which represents the time at which the program was compiled.

Let's see examples of these macros above:

#include <iostream>
using namespace std;
 
int main ()
{
    cout << "Value of __LINE__ : " << __LINE__ << endl;
    cout << "Value of __FILE__ : " << __FILE__ << endl;
    cout << "Value of __DATE__ : " << __DATE__ << endl;
    cout << "Value of __TIME__ : " << __TIME__ << endl;
 
    return 0;
}

 

When the above code is compiled and executed, it produces the following result:

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48

final knowledge point

#  and  ##  operators

# The meaning of stringification, # appearing in the macro definition is to convert the following parameters into a string.

When used as a stringification operation, the main function of # is to convert macro parameters into string constants without expansion.

  •  The spaces on the left and right sides of the macro definition parameter will be ignored, and multiple spaces between each Token of the parameter will be converted into one space.
  •  When macro definition parameters contain characters that require special meaning such as " or \, they will be automatically preceded by the escape character \.

## Connection symbols, connect parameters together.

Connect multiple Tokens into one Token. Main points:

  •  It cannot be the first or last token in a macro definition.
  •  Leading and trailing spaces are optional.
  1. Data types and variable definitions include definitions of data types such as integer, floating-point, character, and pointer, as well as declaration and initialization of variables.

  2. Operators and expressions include arithmetic operators, relational operators, logical operators, etc., as well as evaluation rules for expressions.

  3. Control statements include conditional statements, loop statements, jump statements, etc.

  4. Function and parameter transfer include function definition, function return value, and parameter transfer method (value transfer, pointer transfer, etc.).

  5. Arrays and pointers include array definitions, access to array elements, multidimensional arrays, pointer definitions, pointer operations, etc.

  6. String processing includes the definition of strings, common operations on strings (comparison, copy, connection, split, etc.).

  7. File operations include common operations such as file opening, reading, writing, and closing.

  8. Memory management includes the use of dynamic memory allocation functions malloc and free.

write at the end

Recently, the traffic is getting less and less, please pay attention to it, collect it, thank you

Guess you like

Origin blog.csdn.net/m0_64122244/article/details/130909015