C++中#(一个#号)和##(两个#号)的用法和作用

本文介绍了C++里#和##的用法与作用。#用于宏参数的字符串化操作,即对引用的宏变量替换后左右加双引号;##是连接符,可将两个Token链接成一个;还提到了变参宏中##能在__VA_ARGS__为空时消除前面的逗号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 C++中#(一个#号)和##(两个#号)的用法和作用

1 关于一个#号:
在C语言的宏中,#的功能是将其后面的宏参数进行字符串化操作, 简单说就是对他所引用的宏变量通过替换后再其左右各加上一个双引用。
例子:

# define WARNIF(EXP) \
do{ \
    if (EXP) \
    {    \    
        fprintf(stderr, "warning:" #EXP "\n"); \
    }   \    
}while(0)    
在实际使用中会出现下面所示的替换过程:
WARN_IF(div == 0); 被替换成以下代码
do{
    if (div == 0) 
    {        
        fprintf(stderr, "warning:" "div == 0" "\n"); 
    }       
}while(0)

2 关于两个#号:
##被称为连接符,用来将两个Token链接成一个Token.注意这里的连接的对象时Token就行, 而不一定是宏的变量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数和菜单项命令名直接有直观的名字上的关系, 那么下面的代码就非常实用

struct command
{
    char *name;
    void (*function)(void);
};

#define COMMAND(NAME){NAME, NAME##_command}
然后就用一些预定义好的命令来方便的初始化一个command结构的数据了:
struct command commands[] = {
    COMMAND(quit),
    COMMAND(help),
    ...
}
COMMAND宏在这里充当一个代码生成器的作用,这样可以在一定程度上减少代码的密度, 间接的也可以减少粗心所造成的错误。
我们还可以n个##符号链接n+1个Token,这个特性也是#符号所不具备的。
例如: #define LINK_MULTIPLE(a, b, c, d) a##_##b##_##c##_###d
typedef struct_record_type LINK_MULTIPLE(name, company, position, salary);
//展开内容为 : typedef struct_record_type name_company_position_salary;

3 关于...的使用
...在C语言中被称为变参宏 
#define myprintf(templt, ...)  fprintf(stderr, templt, ##__VA_ARGS__)
这是##这个连接符充当的作用就是当__VA_ARGS__为空的时候, 消除前面的那个逗号。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值