C语言预处理

由源码到可执行的程序
源码-》(编译)-》elf可执行程序
源码-》(编译)-》目标文件.o-》(链接)-》elf可执行程序
源码-》(编译)-》汇编文件.s-》(汇编)-》目标文件.o-》(链接)-》elf可执行程序
源码-》预处理-》预处理过的.i文件-》(编译)-》汇编文件.s-》(汇编)-》目标文件.o-》(链接)-》elf可执行程序//这才是真正的C语言

预处理:用的预处理器
编译:用编译器
汇编:汇编器
链接:用链接器
其它可用的工具
合起来就编译工具链
gcc就是一个编译工具链

预处理的意义:
1.编译器本身的主要目的是编译源代码,将C的源代码转换成.s汇编代码。
编译器聚焦核心功能后,就剥离出一些非核心的功能到预处理去了。
2.预处理帮编译器做一些编译前的杂事

编译中常见的预处理:
1.#include
2.#pragma
3.注释
4.#if #eif #endif #ifdef #undef(条件编译,不是常用if,else)
5.宏定义

只编译不链接:
1.gcc编译时可以给一些参数来做一些设置,譬如

总结:预处理过程:
1.预处理的东西不见了(define,include等),说明编译器根本不知道include,define
例如:
define pachar char*
typedef char* PCHAR

int main()
{
pchar p3;
pchar p1,p2;
return 0;
}

预处理以后:
typedef char* PCHAR

int main()
{
char* p3;
char* p1,p2;
return 0;
}

预处理实战:
1.头文件
#include<>和”“的区别
<>一般用于包含系统提供的头文件(系统自带的,不是程序员写的),只会找系统制定目录(当前编译器配置的或者当前操作系统配置的,当然也可以添加路径),
如果找不到就提示不存在。(如果专门有个路径集中存放头文件,那么也使用<>)
”“一般包含的是自己写的头文件,编译器会默认会先在当前目录下寻找相应的头文件,如果没有找到再到系统目录,如果找不到就提示不存在。

头文件的本质:
就是将头文件.h里面的内容原封不动的放到.i文件(预处理过后的文件),也是将.h的内容方到相应的include位置(当然有先后顺序)

注释:
给人看的,不是给编译器看的,编译器不看注释,那么在预处理阶段预处理器就会拿掉程序中所有的注释。到编译器阶段程序已经没有注释了。注释变成空格了

条件编译:
就是一个配置开关

宏定义:
本质就是替换,当作字符串替换
分为3部分
#define M 1 0(10之间有空格)
1.#define 2.M 3.1 0

带参宏
#define X(a,b) a+b

关键,当一个数字直接出现时,默认为int

函数和宏定义处理期间
1.宏定义在预处理期间,在调用宏的地方展开,没有调用开销,而函数有,跳转执行再返回。在函数体很短的时候可以用宏定义代替。
2.函数在调用函数处跳转到函数中去执行。

带参宏和带参函数的一个重要差别:
1.宏定义不会检查参数的类型,返回值也不会附带类型,而函数有。

既然宏定义和函数各有优缺点,那怎么结合这两个的有点呢:
使用内联函数inline关键字
1.具有静态类型检测。
2.具有函数调用位置展开。
几乎可以这样认为,内联函数就是带了参数静态类型检查的宏。
什么时候使用内联函数,当我们函数体很短(譬如一两句话),又希望有静态类型检查的,就可以使用。

debug版本和release版本的区别就是debug版本有很多宏定义做为额外的辅助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值