发布时间:2023-07-25 09:00
再一次回顾C语言的关键基础知识,今天带大家深刻的剖析一下C语言的预处理、编译(汇编)和链接的过程,以加深对C语言及编程本质的理解!
学习C语言首先要理解的就是如何将程序员输入的源代码一步步转换成计算机可执行的指令去执行?C语言在这一过程中充当什么角色?我们要做的都有哪些工作?
这里提到几个概念,即:预处理、编译、汇编、链接。
简言之:通过C语言编写的.c程序需经过上述几个过程才能将源代码转换为计算机可以识别的机器语言(0和1)并生成可执行文件来执行。
众所周知,C语言是速度最快的编译型语言。区别于面向图形界面的编程语言,使用C语言主要分以下7个步骤:
当程序员编写完代码后,需要通过编译器和链接器来将源代码转换为可执行代码程序。C编译器除了负责把C代码翻译成特定的机器语言外,也会检查C语言程序是否有效,还负责将源代码与C库的代码通过链接器合并最终形成可执行程序文件。在大多数系统中,编译器运行链接器。
具体来说,上述各个环节在编译过程中的原理机制如下:
预处理也称为预编译,在编译过程中主要会将源代码中定义的头文件展开、宏定义进行替换、去掉注释、执行条件编译等前期处理工作,通过预处理可以提高编译效率。
预处理完成后,在对源代码进行编译时,编译器主要负责检测输入的源代码语法,并将其生成汇编指令(中间文件)。
汇编在编译过程主要负责将汇编指令代码转换为机器语言(二进制0和1)。
注:汇编过程通常由编译器执行,不会出错,所以往往忽略,因为对于高级语言开发者来说,汇编基本上很少或不使用,了解即可。但对于研究底层的程序员,汇编语言还是有必要学习的。
链接过程是指通过链接器把编译器编译生成的汇编等中间代码和系统的标准启动代码以及库代码这3部分合并成一个文件,即可执行文件。
通过C语言编程的内部机制和流程如下图所示:
预处理可以简单理解为代码中预处理指令的展开。
常见的预处理指令如下表:
还有下列几种预处理宏:
__LINE__表示正在编译的文件的行号
__FILE__表示正在编译的文件的名字
__DATE__表示编译时刻的日期字符串,例如: “25 Dec 2007”
__TIME__表示编译时刻的时间字符串,例如: “12:30:55”
__ STDC __ 判断该文件是不是定义成标准 C 程序
对于宏定义,和函数相比有有点也有缺点,比如宏定义可以提高代码的复用性,提高编译速度。但缺点是不可调式(因为预处理阶段即进行了展开替换),无安全类型检查,容易出错,在代码中可读性差。建议不要用宏去写函数,可以用宏定义来替代路径、针对编译器版本不兼容报错定义、条件编译等;
对于#include预处理,后面是<>则代表预处理系统路径下的头文件,后面是" "的则代表预处理我们自己定义的或第三方的头文件;
对于#error预处理,是指在编译程序时只要遇到#error就会生成一个编译错误提示信息并停止编译;
对于#line预处理,是指改变当前行数和文件名称,未使用过;
对于#lpragma预处理,用于指示编译器完成一些特定动作。用到较多的有#pragma once,这个主要是为了防止头文件被多次包含。
通常我们说编译器把源代码转换为可执行代码程序,但编译的细节则取决于编程的环境。总之,通过编译即可得到机器能够识别的机器语言指令,并在机器上成功执行。
对于高级语言程序员来说,无需学习编译的底层知识(如汇编等),只需知道C语言通过编译器来检查源C代码语法,并将其生成汇编等中间代码文件即可。
注:至于汇编语言,对于不搞底层的程序员暂时不需要深入学习,当然若能学习更好,有助于编程的更进一步理解。
链接是指将编译得到的中间文件以及必要的系统标准启动代码和所涉及的库代码进行合并,生成可执行文件的过程。而链接可分为静态链接和动态链接。
静态链接是由链接器在链接时将库的内容加入到可执行程序中的做法。链接器是一个独立程序,将一个或多个库或目标文件 (先前由编译器或汇编器生成)链接到一块生成可执行程序。静态链接是指把要调用的函数或者过程链接到可执行文件中,成 为可执行文件的一部分。
动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往 是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接 关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。
将源文件中用到的库函数与汇编生成的目标文件.o合并生成可执行文件。该可执行文件会变大很多,一般是调用自己电脑上的。静态库和应用程序编译在一起,在任何情况下都能运行,而动态库是动态链接,文件生效时才会调用。 很多代码编译通过,链接失败就极有可能在静态库和动态库这出现了纰漏,要视情况解决。缺少相关所需文件,就会链接报 错。这个时候就要检查下本地的链接库是不是缺损。
很多小伙伴在初次接触C语言的学习时,不知道使用什么环境和工具来学习,下面简单介绍一下。
由于C语言与UNIX关系密切,所以UNIX系统和Linux系统都会自带C编译器,可直接使用命令行来实现编程、编译及运行等一系列操作,至于用到的具体工具我会在后续陆续讲解,也可自行百度,网上教程满天飞。
对于Windows或Mac系统,可以使用集成式开发环境进行编程。许多供应商都会提供一个包含各种新建、编写、编译、链接、运行、保存等集于一体的工具软件,简称IDE。例如微软的Visual Studio,苹果自家的Xcode等,都支持C语言的快速开发。当然,很多IDE目前既有Win版本也有Mac版本,可供的选择很多。
对于计算机专业及从事相关软件开发的人员,博主建议从命令行自己搭建环境开始学起,这样既能锻炼自己的码字能力,又能加深对编程的理解;对于想要快速开发一个既定系统或已知目标的软件或者是其他行业涉及到相关C语言编程的,可以使用IDE来快速完成自己的项目功能。
提示:仅代表个人观点,因为博主大学是机电机器人专业的,当初没有太多的时间允许学习、探讨底层的环境搭建,也是从IDE接触编程的。后来看到很多大佬用命令行编程,才逐渐开始转而命令行的学习。。具体应根据自己的实际情况而定,若时间充裕,建议最好多学习多了解多见识一下!
本文部分素材来源于网络及书籍《C primer plus》,如有不妥请告知及时修改!
【预告】下一篇更新C语言的语法、数据类型、关键字和逻辑结构。