C语言进阶——编译预处理指令
编译预处理指令
• #开头的是编译预处理指令
• 它们不是C语⾔的成分,但是C语⾔程序离不开它们
• #define⽤来定义⼀个宏
#define
• #define <名字> <值>
• 注意没有结尾的分号,因为不是C的语句
• 名字必须是⼀个单词,值可以是各种东⻄
• 在C语⾔的编译器开始编译之前,编译预处理程序(cpp)会把程序中的名字替换成值
• 完全的⽂本替换
• gcc —save-temps
宏
• 如果⼀个宏的值中有其他的宏的名字,也是会被
替换的
• 如果⼀个宏的值超过⼀⾏,最后⼀⾏之前的⾏末
需要加\
• 宏的值后⾯出现的注释不会被当作宏的值的⼀部
分
没有值的宏
• #define _DEBUG
• 这类宏是⽤于条件编译的,后⾯有其他的编译预处理指令来检查这个宏是否已经被定义过了
预定义的宏
• __LINE__
• __FILE__
• __DATE__
• __TIME__
• __STDC__
错误定义的宏
• #define RADTODEG(x) (x * 57.29578)
• #define RADTODEG(x) (x) * 57.29578
带参数的宏的原则
• ⼀切都要括号
• 整个值要括号
• 参数出现的每个地⽅都要括号
• #define RADTODEG(x) ((x) * 57.29578)
• #define cube(x) ((x)*(x)*(x))
• 宏可以带参数
带参数的宏
• 可以带多个参数
• #define MIN(a,b) ((a)>(b)?(b):(a))
• 也可以组合(嵌套)使⽤其他宏
// 比如++i类似的自增运算符 属于是文本替换 所以在传参的时候,并没有执行一次自增运算。它只是像函数而且带参数的宏。
分号?
#define PRETTY_PRINT(msg) printf(msg); //不要加分号,因为你在C代码中会习惯再加上一个分号的。
if (n < 10)
PRETTY_PRINT("n is less than 10");
else
PRETTY_PRINT("n is at least 10");
带参数的宏
• 在⼤型程序的代码中使⽤⾮常普遍
• 可以⾮常复杂,如“产⽣”函数
• 在#和##这两个运算符的帮助下
• 存在中⻄⽅⽂化差异
• 部分宏会被inline函数替代
其他编译预处理指令
• 条件编译
• error