目录

C语言中宏相关的技巧 - C语言的一些小技巧(2)

c语言c语言
函数式编程函数式编程
lambdalambda
c语言函数c语言函数
c语言指针c语言指针
c语言staticc语言static
c语言吧c语言吧
c语言从入门到放弃c语言从入门到放弃
c语言macroc语言macro
c语言宏c语言宏
c语言宏定义c语言宏定义
c语言宏替换c语言宏替换
c语言宏技巧c语言宏技巧
printfprintf
定义定义
countcount
intint
definedefine
iframeiframe
括号括号
includeinclude
msgmsg
MMMMMM

引子

整理一下关于C语言的各种技巧, 免得自己遗忘了. C语言的代码持有量一直稳居第一啊, TIOBE 的 C 语言排行榜一直坚挺如初.

这篇文章通过一个个例子, 介绍一下关于 Macro 的各种奇淫巧技, 以此抛砖引玉.

包含多行, 括号有无, 特殊宏, 等等.

欢迎大家指正、讨论.

例1: 多行, 括号, 字符串连接

废话不多, 代码下锅.

这里 ASSERT 被定义为一个断言函数, 实现了判断某些条件必须为真, 否则就报出指定的错误并退出程序.

宏替换与宏函数

可以看到 FAILED 因引用的方式不一致(是否添加括号), 导致结果的不同.

所以, 如果是被定义为宏函数(宏名后添加括号)的宏的话, 必须添加括号的方式来引用. 哪怕没有宏参数的定义也是一样的.

多行宏定义

宏定义的每一行末接 \ 的话, 下一行开头也为该宏的定义.

宏名后的括号与参数

宏定义带括号又叫宏函数, 顾名思义是函数的一种, 所以有参数.

但是宏的参数, 只是简单的替换, 所以有时需要加上括号规避一些优先级问题.

字符串连接

宏定义的被替换部分可以用宏的参数接上其他字面量字符串(使用 # 符号连接), 这样就会把参数的原始指作为字符串连接上去.

例如:

注意: 这段代码里, 用了两个字面量字符串相连的技巧. 另外就是 # 之后必须是宏参数, 而不能是其他.

例2: 常用写法, 特殊内置宏

__FILE__, __func__, __LINE__ 都是编译器内置预定义的宏, 分别被替换为当前语句的源文件名, 执行中的函数名和文件行数.

更多的内置宏定义可以参考: Predefined-Macros

可变参数的宏函数

常用的关于宏的编译器参数

gcc

  • 定义宏: -D <macro>=<value>, 如果 value 被忽略的话, 将被定义为1
  • 宏展开: -E, 例如: gcc -E foo.c, 这将打印出文件被展开所有宏之后的内容, 方便调试复杂的宏是怎么暂开的

msvc cl

  • 定义宏: /D<macro> <value>/D <macro>=<value>, 例如: CL /DDEBUG TEST.CCL /D __far= TEST.C
  • 宏展开: /P, 例如: CL /P /C ADD.C