0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言-#和##的具体用法

嵌入式那些事 来源:嵌入式那些事 2023-12-19 12:54 次阅读

C语言中,在宏里面使用’#’和’##’有它非常神奇的作用。在宏定义的替换的过程中,#号可以作为一个预处理运算符,把宏参数转换为字符串。##运算符则可以把两个宏参数组合在一起。下面就来说说具体的用法。

1、一般用法

我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起。

下面的代码是演示代码:

#include

#defineSTRING(s)#s
#defineCONNECT(a,b)(int)(a##e##b)

intmain(void)
{
//输出字符串"abcdefg"
printf("string:%s
",STRING(abcdefg));

//2e3输出:2000
printf("connect:%d
",CONNECT(2,3));

return0;
}

运行结果如下图:

d2c6516a-9e26-11ee-8b88-92fbcf53809c.png

2016-03-21_171313

2、当宏参数是另一个宏的时候

需要注意的是:凡是宏定义里有用'#'或'##'的地方,宏参数是不会再展开。

(1)、非’#’和’##’的情况

#include

#defineTOW(2)
#defineMUL(a,b)(a*b)

intmain(void)
{
printf("%d*%d=%d
",TOW,TOW,MUL(TOW,TOW));

return0;
}

上面代码中打印那行的宏会被展开为:

printf("%d*%d=%d
",(2),(2),((2)*(2)));

(2)、当有'#'或'##'的时候

#include
#include

#defineA(2)
#defineSTR(s)#s
#defineCONS(a,b)(int)(a##e##b)

intmain(void)
{
//INT_MAX这行会被展开为:printf("intmax:%s
","INT_MAX");
printf("intmax:%s
",STR(INT_MAX));

//这一行会被展开为:printf("%s
",(int)(AeA));
printf("%s
",CONS(A,A));

return0;
}

上面的代码在编译时会失败,INT_MAX和A都不会再被展开,然而解决这个问题的方法也很简单。加多一层中间转换宏。加这层宏的用意是把所有宏的参数在这层里全部展开,那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数。

#include
#include

#defineA2
#define_STR(s)#s
#defineSTR(s)_STR(s)//转换宏
#define_CONS(a,b)(int)(a##e##b)
#defineCONS(a,b)_CONS(a,b)//转换宏

intmain(void)
{
//INT_MAX,int型的最大值,为一个变量
printf("intmax:%s
",STR(INT_MAX));

printf("CONS(A,A):%d
",CONS(A,A));

return0;
}

其中代码:

printf("intmax:%s
",STR(INT_MAX));

输出为:int max: 2147483647,STR(INT_MAX) ---> _STR(2147483647) 然后再转换成字符串。

第二个输出代码:

printf("CONS(A,A):%d
",CONS(A,A));

输出为:CONS(A, A):200,CONS(A, A) ---> _CONS(2, 2) ---> int(2e2)。

3、'#'和'##'的一些应用特例

(1)、合并匿名变量名

#include

#define___ANONYMOUS1(type,var,line)typevar##line
#define__ANONYMOUS0(type,line)___ANONYMOUS1(type,_anonymous,line)
#defineANONYMOUS(type)__ANONYMOUS0(type,__LINE__)

intmain(void)
{
ANONYMOUS(staticint);

_anonymous9=666;

printf("_anonymous9:%d
",_anonymous9);

return0;
}

上述代码:ANONYMOUS(static int);最终展开为:static int _anonymous9; // 9表示该行行号;,下面分析下具体的展开过程:

第一次展开:ANONYMOUS(static int); ---> __ANONYMOUS0(static int, __LINE__);;

第二次展开:__ANONYMOUS0(static int, __LINE__); ---> ___ANONYMOUS1(static int, _anonymous, 9);;

第三次展开:___ANONYMOUS1(static int, _anonymous, 9); ---> static int _anonymous9;;

对于宏的展开过程,每次只能解开当前层的宏,所以__LINE__在第二层才能被解开。

(2)、获取文件名

#include

#define_GET_FILENAME(filename)#filename
#defineGET_FILENAME(filename)_GET_FILENAME(filename)

intmain(void)
{
charfilename[]=GET_FILENAME(__FILE__);

printf("filename:%s
",filename);

return0;
}

当然了,上述的宏也可以获取__DATE__,__LINE__等宏实际对应的值,上面专门定义了一个数组来存储转换后的值,实际使用时是否定义数组可自行安排。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128782
  • 字符串
    +关注

    关注

    1

    文章

    552

    浏览量

    20130
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66784
  • 运算符
    +关注

    关注

    0

    文章

    163

    浏览量

    10947

原文标题:C语言-#和##的神奇作用

文章出处:【微信号:嵌入式那些事,微信公众号:嵌入式那些事】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于Rust语言Hash特征的基础用法和进阶用法

    ,包括Hash trait、HashMap、HashSet等,本教程将详细介绍Rust语言Hash特征的基础用法和进阶用法。 基础用法 使用Hash trait 在Rust
    的头像 发表于 09-19 16:02 741次阅读

    plsy指令具体用法

    、WAV等。下面将详细介绍plsy的用法。 安装: 在使用plsy之前,首先需要在Unix系统中安装。你可以通过在终端上运行以下命令来安装plsy: sudo apt-get install plsy
    的头像 发表于 12-08 14:10 847次阅读

    谁知道BAV99的具体功能和用法

    本帖最后由 gk320830 于 2015-3-9 20:41 编辑 谁知道BAV99的具体用法
    发表于 09-07 09:33

    单片机的C语言中位操作用法

    单片机的C语言中位操作用法
    发表于 08-17 15:04

    discrete filter 与discrete transfer 两者的具体用法

    请教一哈大侠们:能不能举一下具体的例子来说明两个的具体用法呀!!两个的图标分别如下:先谢谢哈!!
    发表于 01-03 19:45

    求教这个软键盘的具体用法

    这个软键盘的具体用法,谢谢。
    发表于 09-30 21:28

    CC3200 的“VStartSimpleLinkSpawnTask具体用途是什么?

    CC3200的“VStartSimpleLinkSpawnTask(SPAWN_TASK_PRIORITY);”这个任务是否可以给讲讲?不知道这个具体用途, 应该跟wifi有关 ?貌似每个工程开始都会创建这个任务,到底是干啥用的?
    发表于 03-14 15:59

    C语言中atoi()函数的用法 相关资料分享

    C语言中atoi()函数的用法
    发表于 07-01 08:12

    C语言的位操作在STM32f1单片机编程的具体应用 精选资料推荐

    C语言的位操作在STM32f1单片机编程的具体应用前言:熟练掌握位操作是学习stm32入门的必备技术,位操作在单片机编程中格外重要,下面我就分别详细介绍C
    发表于 07-14 07:31

    STM32CUBEMX具体详细的用法

    所需工具1、MATLAB 2018b2、STM32硬件支持工具下载连接:STM32CUBEMX(用于配置STM32资源)下载连接:和3仅仅是在生成c语言中作为一个必须辅助的工具,具体详细的用法
    发表于 08-11 06:53

    MCS51汇编中的DATA是伪指令吗?具体用法是什么?

    MCS51汇编中的DATA是伪指令吗?具体用法是什么?
    发表于 11-02 08:17

    C语言结构体用法很多,但是坑也很多

    C语言结构体用法很多,坑也很多
    的头像 发表于 01-13 16:06 1052次阅读

    温补晶振通常用法具体说明

    温补晶振通常的用法与常规有源晶振一至:一脚悬空,二脚接地,三脚接输出,四脚接电压。具体说明如下
    的头像 发表于 04-28 16:22 3158次阅读
    温补晶振通常<b class='flag-5'>用法</b><b class='flag-5'>具体</b>说明

    【C语言进阶】C语言指针的高阶用法

    【C语言进阶】C语言指针的高阶用法
    的头像 发表于 08-31 13:24 1956次阅读

    PLC光分路器的分类和具体用法

    PLC光分路器的分类和具体用法  PLC(Planar Lightwave Circuit,平面光波导电路)光分路器是一种集成光学器件,用于在光通信、光网络、传感器和光学测试等领域中实现光信号的分配
    的头像 发表于 11-28 15:50 564次阅读