💝总结了在实际开发过程中使用到的开发技巧,在此记录。
👉官方解释:数字符号或"字符串化"运算符 (#) 将宏参数转换为字符串文本,而不扩展参数定义。它仅用于接受参数的宏。如果它位于宏定义中的正式参数之前,则宏调用传递的实际参数将括在引号中,并被视为字符串文本。然后,字符串文本将替换宏定义中字符串化运算符和正式参数组合的每个匹配项。
实际参数的第一个标记之前和实际参数的最后一个标记后面的空格将被忽略。在生成的字符串文本中,实际参数中的标记之间的任何空格都将减少到单个空格。因此,如果注释出现在实际参数中的两个标记之间,则将其简化为单个空格。生成的字符串文本会自动与任何相邻的字符串文本连接,而相邻的字符串文本仅由空格分隔。
此外,如果在字符串文本(例如,引号 (") 或反斜杠 (\) 字符)中使用时,参数中包含的字符通常需要转义序列,则在该字符之前会自动插入必要的转义反斜杠。
就是说在它引用的宏变量的左右各加上一个双引号😏
代码如下(示例):
#define name2str(name) (#name) /*定义宏*/
typedef enum
{
E_ONE,
E_TWO,
E_THREE
}enum_x;
void test()
{
printf("test\n");
}
int main(void)
{
/*name2str宏的参数可以是数字、函数名、变量名、枚举成员名称...*/
const char* strname = name2str(001); // (1)
//const char* strname = name2str(E_ONE);// (2)
//const char* strname = name2str(enum_x);// (3)
//const char* strname = name2str(test);// (4)
printf("strname:%s\n", strname);
return 0;
}
上述代码打印结果为👎
(1)“strname:001”
(2)“strname:E_ONE”
(3)“strname:enum_x"
(3)“strname:test"
👉官方解释:双数字符号或"令牌粘贴"运算符 (##)有时称为"合并"运算符,用于类对象宏和类函数宏。它允许将单独的令牌联接到单个令牌中,因此不能是宏定义中的第一个或最后一个令牌。
如果宏定义中的正式参数前面或后面是标记粘贴运算符,则该正式参数将立即替换为未展开的实际参数。在替换之前,不会对参数执行宏扩展。
然后,将删除令牌字符串中每次出现的令牌粘贴运算符,并连接其前面和后面的标记。生成的令牌必须是有效的令牌。如果是,则扫描令牌,以查找可能的替换(如果它表示宏名)。标识符表示在替换之前在程序中已知的串联令牌的名称。每个令牌都表示在其他位置(程序中或在编译器命令行上)定义的令牌。运算符前面或后面的空格是可选的。
可以理解为拼接功能😏
代码如下(示例):
#include <stdio.h>
#define paster( n ) printf_s( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
上述代码打印结果为👎
token9 = 9