c 路径 空格 参数_【Just For Fun】C - 预处理器、宏 #, ##、预先定义的宏

33295407cee54a5046361a8cfd122813.png

【Just For Fun】

本系列纯粹娱乐、研究用。一些旁门左道的东西。
事实上可能完全没用。 (๑•̀ω•́๑)

说一点基础的宏知识,###
曾经有在 另一些地方 写过,又搬过来一下。

▌预处理器:

预处理器,于编译前进行。
例如常用的 #include#define#define 即 宏/巨集 (marco) 。

# 开头都是预处理器,其他的例子如
例如: #if, #endif, #else, #elif,#ifdef, #ifndef, #error, #pragma, #typedef 等等。

详情可参考 microsoft 的 C/C++ 前置处理器参考
以及 Preprocessor Directives | Microsoft Docs

▌宏 #define:

宏和指标可谓是 C 语言的精髓,
依靠它们可以创造无限可能,极为博大精深。

宏可以节省工作量,同时增加可读性,使代码变得优雅。
即使宏的本身不优雅、可读。

一般代换展开这种基础知识就不说了,以下讲述 ### 前置处理器运算子的功能,
详情亦可参考 microsoft 的 前置处理器运算子

#:

# — 字串化运算子,
放在宏参数前,展开时中参数两端加入 ",使其字串化。

例子:

#define str(x) #x

使用 str( 9qwe7 h5d1v3jk6w ) 会被展开为

" 9qwe7 h5d1v3jk6w "

___

另外,根据定义,

如果在字串常值中使用引数包含通常需要逸出序列时 (例如引号 (") 或反斜线 () 字元),必要的逸出反斜线字元就会自动插入至该字元之前。

# 会自动添加逸出反斜线字元(
利用此特性可以简化大量需要逸出反斜线的字串。

___

例如 我要输入 the "" mean escaped character. 作为字串
正常:"the "" mean escaped character."
宏: str(the "" mean escaped character.)
某程度上来说,可读性会较好。

还有常见的档案路径,如果我要输入 D:UserDocumentsC_Test.txt 作为档案路径。
正常:"D:UserDocumentsC_Test.txt"
宏: str(D:UserDocumentsC_Test.txt)
可以不用考虑要不要加 ,也可以打少一些字元。

##:

## — 语汇基元带入的运算子,
这名字是 microsoft 改的,有时称为「合并」运算子。

可以合并文字,例子:

#define mix(x) abc##x

使用 mix(d) 会被展开为 abcd

意义何在呢?因为识别字(identifier)是以空格等等作为分隔,若果:

#define mix(x) abcx

预处理器无法辨认出 x,它只看到有 abcx 这个识别字。
加入 ## 可以令它识别出 宏参数 并将其合并。

另外,## 前后的空格可有可无,
abc##x 等价 abc ## x

▌阻止另一个宏的展开:

一旦在使用了 ### 在 宏中,
其宏参数是另一个宏 ,
将会阻止另一个宏的展开。

例子:

#define foo abc
#define foo2(x) x##123

foo2(foo) 的结果并不会是 abc123
不会展开作为参数的宏 foo
所以结果是 foo123

可参看 C宏展开的几个注意事项 - nanoix9 - 博客园,貌似很详细。

注意一下 VS 的展开规则,跟其他编译器不一样
(来自作者血泪的教训。Q _____ Q)

▌预先定义的宏:

有一些预先定义在前置处理器中的宏:__LINE__:从原始档开头起算, __LINE__ 所在的行数__FILE__:档案名称(字串常数)__DATE__:以 Mmm dd yyyy 格式(eg. Oct 31 2018),表示编译时的日期__TIME__:以 hh:mm:ss 格式,表示编译时的时间 (字串常数)__STDC__:若 1 ,表示编译器遵循 ISO C 标准__STDC_VERSION__:若支援 C99,数值为 199901L , 若支援 C11,数值为 201112L__func__:函式名称 (C99)

...还有很多,不全部列出。

__LINE____FILE__ 常用于错误讯息。__func__ 也是,不过是 C99 才支援。

还有一些是编译器扩展,但C标准好像没有支持的。
像是 __COUNT__
这个很实用,未来可能会讲解一下。

___

最后特意推荐 宏定义的黑魔法 - 宏菜鸟起飞手册,

循序渐进,很好,很详细,很深入。
学到不少新技术,
推荐推荐~!

▌参考资料:

预处理器 - 维基百科,自由的百科全书
C/C++ 前置处理器参考 C/C++ Preprocessor Reference
前置处理器运算子 Preprocessor Operators
C宏展开的几个注意事项 - nanoix9 - 博客园
[C 語言] 程式設計教學:如何使用巨集 (macro) 或前置處理器 (Preprocessor)
宏定义的黑魔法 - 宏菜鸟起飞手册

___

原文網址(作者是我):2019 iT 邦幫忙鐵人賽:Day 21:重溫前置處理器、巨集( #, ## )、預先定義的巨集

___

【Just For Fun】俺 是 目 录 !

___

下一篇:【Just For Fun】C - 可变参数函数、可变参数宏 __VA_ARGS__、额外的逗号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值