编译预处理
(一)、程序形成过程:预处理---->编译---->汇编---->链接
(二)、预处理阶段
1、过程:1>头文件展开 2>宏替换 3>条件编译注:在程序中凡是有#开头的都属于预处理阶段
2、<>与“ ”的区别
系统的头文件目录为:/usr/include,<>的含义为指定头文件的搜索路径为系统的头文件目录:/usr/include,而“ ”是在当前的目录找,找不到再去系统的头文件中找。
一般来说,自己写的头文件用“ ”,系统的头文件用<>
3、宏定义:
1、如int a[3],当中的3为幻数,因为可读性差,要杜绝幻术可以使用宏定义:#define MAX_SIZE 3。
2、使用宏定义的注意事项:
1>宏定义无分号 2>宏定义要体现它的意义 3>宏定义要大写 4>宏定义不要以双下划线开头(不与系统的宏冲突)
3、宏函数:
例:
#define MAX(a,b) a > b ? a : b
int max = MAX(5 * 3,6 + 7);
这样替换的结果可能会出错,可以这样
#define MAX(a,b) (a) > (b) ? (a) : (b)
4、定义函数和宏函数的区别
1>宏定义在预处理阶段就完成,而函数需要经历四个阶段
2>宏定义不分配内存空间,定义函数需要分配内存空间
3>宏定义制作傻瓜式替换,而自定义比较复杂
4>
5、什么时候用宏函数什么时候用自定义函数
简短而且频率频繁调用的函数用宏函数
6、编译时间、执行时间
宏函数编译时间长:以编译时间换内存空间
一内存空间换执行时间的例子:内嵌函数
inline int main(int a)
{
return a > b ? a : b;
}
如果max调用连续四次,inline会把实践部分加载到函数调用处,占用了内存空间,但提高执行时间。(C99标准)
7、宏的使用技巧:
1>printf("%d\n",__LINE__); 打印行号
2>printf("%s:%d\n",__func__,__LINE__);
打印所在行号并且打印其所在函数,此函数可用来调试段错误。
3>其他系统宏:__TIME__:显示时间 __DATE__:显示日期
8、条件编译
1、例子:
int main()
{
#ifdef MAX //如果定义了MAX这个宏,则
printf("a");
#else //否则
printf("b");
#endif //结束
}
注释:
#if 0
#endif
2、如果a.h中有func1.h且里面定义了a = 5;func1.h中有a.h且定义的吧= 5;那么在mian中引用a.h与fun1.c头文件展开时会出现重复定义
如果在fun1.h中加:
#ifdef A_H
#define A_H
int a = 5;
#endif
加了的作用是放置头文件重复包含带来的重复定义