#:字符串化
可以用在断言中,如果断言失败,则输出到反馈信息中(echo > err.msg)
When you put a # before an argument in a preprocessor macro, the preprocessor turns that argument into a character array. This, combined with the fact that character arrays with no intervening punctuation are concatenated into a single character array, allows you to make a very convenient macro for printing the values of variables during debugging
When you put a # before an argument in a preprocessor macro, the preprocessor turns that argument into a character array.
**注意:#**宏的参数会被直接转换并不会递归展开,这是它与其他带参宏的不同
案例
#define WARN_IF(EXP) do {if (EXP) \
fprintf(stderr, "Warning: " #EXP "\n"); \
}while(0);
#define IntTostring(EXP) #EXP
// ** user code ** //
int err_module = 0;
WARN_IF(err_module == 0);
IntTostring(err_module);
//输出
Warning: err_module == 0
err_module
##:连接左右符号
在宏体中,如果宏体所在标示符中有##,那么在宏体扩展的时候,宏参数会被直接替换到标示符中。(转者注:这里的宏参数会展开一次,但是并不会递归展开.对宏体中的参数替换一次,然后强制链接)
案例
// 1.基础用法
#define WhatAFuckDay 555
#define Type1(type, name) type _name ## name_ ## WhatAFuckDay
#define Type2(type, name) type _name ## name_
#define Type3(type, name) type _name_ ## name
// ** user code ** //
Type1(int, c); // int _namename_WhatAFuckDay;
Type1(int, c); // int _namename_;
Type2(int, c); // int _name_c;
_namename_WhatAFuckDay = 1;
_namename_ = 2;
_name_c = 3;
std::cout << _namename_WhatAFuckDay << _namename_ << _name_c << std::endl;
//2.函数指针场景
#define COMMAND(NAME) { #NAME, NAME ## _command }
// ** user code ** //
struct command {
char *name;
using function = void(*)(void);
function pFunc;
};
struct command commands[] = {
COMMAND (quit),
COMMAND (help),
...
};
// ** 编译时 ** //
struct command commands[] = {
{ "quit", quit_command },
{ "help", help_command },
...
};