1. How to view macro development
Before getting started, let's briefly introduce how a macro we define can be expanded in the referenced code. I use Microsoft Visual C ++ 6.0, project menu-> Settings, C/C ++ tabs, and add/P to project options, as shown in 1. Rebuild all will generate a. I file with the same name as. cpp. Open the. I file and you can see how macros are expanded in the code.
Figure 1 1 Add "/P" Compilation options
For example:
# Define cons (a, B) int (A ## e ## B)
Int n = cons (2, 3); // expands to int n = int (2e3); that is, n = 2000;
2. Preprocessing Operators
In the past, I often saw some clever macro definitions, which used symbols such as #, #, and so on. But I don't understand them. # Is it useful. Today I suddenly think of it, I decided to thoroughly understand them.
Open msdn to view related instructions, as shown in the following table. Note that these preprocessing operators can only be used in the # define macro definition.
.
Preprocessor Operators |
Action |
Stringizing operator (#) |
String operator, which adds double quotation marks to the corresponding real parameters. |
Charizing operator (#@) |
Character operator, which adds single quotation marks to the corresponding real parameters. |
Token-pasting operator (##) |
The symbolic concatenation operator concatenates two symbols. |
2.1. stringizing operator (#)
String operator. function: converts the input parameter names in the macro definition into a pair of double quotation marks, that is, String. Let's test it (the example is from msdn ).
# Define Stringer (x) printf (# X "/N ")
Void main ()
{
Stringer (in quotes in the printf function call/N );
Stringer ("in quotes when printed to the screen"/N );
Stringer ("This:/" prints an escaped double quote ");
}
Use the method described above to view the macro development (in. in the I file), the above Code is expanded into the following code during pre-compilation, you can find that when using string (stringizing) operations, if the real parameter contains quotation marks, backslash characters, during macro expansion, "/" will be automatically added to the money to stringize these characters.
Void main ()
{
Printf ("in quotes in the printf function call/N" "/N ");
Printf ("/" in quotes when printed to the screen/"/N" "/N ");
Printf ("/" This: // "prints an escaped double quote/"/N ");
}
The final input is as follows:
In quotes in the printf function call
"In quotes when printed to the screen"
"This:/" prints an escaped double quote"
Note:
◆ Escape characters
◇ In some forms of input parameter names, if there are special characters, the compiler will automatically add escape characters '/' to them '/'.
◆ Space Processing
◇ Ignore the spaces before and after the input parameter name.
For example, Stringer (ABC); // The macro is printf ("ABC" "/N ");
◇ When there is a space between input parameter names, the compiler will automatically connect each sub-string and use only one space in each sub-string to connect, ignoring the extra space.
For example, Stringer (abc def); // The macro is printf ("ABC Def" "/N ");
2.2. charizing operator (#@)
Character operator. function: converts the input parameter names in the macro definition into a pair of single quotes, that is, the name of the input parameter. For example:
# Define makechar (CH) # @ ch
Char A = makechar (B); // expanded to Char A = 'B' by macro ';
Note:
In the default type conversion, if the input parameter is not character type, it will be truncated to char type.
For example:
Char A = makechar (ABCD); It is truncated to a = 'D '.
2.3. Token-pasting operator (##)
Symbol concatenation operator. function: concatenates two symbol strings into one symbol. The token-pasting operator also becomes the merging operator, that is, the merge operation. The text macro is familiar to anyone who wants to program windows. Let's look at its definition:
# Ifdef Unicode
# DEFINE _ text (quote) L # quote
# Else
# DEFINE _ text (quote) quote
# Endif
# Define text (quote) _ text (quote)
Use the actual example to see how to connect to the Unicode environment:
Text (ABC); // The macro scale is labc;
Text ("ABC"); // The macro is l "ABC ";
For example:
# Define cons (a, B) int (A ## e ## B)
Int n = cons (2, 3); // expands to int n = int (2e3); that is, n = 2000;
3. Macro embedding
Macro definition allows nesting, but note that the GEO macro parameters '#', '# @', and '#' are not expanded in the macro definition.
. To illustrate the problem, let's take a look at a simple example.
# Define max_val 100
# DEFINE _ STR (ARG) # ARG
# Define STR (ARG) _ STR (ARG)
Int main ()
{
Puts (_ STR (max_val ));
Puts (STR (max_val ));
Return 0;
}
First, let's take a look at the macro expansion in the. I file:
Int main ()
{
Puts ("max_val ");
Puts ("100 ");
Return 0;
}
Output:
Max_val
100
From the output result, we can see the difference. The reason is that: in macro definition, the remote macro parameters '#', '# @', and '#' are not expanded.
. However, the method to solve this problem is very simple. Add an intermediate conversion macro to expand macro parameters. Such definitions are everywhere in header files of many large projects, MFC code, and Microsoft code. Just like the definition of the text macro embedded above.
4. Summary
Macro design is very clever. As long as you can think of it, you can greatly strengthen your code. In the process of learning and working, you must be good at summarizing, summarizing, and collecting clever macro applications. It is for reference only. If there are any mistakes, please kindly advise. If what I write is useful to you, don't forget to stick to it.