Usage of "#" and "#" in macro
I. general usage
We use # to convert the macro parameter into a string, and # to combine the two macro parameters.
Usage:
# Include <cstdio>
# Include <climits>
Using namespace std;
# Define STR (s) # s
# Define CONS (a, B) int (a ## e ## B) int main ()
{
Printf (STR (vck); // output string "vck"
Printf ("% d/n", CONS (2000); // 2e3 output:
Return 0;
} 2. When the macro parameter is another macro
It should be noted that all macro parameters that use '#' or '#' in macro definition will not be expanded. 1, not '#' and '#'.
# Define TOW (2)
# Define MUL (a, B) (a * B) printf ("% d * % d = % d/n", TOW, TOW, MUL (TOW, TOW ));
The Macros in this line will be expanded:
Printf ("% d * % d = % d/n", (2), (2), (2) * (2 )));
The TOW parameter in MUL is expanded to (2). 2. When there is '#' or '#',
# Define A (2)
# Define STR (s) # s
# Define CONS (a, B) int (a ## e ## B) printf ("int max: % s/n", STR (INT_MAX )); // INT_MAX # I nclude <climits>
This row is expanded:
Printf ("int max: % s/n", "INT_MAX"); printf ("% s/n", CONS (A, A); // compile error
This line is:
Printf ("% s/n", int (AeA); INT_MAX and A will not be expanded. However, the solution to this problem is simple. add A layer of intermediate conversion macro.
The purpose of adding this macro layer is to expand all macro parameters in this layer, so that the macro (_ STR) in the conversion macro can get the correct macro parameters. # define A (2)
# Define _ STR (s) # s
# Define STR (s) _ STR (s) // convert macro
# Define _ CONS (a, B) int (a ## e ## B)
# Define CONS (a, B) _ CONS (a, B) // convert the macro printf ("int max: % s/n", STR (INT_MAX )); // INT_MAX, the maximum value of int type, is a variable # I nclude <climits>
Output: int max: 0x7fffffff
STR (INT_MAX) --> _ STR (0x7fffffff) and then convert it to A string; printf ("% d/n", CONS (A, ));
Output: 200
CONS (A, A) --> _ CONS (2), (2) --> int (2) e (2 )) iii. Special Application Cases of '#' and '#'
1. Merge anonymous variable names
# Define ___ ANONYMOUS1 (type, var, line) type var # line
# Define _ ANONYMOUS0 (type, line) ___ ANONYMOUS1 (type, _ anonymous, line)
# Define ANONYMOUS (type) _ ANONYMOUS0 (type, _ LINE __)
For example, ANONYMOUS (static int); that is, static int _ anonymous70; 70 indicates the row number;
First layer: ANONYMOUS (static int); --> _ ANONYMOUS0 (static int, _ LINE __);
Layer 2: --> ___ ANONYMOUS1 (static int, _ anonymous, 70 );
Layer 3: --> static int _ anonymous70;
That is, you can only unlock the macros of the current layer at a time, so _ LINE _ can be unlocked on the second layer. 2. Fill the structure.
# Define FILL (a) {a, # a} enum IDD {OPEN, CLOSE };
Typedef struct MSG {
IDD id;
Const char * msg;
} MSG; MSG _ msg [] = {FILL (OPEN), FILL (CLOSE )};
Equivalent:
MSG _ msg [] = {OPEN, "OPEN "},
{CLOSE, "CLOSE"}; 3. Record File Name
# Define _ GET_FILE_NAME (f) # f
# Define GET_FILE_NAME (f) _ GET_FILE_NAME (f)
Static char FILE_NAME [] = GET_FILE_NAME (_ FILE _); 4. Obtain the buffer size of the string corresponding to the value type.
# Define _ TYPE_BUF_SIZE (type) sizeof # type
# Define TYPE_BUF_SIZE (type) _ TYPE_BUF_SIZE (type)
Char buf [TYPE_BUF_SIZE (INT_MAX)];
--> Char buf [_ TYPE_BUF_SIZE (0x7fffffff)];
--> Char buf [sizeof "0x7fffffff"];
This is equivalent:
Char buf [11]; reproduced from: http://blog.csdn.net/blackbillow/article/details/3850587