C语言宏中的 # 和 ## 的骚气

举报
ReCclay 发表于 2022/02/22 02:18:02 2022/02/22
【摘要】 记得上次见到它们是在17年暑假电赛上,当时忘了记录,而今又重新拾起,来总结下! 总的来说呢, 单#号就是对它所引用的宏变量通过替换后在其左右各加上一个双引号。 而##被称为连接符(concate...

记得上次见到它们是在17年暑假电赛上,当时忘了记录,而今又重新拾起,来总结下!


总的来说呢,
单#号就是对它所引用的宏变量通过替换后在其左右各加上一个双引号。

而##被称为连接符(concatenator),用来将两个Token连接为一个Token。

先来看一个例子:

#include <stdio.h>
#include <stdlib.h>
#define paster(n) printf("token"#n"=%d", token##n   )

int main()
{
    int token9 = 9;
    paster(9);
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

运行结果:


token9=9
Process returned 0 (0x0)   execution time : 0.035 s
Press any key to continue.

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

en,,,没错。#n被原封不动的替换成为”9”,,然后 token##9 则被替换成为 token9


定义单行宏:主要有以下三种用法.

1、 前加##或后加##,将标记作为一个合法的标识符的一部分.注意,不是字符串.多用于多行的宏定义中.例如:

#define A(x)  T_##xint A(1) = 10; //等效于int T_1 = 10;
#define A(x)  Tx##__int A(1) = 10; //等效于int T1__ = 10;
  
 
  • 1
  • 2
  • 3
  • 4

2、 前加#@,将标记转换为相应的字符,注意:仅对单一标记转换有效

        #define B(x) #@xB(a)即’a’,B(1)即’1’.但B(abc)却不甚有效.
  
 
  • 1
  • 2

3、前加#,将标记转换为字符串.

 #define C(x) #x
 则C(1+1) 即 ”1+1”.
  
 
  • 1
  • 2

对了,再来补充一下!

#和## 宏参数是不支持宏的。

什么意思呢?宏定义中有#或者##的地方都不会再进行宏展开。
譬如,

#define K A
#define PT(X) PT##X

  
 
  • 1
  • 2
  • 3

当写入PT(K)的时候,最终的展开也只能是PTK,因为有##不会再进行宏展开了?

如何让其再次进行宏展开呢?

再来一层宏进行包装!

#define K A
#define _PT(X) PT##X
#define PT(X) _PT(X)
  
 
  • 1
  • 2
  • 3

这个时候再次执行, PT(K),,宏展开之后就是PTA了。

再记录一段,常用的调试代码..

#include <stdio.h>
#include <stdlib.h>

#define _MKSTR(str) #str
#define MKSTR(str) _MKSTR(str)
#define DEFINE_PRINTF(def) printf(MKSTR(def)"\n")
#define K A
#define _PT(X) PT##X
#define PT(X) _PT(X)

int main()
{
    DEFINE_PRINTF(PT(K));
    return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
PTA

Process returned 0 (0x0)   execution time : 0.026 s
Press any key to continue.

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

再来补充一个反斜杠 \
\ 行继续操作

\行继续操作当定义的宏不能用一行表达完整时,可以用”\”表示下一行继续此宏的定义注意:最后一行不要加续行符啊.VC的预处理器在编译之前会自动将\与换行回车去掉(写成多行时,反斜杠后不能有空格,否则编译器(ARM或VC)会报错!),这样一来既不影响阅读,又不影响逻辑,皆大欢喜.

参考:
1、http://blog.csdn.net/killmice/article/details/49003739

2、http://bbs.csdn.net/topics/280055634

3、http://blog.csdn.net/u012234115/article/details/42169815

文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。

原文链接:recclay.blog.csdn.net/article/details/79145218

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。