关于#和##在C语言的宏中,
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
Printf(STR(vck)); // 输出字符串"vck"
printf("%d\n", CONS(2,3)); // 2e3 输出:2000
1.#的功能是将其后面的宏参数进行字符串化操作(Stringfication),
简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个双引号。
比如下面代码中的宏:#define WARN_IF(EXP)
do{ if (EXP)
fprintf(stderr, "Warning: " #EXP " "); }
while(0)
那么实际使用中会出现下面所示的替换过程:WARN_IF (divider == 0);
被替换为
do {
if (divider == 0)
fprintf(stderr, "Warning" "divider == 0" " ");
} while(0);
这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。
2. 而##被称为连接符(concatenator),用来将两个Token连接为一个Token。
注意这里连接的对象是Token就行,而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就非常实用:
struct command
{
char * name;
void (*function) (void);
};
#define COMMAND(NAME) { NAME, NAME ## _command }
// 然后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:
struct command commands[] = {
COMMAND(quit),
COMMAND(help),
…
}