简要理解c语言程序编译和链接

引言

通常在我们写好c程序后,使用编译器直接编译运行即可,但是就像如此简单的一句程序gcc test.c同样有其深入复杂的原理,深入理解他们有助于我们更好的理解程序编译执行的过程。通常,这过程细分共有四步,预编译(又叫预处理),编译,汇编,链接。即正常本来是编译和执行,但编译部分又被分为了预编译,编译,汇编三部分。同时编译进行的环境我们叫做翻译环境,执行文件在电脑上的环境称作执环境,现在让我们细节的简要直白展示一下编译的过程。(想要了解更多相关知识可以参考《程序员的自我修养一书》)

一 预编译

我们写c语言程序的时候,不知道大家想过那些以#号开头的指令如何发挥作用嘛,预编译就是主要用来处理源文件中的以“#”开头的预编译指令,他将源文件及相关的头文件预编译为一个.i文件,相当如下命令:

gcc -E hello.c -o hello.i

有如下处理规则:

1.将所有的“#define”删除,并且展开所有的宏定义

2.处理所有条件预编译指令,比如“#if,#ifdef,#elif,#else,#endif”

3.处理“#include预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,即包含的文件可能还含有其他文件。

4.添加行号和文件名标识,比如#2“helloo.c"2,以便于编译时编译器产生调试用的行号信息及用于编译时残生编译错误被警号时能够显示行号。

5.保留所有#pragram编译器指令,因为编译器要使用他们。

经过预编译后的.i文件不包含任何宏定义,因为所有的宏以及被展开,并且包含的文件也以及被插入到.i文件中,所以当我们无法判断宏定义是否正确或头文件包含是否正确时,可以查看预编译后的文件来确定问题。

二 编译

编译过程就是将预处理完的文件进行一系列词法分析,语法分析,语义分析及优化生成后的汇编代码文件,可以理解为将c语言代码翻译为汇编代码,这个过程较为复杂繁琐,此处简要介绍,具体可以参考《程序员的自我修养》一书,总归而言,该过程相当于指令:

gcc -S hello.c -o hello.s

接下来介绍三个主要步骤

2.1,词法分析

例如,假设有这么一段代码

array[index] = (index+4)*(2+6);

那么编译的时候会怎么做呢,首先该源代码程序被输入扫描器,扫描器的任务就是进行简单的词法分析,把代码中的字符分割成一系列的记号(关键字,标识符,字面量,特殊字符等)。

2.2 语法分析

接下来语法分析器(Grammar Parser)将对由扫描器产生的记号进行语法分析,从而产生语法树(Syntax Tree)。整个分析过程采用了上下文无关语法(Context-free Grammar)的分析手段,如果你对上下文无关语法及下推自动机很熟悉,那么应该很好理解。否则,可以参考一些计算理论的资料,一般都会有很详细的介绍。此处不再赘述。简单地讲,由语法分析器生成的语法树就是以表达式(Expression)为节点的树。我们知道,C语言的一个语句是一个表达式,而复杂的语句是很多表达式的组合。上面例子中的语句就是一个由赋值表达式、加法表达式、乘法表达式、数组表达式、括号表达式组成的复杂语句。它在经过语法分析器以后形成如图所示的语法树。

2.3 语义分析

(转自自我修养一书,该段已经介绍的非常清晰了)

接下来进行的是语义分析,由语义分析器(Semantic Analyzer)来完成。语法分析仅仅是完成了对表达式的语法层面的分析,但是它并不了解这个语句是否真正有意义。比如C语言里面两个指针做乘法运算是没有意义的,但是这个语句在语法上是合法的;比如同样一个指针和一个浮点数做乘法运算是否合法等。编译器所能分析的语义是静态语义(StaticSemantic),所谓静态语义是指在编译期可以确定的语义,与之对应的动态语义(DynamicSemantic)就是只有在运行期才能确定的语义。
静态语义通常包括声明和类型的匹配,类型的转换。比如当一个浮点型的表达式赋值给一个整型的表达式时,其中隐含了一个浮点型到整型转换的过程,语义分析过程中需要完成这个步骤。比如将一个浮点型赋值给一个指针的时候,语义分析程序会发现这个类型不匹配,编译器将会报错。动态语义一般指在运行期出现的语义相关的问题,比如将0作为除数是一个运行期语义错误。
经过语义分析阶段以后,整个语法树的表达式都被标识了类型,如果有些类型需要做隐式转换,语义分析程序会在语法树中插入相应的转换节点。上面描述的语法树在经过语义分析阶段以后成为如图2-4所示的形式。

三 汇编

汇编通过汇编器完成,而汇编器则将汇编代码转化为机器可执行的指令,每一个汇编语句几乎都对应着一个机器指令。就是根据汇编指令和机器指令的对照表一一进行翻译,也不做指令优化。

汇编的指令:

gcc -c test.s -o test.o

以.o为结尾的文件叫做目标文件。

四 链接

链接是一个复杂的过程,链接的时候需要把一堆文件链接在一起才生成可执行程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。
链接解决的是一个项目中多文件、多模块之间互相调用的问题。

这个过程同时依托多个动作执行,即编译过程中实现的符号汇总,汇编过程中实现的符号表的建立,此后在链接步骤时进行符号决议和重定位。更加具体的内容可查阅相关资料。

最后,总体过程如下:


 

  • 37
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《C语言程序设计(第4版)》是由何钦铭编写的一本关于C语言程序设计的教材。该教材是针对C语言初学者而设计的,旨在帮助读者系统地学习C语言的基础知识和程序设计技巧。 该教材的特点有以下几个方面: 首先,教材内容全面且深入。从C语言的基本概念、语法结构开始,逐渐引入函数、数组、指针、结构体、文件操作等更高级的知识点,最后以编程案例进行实践应用。 其次,教材结构清晰,逻辑有序。每个章节都以特定的主题为中心,从浅入深地讲解相关知识,通过大量的实例演示和练习,有助于读者理解和掌握所学内容。 再次,教材充实了许多实例和习题。通过对各种实例的讲解和实际编写,读者可以更好地理解C语言的应用技巧,并提高自己编程的能力。 最后,教材注重实践和项目开发。每个章节都提供了一些实际项目的例子,从简单到复杂,让读者逐步了解如何使用C语言进行实际开发,培养实际应用能力。 总的来说,《C语言程序设计(第4版)》是一本权威的、全面而深入的C语言教材,适合用于高校的计算机相关专业教学和自学。通过学习该教材,读者可以系统地掌握C语言的基础知识和实践技巧,为进一步学习和应用C语言打下坚实的基础。 ### 回答2: 《C语言程序设计(第四版)》是何钦铭所著的一本经典教材,适用于C语言的初学者和进阶者。本书内容全面,深入浅出地介绍了C语言的基本概念、语法规则以及常用的程序设计方法。以下是对该书的简要回答: 该书首先介绍了C语言的基本概念,包括变量、数据类型、运算符等。通过清晰的解释和丰富的示例代码,读者可以很容易理解这些概念,并能够灵活运用于实际编程中。 接着,书中详细讲解了控制流语句,如if语句、循环语句等,以及数组、指针等重要的数据结构。通过实例的演示,读者将学会如何使用这些语句和数据结构来解决实际问题,进一步提升编程能力。 此外,该书还介绍了函数、文件操作、字符串处理等重要的C语言编程技巧。这些内容对于提高代码的复用性、程序的健壮性和性能优化都非常重要。通过学习本书,读者将能够掌握这些技巧,写出高效、可靠的C语言程序。 与其他教材相比,该书的优势在于内容全面、条理清晰、语言通俗易懂。而且,书中附有大量的习题和实例,读者可以通过实践来加深对知识的理解和掌握。 总的来说,《C语言程序设计(第四版)》是一本适合C语言初学者和进阶者的教材,可以帮助读者快速入门,并扎实掌握C语言的基本知识和编程技巧。无论是作为学习教材还是作为参考书籍,都具有很高的实用价值。 ### 回答3: 《C语言程序设计》是由何钦铭编写的一本经典教材,常用来作为C语言课程教材。该书的第四版是根据C语言的最新标准进行了更新和改进,内容更加全面、深入和具体。 《C语言程序设计》第四版的PDF版本是该教材的电子版,可以在电脑、平板电脑或手机等电子设备上阅读学习。相比于纸质书籍,PDF版本具有便携性和可搜索性的优点,方便学生在任何时间和地点学习和查阅相关内容。 《C语言程序设计》第四版的PDF版本包含了该教材的全部内容,包括C语言的基本语法、数据类型、运算符、流程控制、函数、指针、数组、字符串、结构体、文件操作等知识点。每个知识点都配有详细的解释、示例代码和练习题,帮助学生深入理解和掌握C语言的编程技巧和方法。 使用《C语言程序设计》第四版的PDF版本,可以根据自己的学习进度和需要,自主选择学习的章节和顺序。同时,PDF版本还允许用户进行标注和书签的功能,方便学生进行重点内容的标记和复习。 总之,《C语言程序设计》何钦铭第四版PDF是一本优秀的学习工具,对于初学者和希望提高编程能力的人来说,都是一本不可或缺的参考书。通过系统地学习和实践,可以帮助读者逐步掌握C语言编程的基本原理和技巧,为以后深入学习和应用其他编程语言打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值