一、预处理
1.预处理的基本概念
C语言对源程序处理的四个步骤:预处理、编译、汇编、链接。
预处理是在程序源代码被编译之前,由预处理器(Preprocessor)对程序源代码进行的处理。这个过程并不对程序的源代码语法进行解析,但它会把源代码分割或处理成为特定的符号为下一步的编译做准备工作。
1.1 文件包含指令(#include)
1.1.1 文件包含处理
“文件包含处理”是指一个源文件可以将另外一个文件的全部内容包含进来。C语言提供了#include命令用来实现“文件包含”的操作。
1.1.2 #incude<> 和 #include"" 区别
(1)"" 表示系统先在file1.c所在的当前目录找file1.h,如果找不到,再按系统指定的目录检索。
(2)< > 表示系统直接按系统指定的目录检索。
1.1.3 注意:
1. #include <>常用于包含库函数的头文件;
2. #include ""常用于包含自定义的头文件;
3. 理论上#include可以包含任意格式的文件(.c .h等) ,但一般用于头文件的包含;
2.宏定义
2.1 无参数的宏定义(宏常量)
如果在程序中大量使用到了100这个值,那么为了方便管理,我们可以将其定义为:
const int num = 100;
但是如果我们使用num定义一个数组,在不支持c99标准的编译器上是不支持的,因为num不是一个编译器常量,如果想得到了一个编译器常量,那么可以使用:
#define num 100
在编译预处理时,将程序中在该语句以后出现的所有的num都用100代替。这种方法使用户能以一个简单的名字代替一个长的字符串,在预编译时将宏名替换成字符串的过程称为“宏展开”。宏定义,只在宏定义的文件中起作用。
#define PI 3.1415
void test(){
double r = 10.0;
double s = PI * r * r;
printf("s = %lf\n", s);
}
2.2 注意事项:
-
宏名一般用大写,以便于与变量区别;
-
宏定义可以是常数、表达式等;
-
宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错;
-
宏定义不是C语言,不在行末加分号;
-
宏名有效范围为从定义到本源文件结束;
-
可以用#undef命令终止宏定义的作用域;
-
在宏定义中,可以引用已定义的宏名;
2.3 带参数的宏定义(宏函数)
在项目中,经常把一些短小而又频繁使用的函数写成宏函数,这是由于宏函数没有普通函数参数压栈、跳转、返回等的开销,可以调高程序的效率。
宏通过使用参数,可以创建外形和作用都与函数类似地类函数宏(function-like macro). 宏的参数也用圆括号括起来。
#define SUM(x,y) (( x )+( y ))
void test(){
//仅仅只是做文本替换 下例替换为 int ret = ((10)+(20));
//不进行计算
int ret = SUM(10, 20);
printf("ret:%d\n",</