文章目录一、编译1.预处理处理源文件中以#开头的预编译指令删除所有的注释添加行号和文件名标识以方便后续编译器生成调试信息保留所有的#pragma的编译器指令编译器后续会使⽤2.编译2.1词法分析2.2语法分析2.3语义分析3.汇编将汇编代码翻译成二进制的指令二、链接将各个单独编译好的目标二进制文件与链接库文件链接合并生成一个可执行程序在 ANSI C (C语言标准)的任何⼀种实现中存在两个不同的环境翻译环境-源代码在翻译环境中被转换为机器可执行的二进制指令由编译和链接两部分完成运行环境-源代码经过翻译环境转换成机器可执行的二进制指令后在运行环境中被执行下面我们讨论的是翻译环境即翻译环境中的编译和链接的过程一、编译编译分为预处理、编译、汇编3个过程编译过程中每一个文件都是分开单独各自处理的从最开始的源文件(与头文件)到最后编译好后的目标二进制文件源文件.c – 预编译代码.i – 汇编代码.s – 二进制目标文件.oUnix/Linux系统中目标文件格式.oWindows系统中.obj1.预处理源文件.c – 预编译代码.i(过程中处理的对象是源文件.c与头文件.h处理结束后生成预编译代码.i)处理源文件中以#开头的预编译指令1.将代码中用#define定义的文本代替内容还原为原信息并将#define定义语句代码删除2.处理所有的条件编译指令如 #if、#ifdef、#elif、#else、#endif3.将#include包含的头文件内容插入到文件中来删除所有的注释添加行号和文件名标识以方便后续编译器生成调试信息保留所有的#pragma的编译器指令编译器后续会使⽤2.编译预编译代码.i – 汇编代码.s将预处理后的文件进行词法分析、语法分析、语义分析2.1词法分析将代码内容视为字符内容以关键字、标识符、字面量、特殊字符4种记号将字符分割例如将上述代码视为字符内容以4种记号分割好后便得到了16个记号2.2语法分析将记号以表达式为关系块块联系在一起构成有理解意义的语法树2.3语义分析编译器对表达式进行语法层面的分析与检查例如此图中如果等号两边类型不相同语法层面有错编译器会报警告3.汇编汇编代码.s - 目标二进制文件.o将汇编代码翻译成二进制的指令二、链接将各个单独编译好的目标二进制文件与链接库文件链接合并生成一个可执行程序首先因为每个文件都是单独编译过来的创建内存空间时谁也没见过谁等到后面放在同一个程序里时难免会有内存地址共用冲突的问题编译器采取的做法是每一个文件都会生成它里面有关函数、全局变量的名称对应它的地址的符号表然后将所有的符号表进行合并与重定位下图中文件1与文件2会将其符号表进行合并发现Add有重复的要删掉重复的Add时经过符号决议选择删掉文件2的Add函数的地址实现了重定位得到有效的地址与空间分配然后再将合并好的符号表交给链接好的可执行程序里分配空间这样链接就实现了多文件合成可执行程序的同时保证了地址和空间的有效正确分配解决了一个项目中多文件、多模块之间互相调用的问题文件2中Add函数未找到其地址(即Add函数不在文件2中定义在别的文件里定义的)就会先将其地址置为空
【C语言】编译和链接
文章目录一、编译1.预处理处理源文件中以#开头的预编译指令删除所有的注释添加行号和文件名标识以方便后续编译器生成调试信息保留所有的#pragma的编译器指令编译器后续会使⽤2.编译2.1词法分析2.2语法分析2.3语义分析3.汇编将汇编代码翻译成二进制的指令二、链接将各个单独编译好的目标二进制文件与链接库文件链接合并生成一个可执行程序在 ANSI C (C语言标准)的任何⼀种实现中存在两个不同的环境翻译环境-源代码在翻译环境中被转换为机器可执行的二进制指令由编译和链接两部分完成运行环境-源代码经过翻译环境转换成机器可执行的二进制指令后在运行环境中被执行下面我们讨论的是翻译环境即翻译环境中的编译和链接的过程一、编译编译分为预处理、编译、汇编3个过程编译过程中每一个文件都是分开单独各自处理的从最开始的源文件(与头文件)到最后编译好后的目标二进制文件源文件.c – 预编译代码.i – 汇编代码.s – 二进制目标文件.oUnix/Linux系统中目标文件格式.oWindows系统中.obj1.预处理源文件.c – 预编译代码.i(过程中处理的对象是源文件.c与头文件.h处理结束后生成预编译代码.i)处理源文件中以#开头的预编译指令1.将代码中用#define定义的文本代替内容还原为原信息并将#define定义语句代码删除2.处理所有的条件编译指令如 #if、#ifdef、#elif、#else、#endif3.将#include包含的头文件内容插入到文件中来删除所有的注释添加行号和文件名标识以方便后续编译器生成调试信息保留所有的#pragma的编译器指令编译器后续会使⽤2.编译预编译代码.i – 汇编代码.s将预处理后的文件进行词法分析、语法分析、语义分析2.1词法分析将代码内容视为字符内容以关键字、标识符、字面量、特殊字符4种记号将字符分割例如将上述代码视为字符内容以4种记号分割好后便得到了16个记号2.2语法分析将记号以表达式为关系块块联系在一起构成有理解意义的语法树2.3语义分析编译器对表达式进行语法层面的分析与检查例如此图中如果等号两边类型不相同语法层面有错编译器会报警告3.汇编汇编代码.s - 目标二进制文件.o将汇编代码翻译成二进制的指令二、链接将各个单独编译好的目标二进制文件与链接库文件链接合并生成一个可执行程序首先因为每个文件都是单独编译过来的创建内存空间时谁也没见过谁等到后面放在同一个程序里时难免会有内存地址共用冲突的问题编译器采取的做法是每一个文件都会生成它里面有关函数、全局变量的名称对应它的地址的符号表然后将所有的符号表进行合并与重定位下图中文件1与文件2会将其符号表进行合并发现Add有重复的要删掉重复的Add时经过符号决议选择删掉文件2的Add函数的地址实现了重定位得到有效的地址与空间分配然后再将合并好的符号表交给链接好的可执行程序里分配空间这样链接就实现了多文件合成可执行程序的同时保证了地址和空间的有效正确分配解决了一个项目中多文件、多模块之间互相调用的问题文件2中Add函数未找到其地址(即Add函数不在文件2中定义在别的文件里定义的)就会先将其地址置为空