宏定义的#和##

‘#’

宏定义中一个#表示右侧的符号转化为字符串,比如:

#define STR(x) #x

QString s = STR(3)

编译ok,s值为"3"。

之前在看QT源码时,发现了下面的宏定义:

# define QLOCATION "\0" __FILE__ ":" QT_STRINGIFY(__LINE__)

#define QT_STRINGIFY2(x) #x
#define QT_STRINGIFY(x) QT_STRINGIFY2(x)

第一行的好理解,就是把文件行号拼起来,后面两行看起来有点重复,中间多了一层转换,我就试了下两个宏有什么不同:

#define STR(x) #x
#define STR1(x) STR(x)

QString s = STR(3);

#define NUM 3
QString s1 = STR(NUM);
QString s2 = STR1(NUM);
qDebug() << s << s1 << s2;

输出结果:“3” “NUM” “3”
使用STR(NUM)传入宏时结果为"NUM",说明NUM宏没有被展开,所以前面中间多了一层。
如果#右侧的符号本身就是字符串会怎么样呢,我们试试:

#define _STR(x) #x
#define STR(x) _STR(x)
#define TTT(x) _STR(abc x)
    QString sp = TTT("123");
    qDebug() << sp;

上面加了一个TTT宏,TTT("abc")展开为_STR(abc "123"),再展开得到#abc "123",实际的输出结果是"abc \"123\"",而且中间的空格并没有中断#的处理(当时发现中间有空格,想着在#define _STR(x) #x的x加个括号,发现报错不让加,原来有空格也没问题)。

‘##’

##表示将左右的符号拼接在一起。例如拼接变量名:

#define INT(name) INT_##name

int INT_A = 13;
int INT_B = 10;

int a = INT(A); //  INT(A)展开为INT_##A,通过##连接得到INT_A
int b = INT(B);
qDebug() << a << b;

输出13 10。

同样,##的参数如果是宏的话也不会展开,需要写中间宏来处理

#define _INT2(name) INT_##name
#define INT2(name) _INT2(name)

#define INT(name) INT_##name

#define NAME A

int INT_A = 13;
int INT_B = 10;

int a = INT(NAME); // 编译失败,提示INT_NAME不存在
int aa = INT2(NAME); // 成功展开为INT_A

从上面可以看出,如果##的参数是宏的话,需要写一个中间层去处理

总结

  • #表示右侧的符号转化为字符串
  • ##只是简单的将左右两边的符号连接在一起。
  • #和##的参数如果是宏,都需要写一个中间宏来扩展,否则参数宏不会展开
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值