关于#和##c#
在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操做(Stringfication),简单说就是在对它所引用的宏变量经过替换后在其左右各加上一个双引号。好比下面代码中的宏:数组
1. #使用ide
#define WARN_IF(EXP) /函数
do{ if (EXP) /ui
fprintf(stderr, "Warning: " #EXP "/n"); } /spa
while(0)指针
那么实际使用中会出现下面所示的替换过程:code
WARN_IF (divider ); 其中divider == 0对象
被替换为blog
do { if (divider == 0) fprintf(stderr, "Warning" "divider == 0" "/n"); } while(0);
这样每次divider(除数)为0的时候便会在标准错误流上输出一个提示信息。
2. ##使用
而## 被称为链接符(concatenator),用来将两个Token链接为一个Token。注意这里链接的对象是Token就行,而不必定是宏的变量。好比你要作一个菜单项命令名和函数指针组成的结构体的数组,而且但愿在函数名和菜单项命令名之间有直观的、名字上的关系。那么下面的代码就很是实用:
struct command { char * name; void (*function) (void); };
#define COMMAND(NAME) { NAME, NAME ## _command } 此处的##表示后面有内容与NAME连接
// 而后你就用一些预先定义好的命令来方便的初始化一个command结构的数组了:
struct command commands[] = { COMMAND(quit), COMMAND(help), ... }
COMMAND宏在这里充当一个代码生成器的做用,这样能够在必定程度上减小代码密度,间接地也能够减小不留心所形成的错误。咱们还能够n个##符号链接 n+1个Token,这个特性也是#符号所不具有的。好比:
#define LINK_MULTIPLE(a,b,c,d) a##_##b##_##c##_##d //注意这里的规则(a##开头,##d结束,中间都用##x##)
typedef struct _record_type LINK_MULTIPLE(name,company,position,salary);
// 这里这个语句将展开为:
// typedef struct _record_type name_company_position_salary;
我的认为##相似 运算符+ 起到链接的做用。
3 再看一个#使用以下:
#define display(name) printf(""#name"") int main() { display(name); }
运行结果是name,为何不是"#name"呢?
---------------------------------------------------------------
#在这里是字符串化的意思 printf(""#name"") 至关于 printf("" "name" "")