1、由源码到可执行程序的过程
(1)源码.c->(编译)->elf可执行程序
(2)源码.c->(编译)->目标文件.o->(链接)->elf可执行程序
(3)源码.c->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序
(4)源码.c->(预处理)->预处理过的.i源文件->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序
预处理是将原本的C文件进行处理,将宏展开。头文件展开。形成预处理过的.i源文件本质也是c语言文件。
2、编程中常见的预处理
(1)#include(#include <>和#include ""的区别)
(2)注释
(3)#if #elif #endif #ifdef
(4)宏定义
#include(#include <>和#include ""的区别)
<>只会去系统默认的文件夹寻找头文件,""会首先寻找当前文件夹,然后去系统默认文件夹寻找。
预处理过程中会将头文件原地展开。
abc.c文件
#include"abc.h" int main() {
func(); return 0; }
abc.h文件
typedef unsigned char uchar uchar fun();
执行 gcc -E abc.c -o abc.i
abc.i文件
typedef unsigned char uchar uchar fun(); int main() { func(); return 0; }
注释
在预处理后,注释不会出现在.i文件中
#if #elif #endif #ifdef 条件编译
.c文件
#include<stdio.h> #define LED
int main() {
#ifdef LED
·· printf("#ifdef ");
#else
aa=2;
c=aaa
dasdasdasd// 编译之前预处理时会将这种情况去掉,所以不抱错,
printf("#else "); #endif printf("main-1"); printf("main-2"); return 0; }
.i文件
/* ...... */ int main() { aa=1; printf("#ifdef "); printf("main-1"); printf("main-2"); return 0; }
预处理时,将不符合条件的代码取消。并不检查c语法问题。
宏定义
.c
#include<stdio.h> #define TEAR_S (365*24*60*60UL) int main() { printf("YEAR_S=%u ",TEAR_S); return 0; }
.i
... int main() { printf("YEAR_S=%u ", (365*24*60*60UL)); return 0; }
对于宏进行完全替换