C语言宏#define中#,##,#@和\的用法(Usage of #, ##, #@ and \ in C language macro # define)

一、(#)字符串化操作符作用:将宏定义中的传入参数名转换成用一对双引号括起来参数名字符串。其只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前。

如:

#define example( instr )  printf( “the input string is:\t%s\n”, #instr )#define example1( instr )  #instr当使用该宏定义时:

example( abc ); // 在编译时将会展开成:printf(“the input string is:\t%s\n”,”abc”)string str = example1( abc );  // 将会展成:string str=”abc”注意, 对空格的处理:

a. 忽略传入参数名前面和后面的空格。

如:str=example1(   abc );//将会被扩展成 str=”abc”b.当传入参数名间存在空格时,编译器将会自动连接各个子字符串,用每个子字符串之间以一个空格连接,忽略剩余空格。

如:str=exapme( abc    def);//将会被扩展成 str=”abc def”二、 (##)符号连接操作符作用:将宏定义的多个形参转换成一个实际参数名。如:

#define exampleNum( n )  num##n使用:

int num9 = 9;int num = exampleNum( 9 ); // 将会扩展成 int num = num9注意:

a. 当用##连接形参时,##前后的空格可有可无。

如:  #define exampleNum( n )       num ## n                 // 相当于 #define exampleNum( n )      num##nb. 连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义。

c. 如果##后的参数本身也是一个宏的话,##会阻止这个宏的展开。

#include <stdio.h>#include <string.h>

#define STRCPY(a, b)   strcpy(a ## _p, #b)int main(){    char var1_p[20];    char var2_p[30];    strcpy(var1_p, “aaaa”);    strcpy(var2_p, “bbbb”);    STRCPY(var1, var2);    STRCPY(var2, var1);    printf(“var1 = %s\n”, var1_p);    printf(“var2 = %s\n”, var2_p);

    //STRCPY(STRCPY(var1,var2),var2);    //这里是否会展开为: strcpy(strcpy(var1_p,”var2″)_p,”var2“)?答案是否定的:    //展开结果将是:  strcpy(STRCPY(var1,var2)_p,”var2″)    //## 阻止了参数的宏展开!如果宏定义里没有用到 # 和 ##, 宏将会完全展开    // 把注释打开的话,会报错:implicit declaration of function ‘STRCPY’    return 0;}  结果:

var1 = var2var2 = var1三、 (#@)单字符化操作符作用:将传入单字符参数名转换成字符,以一对单引用括起来。

如:

#define makechar(x)    #@xchar a = makechar( b ); //展开后变成了:a = ‘b’;四、(\) 续行操作符作用:当定义的宏不能用一行表达完整时,可以用”\”表示下一行继续此宏的定义。

注意 \ 前留空格。

当宏参数是另一个宏的时候,需要注意的是凡宏定义里有用’#’或’##’的地方宏参数是不会再展开。

1、非#和##的情况

#define TOW       (2) #define MUL(a,b) (a*b) printf(“%d*%d=%d\n”, TOW, TOW, MUL(TOW,TOW)); //这行的宏会被展开为: printf(“%d*%d=%d\n”, (2), (2), ((2)*(2))); //MUL里的参数TOW会被展开为(2). 2、当有#或##的时候

#define A           2#define STR(s)      #s #define CONS(a,b)   (int)a##e##bprintf(“int max: %s\n”,   STR(INT_MAX));     // INT_MAX #include <limits>//这行会被展开为: //printf(“int max: %s\n”, “INT_MAX”); printf(“%s\n”, CONS(A, A));                // compile error  //这一行则是: //printf(“%s\n”, int(AeA)); //INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.//加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数. #define A            2#define _STR(s)      #s #define STR(s)       _STR(s)           // 转换宏 #define _CONS(a,b)   (int)a##e##b #define CONS(a,b)    _CONS(a,b)        // 转换宏 printf(“int max: %s\n”, STR(INT_MAX)); // INT_MAX,int型的最大值,#include <limits>//输出为: int max: 2147483647 //STR(INT_MAX) –>   _STR(2147483647) 然后再转换成字符串; printf(“%d\n”, CONS(A, A)); //输出为:200 //CONS(A, A)  –>  _CONS(2, 2) –> (int)2e2 参考:https://blog.csdn.net/bytxl/article/details/47423151https://blog.csdn.net/roger_ranger/article/details/78305021

————————

< strong > I. (#) stringing operator < / strong > function: convert the incoming parameter name in the macro definition into a parameter name string enclosed in a pair of double quotation marks. It can only be used in macro definitions with incoming parameters, and must be placed in front of the parameter name in the macro definition body.

For example:

#define example( instr )  printf( “the input string is:\t%s\n”, #instr )#define example1( instr )  #instr当使用该宏定义时:

example( abc ); // When compiling, the exhibition will be opened as: printf (“the input string is: \ T% s \ n”, “ABC”) string STR = example1 (ABC); / / it will be expanded into: String STR = “ABC” note that the processing of spaces:

a. Ignore the spaces before and after the passed in parameter name.

For example: STR = example1 (ABC)// It will be extended to STR = “ABC” B. when there are spaces between the incoming parameter names, the compiler will automatically connect each substring with a space between each substring, ignoring the remaining spaces.

For example: STR = exapme (ABC DEF)// It will be extended to STR = “ABC def” < strong > II. (##) symbolic connection operator < / strong > function: convert multiple formal parameters defined by the macro into an actual parameter name. For example:

#define exampleNum( n )  num##n使用:

int num9 = 9; int num = exampleNum( 9 ); // Will be expanded to int num = Num9 note:

a. When ## connecting formal parameters, the spaces before and after ## are optional.

For example: #define examplenum (n) num ## n / / equivalent to #define examplenum (n) num ##nb The actual parameter name after connection must be an actual parameter name or a macro definition known to the compiler.

c. If ## the parameter after is also a macro, ## it will prevent the macro from expanding.

#include <stdio.h>#include <string.h>

#define STRCPY(a, b)   strcpy(a ## _p, #b)int main(){    char var1_p[20];    char var2_p[30];    strcpy(var1_p, “aaaa”);    strcpy(var2_p, “bbbb”);    STRCPY(var1, var2);    STRCPY(var2, var1);    printf(“var1 = %s\n”, var1_p);    printf(“var2 = %s\n”, var2_p);

//STRCPY(STRCPY(var1,var2),var2); / / will it expand to: strcpy (strcpy) (var1_p, “var2”)_ p. “Var2”)? The answer is no. / / the expansion result will be: strcpy (strcpy (VAR1, var2) _p, “var2”) / / ## prevents the macro expansion of parameters! If # and ## are not used in the macro definition, the macro will be fully expanded. / / if the comment is opened, an error will be reported: implicit declaration of function ‘strcpy’ return 0;} result:

VAR1 = var2var2 = VAR1 < strong > III. (#@) single character operator < / strong > function: convert the incoming single character parameter name into characters and enclose it with a pair of single references.

For example:

#define makechar(x)    #@xchar a = makechar( b ); // After expansion, it becomes: a = ‘B’< Strong > IV. (\) continuation operator < / strong > function: when the defined macro cannot be expressed completely in one line, you can use “\” to indicate that the definition of this macro can be continued in the next line.

Note: leave space before \.

When the macro parameter is another macro, it should be noted that where there is’ # ‘or’ ## ‘in the macro definition, the macro parameter will not be expanded.

< strong > 1. Non # and ## < / strong >

#define TOW       (2) #define MUL(a,b) (a*b) printf(“%d*%d=%d\n”, TOW, TOW, MUL(TOW,TOW)); / / the macro in this line will be expanded to: printf (‘% d *% d =% d \ n’, (2), (2), (2) * (2)); / / the parameter tow in mul will be expanded to (2) < strong > 2. When there is # or ## < / strong >

#define A           2#define STR(s)      #s #define CONS(a,b)   (int)a##e##bprintf(“int max: %s\n”,   STR(INT_MAX));     // INT_ MAX #include < limits>// This line will be expanded to: / / 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 again, but the solution to this problem is simple Add one more layer of intermediate conversion macro// The purpose of adding this layer of macro is to expand all macro parameters in this layer, so the correct macro parameters can be obtained by converting the macro (_str) in the macro  #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 macro # printf (“int Max:% s \ n”, str (int_max))// INT_ Max, maximum value of int type, include & lt; limits>// Output: int Max: 2147483647 / / str (int_max) – & gt;   _ Str (2147483647) and then converted into a string;  printf(“%d\n”, CONS(A, A)); / / output: 200 / / cons (a, a) – & gt;  _ CONS(2, 2) –> (int) 2e2# reference: https://blog.csdn.net/bytxl/article/details/47423151https://blog.csdn.net/roger_ranger/article/details/78305021