<1>预处理的意义(1)编译器本身的主要目的是编译源代码,将C的源代码转化成.S的汇编代码。编译器聚焦核心功能后,就剥离出了一些非核心的功能到预处理器去了。
(2)预处理器帮编译器做一些编译前的杂事。如:(1)#include(#include <>和#include ""的区别)
(2)注释
(3)#if #elif #endif#ifdef
(4)宏定义
备注: gcc中只预处理不编译的方法 -o生成可执行文件名 -c只编译不链接 -E 只预处理不编译 -I ( 是大i,不是L )编译时从某个路径下寻找头文件 . /当前
(1)gcc编译时可以给一些参数来做一些设置,譬如gcc xx.c -o xx可以指定可执行程序的名称;譬如gcc xx.c -c -o xx.o可以指定只编译不连接,也可以生成.o的目标文件。
(2)gcc -E xx.c -o xx.i可以实现只预处理不编译。一般情况下没必要只预处理不编译,但有时候这种技巧可以用来帮助我们研究预处理过程,帮助debug程序。
(3)链接器:链接的时候是把目标文件(二进制)通过有序的排列组合起来,如 star.s main.c led.c 这三个源文件,分别被编译成三个目标文件 ,每个目标文件有很多函数集合。链接的时候会根据运行思路把这些杂乱的函数
给排列组合起来,不是把目标文件简单的排列组合。
(4)当生成可执行程序之后,这个可执行程序里面有很多符号信息,有个符号表,里面的符号与一个地址相对应,如 函数名max对应一个地址,虽然这个程序有符号信息,但是为什么还是可以执行呢?因为如windows的exe程序,
有专门的一套程序来执行这个.exe 文件,就好比压缩文件,就有一套 “好压”的软件,然后去压缩(执行).rar .zip的文件,而这套程序就把这些符号信息给过滤掉,然后得到纯净的二进制代码,最后把他们加载到内存中去。
(5) debug版本就是有符号信息,而Release版本就是纯净版本的。可用strip工具: strip是把可执行程序中的符号信息给拿掉,以节省空间。(Debug版本和Release版本)objcopy:由可执行程序生成可烧录的镜像bin文件。
6.2、预处理:<1>头文件有”“是本目录去找,找不到就去库头文件找,和< > 只到库头文件去找,库头文件可以自己制作,用 -I ( 是大i,不是L )参数去寻找路径。
头文件在预处理时,会把文件的内容原封不动的赋值到 c 文件里面。
<2>注释:在预处理时,把注释全部拿掉。 注意:#define zf 1 再判断 #undef zf 2 时,也是通过的。其意思是有没有定义过zf.
<3>条件编译:当作一个配置开关 #define NUM 表示定义了NUM,则执行下一条语句,且NUM用空格替代,而且预处理会删掉条件编译,留下正确的执行语句。
<4>宏定义:#define cdw 1 在预处理阶段,会替代那些宏,可以多重替代宏;也可以表示多个语句,如 #define cdw printf("cdw\n") ; printf("zf\n"); cdw;这条语句会直接展开
还有带参宏,#define max(a,b) ((a)+(b)) 注意的是带参宏一定要( ) 不然有时候会引起错误,每一个”形参“都应该要();
#define year (365*24*60*60*60*60 ) 安理说是可以的,但是year是int型的已经超过了范围,所以要把它搞成无符号长整形。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33816-9.html
让所谓盟国有底气来对抗中国