预处理器
首先C 预处理器不是编译器的组成部分,但是是编译过程中一个单独的步骤。本质是一个文本替换工具,指示编译器在实际编译之前完成所需的预处理。 C Preporcessor 简称 CPP
-
所有预处理命令都是由 # 开头, 必须是一个非空字符,为增加可读性,应从第一列开始。
#define | 定义宏 #include | 包含一个源代码文件 #undef | 取消已定义的宏 #ifdef | 如果宏已经定义,返回真 #ifndef | 如果宏没有定义,返回真 #if | 如果给定条件为真,则编译下面代码 #else | #if 的代替方案 #elif | 如果前面的#if 条件不为真,则编译下面代码 #endif | 结束一个 #if...#else 条件编码块 #error | 当遇到标准错误时,输出错误消息 #pragma | 使用标准化方法,向编译器发布特殊的命令到编译器中
这部分内容在前面的时候都有遇到过,简单的复习一下。
-
定义常量
-
从系统库中获取 stdion.h 添加到源文件中
#include "myheader.h"
从本地目录获取 myheader.h 并添加到当前源文件中
-
-
-
除此之外还有 预定义宏
__DATE__ | 当前日期 , 一个以 “MMM DD YYYY” 格式表示的字符常量
__TIME__ | 当前时间 , 一个以 “HH:MM:SS” 格式表示的字符常量
__FILE__ | 包含当前文件名 ,一个字符常量
__LINE__ | 包含当前行号 , 一个十进制常量
__STDC__ | 编译器为 ANSI 标准编译时 ,定义为1
printf("-=-=-=-=-=-=-=-=-=-==-=-=-=-=\n");
printf("下面运行测试一下预定义宏:\n");
printf("FILE:%s\n",__FILE__);
printf("Date:%s\n",__DATE__);
printf("Time:%s\n",__TIME__);
printf("Line:%d\n",__LINE__);
//printf("ANSI:%d\n",__STDC__);
在测试中发现 __ STDC __ 报错,显示未定义。上网搜索没找到问题,暂时搁置。
预处理器运算符
预处理器也有自己的运算符
-
宏延续运算符 ( / )
- 单行无法容纳时,使用延续运算符
-
字符串常量化运算符 ( # )
- 将宏的参数转化为字符串常量d
-
标记粘贴运算符 ( ## )
- 会合并两个参数,允许在宏定义中两个独立的标记合成一个标记
-
使用 #if 以及 #endif
#define message_for(a,b) \ printf(#a " and " #b ": We love you ! \n") #define tokenpaster(n) \ printf("token" #n " = %d",token##n) #if !defined(MESSAGE) #define MESSAGE "You wish!" #endif int main(void) { message_for(Cadarl, Deb); int token23 = 540; tokenpaster(23); printf("\nHere is the message: %s \n", MESSAGE); }
可以将宏看做函数的另一种表达方式。在CPP中可以使用参数化的宏来模拟函数
需要注意的是在宏定义后的参数括号与名称前需要没有空格
/*int square(int x) { return x * x } */
#define square(x) ((x) * (x))
#define MAX(x,y) ( (x) > (y) ? (x) : (y))
printf("Max between 20 and 10 is : %d \n", MAX(10,20));
printf(" %d * %d = %d\n",10, 10 , square(10));