一、编译流程
1.预处理
预编译--将代码中相关预处理命令执行,最后生产一个只包含C语言代码的文件
-E 只作预处理
2.编译
对语法进行检查,将C的源代码生成汇编代码
-S 编译成汇编语言程序
3.汇编
表示将汇编源代码最终生成机械代码
-c 只编译不连接,生成目标文件“.o”
4.连接
将使用到的其它代码链接到一起生成最终的可执行文件
二、预处理:作文本替换
1.宏定义
语法:#define 标识符 字符串
#define 宏名 宏值
注意:
(1)预处理命令都是以#开头的
(2)宏名命名规则和之前标识符命名规则一致,宏名一般都写为大写,以区别于普通变量
(3)预处理实际上是将宏名用宏值(预处理阶段的字符串)原样替换即文本替换,但是C语言中出现的“宏名”不会被替换
(4)应用:a.提高代码可读性
b.一改全改,方便代码修改
(5)宏名的作用域
2.#undef 宏名 :表示取消宏名的定义
只在预处理阶段发挥作用,作用范围为从定义处开始到#undef结束
eg:define N 10
含义:表示将来代码中出现的N都代表
10,即编写代码时可以使用N表示数字10
3.带参宏定义:
语法
#define 宏名(参数)宏值
eg:#define ADD(a,b) a+b
注意:
(1)带参宏和函数有本质区别
a.处理阶段不一样
宏定义----预处理阶段
函数-----编译阶段
b.使用不一样
宏--预处理阶段就使用结束了,宏的使用本质上是文本的原样替换,宏的参数只进行文本替换不进行语法检查
函数--调用时,进行使用;函数的使用班智商是函数代码的调用;函数的参数是有类型的编译阶段是要进行类型检查的
c.应用:一般对于一些短小代码,考虑写成带参宏(不超过5行的代码)
d.宏的副作用
处理:把能加括号的地方都加括号
e.宏定义必须写在一行,若在多行,需在每一行末尾加续航符“\”,且续航符后面不可以有空格
4.文件包含
#include <文件名>
#include "文件名"
<>与""的区别在于查找头文件的方式不一样
<> 到系统默认的路径寻找对应的头文件
"" 先到当前目录下寻找头文件,如果没有,再到系统默认路径下寻找
5.条件编译
条件编译命令形式
(1)#ifdef 标识符
程序段1
#else
程序段2
#endif
含义:如果定义了标识符,则预处理程序段1,即将程序段1的代码保留,否则保留程序段2
用途:调试代码;设计头文件
(2)#ifdef 标识符
程序段1
#endif
(3)#ifndef 标识符
程序段1
#else
程序段2
#endif
含义:如果没有定义了标识符,则预处理程序段1,即将程序段1的代码保留,否则保留程序段2
(4)#if 表达式
程序段1
#else
程序段2
#endif
含义:表达式为真处理程序段1,表达式为假处理程序段2
防止多次包含,带来重复定义的问题