C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。
C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。
我们将把 C 预处理器(C Preprocessor)简写为 CPP。
所有的预处理器命令都是以井号(#)开头。
一.预处理器实例
解决App上线不能向终端输入信息的问题
#define DEBUG 1
#if DEBUG
#define Log(x) printf(x)
#else
#define Log(x)
#endif
二.预定义宏
在编程中您可以使用这些宏,但是不能直接修改这些预定义的宏。
#include <stdio.h>
int main() {
printf("File :%s\n", __FILE__ );
printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
return 0;
}
//运行结果
File :c:\users\a2867\desktop\c语言学习\c语言阶段\day6_2.s_t\s_t.cpp
Date :Aug 5 2019
Time :22:32:28
Line :8
三.预处理器运算符
- 一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)。
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
- 在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)
#include <stdio.h>
#define message_for(a, b) \
printf(#a " and " #b ": We love you!\n")
int main(void) {
message_for(Carole, Debra);
return 0;
}
//运行结果
Carole and Debra: We love you!
- 宏定义内的标记粘贴运算符(##)会合并两个参数,它允许在宏定义中两个独立的标记被合并为一个标记。
#include <stdio.h>
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
int main(void) {
int token34 = 40;
tokenpaster(34);
return 0;
}
//运行结果
//实际上执行了printf ("token34 = %d", token34);
token34 = 40
四.参数化的宏
- CPP 一个强大的功能是可以使用参数化的宏来模拟函数。
#include <stdio.h>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
int main(void) {
printf("Max between 20 and 10 is %d\n", MAX(10, 20));
return 0;
}
//运行结果
Max between 20 and 10 is 20