宏和函数的区别以及C语言的编译链接过程

来源:互联网 发布:淘宝女装店铺公告图片 编辑:程序博客网 时间:2024/05/17 23:42

宏和函数的区别大致可分为以下五点:

1、宏是完全替换,插入到程序中,会增加代码的长度; 而函数代码是只出现在一个地方,使用时调用即可。


2、宏的执行速度相比函数更快一些,因为在预编译阶段都已完成;函数则因为需要调用以及返回而需要额外时间。 
 
3、宏有时因为操作符优先级问题会导致计算逻辑出错; 而函数会将值返回。
 
4、参数求值时,宏每次使用都要进行运算;而函数只需要计算一次,之后多次调用不会导致求值出错。
 
5、宏不关心参数类型,只要参数操作合法即可; 而函数类型则要一致,不同类型需要不同函数。

C语言的编译链接过程:
我们所编辑的C语言程序是不能直接放到机器上运行的,它只不过是一个带".c"后缀的文件即源代码,需要经过一定的处理才能转换成机器上可运行的可执行文件。我们将对C语言的这种处理过程称为编译与链接。

编译就是把文本形式源代码翻译为机器语言形式的目标文件过程。

链接是把目标文件、操作系统的启动代码和用到的库文件进行组织最终形成可执行代码的过程。

编译是读取源程序,对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程主要包含两个阶段:

第一个阶段是:预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置的文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,他把文件的内容添加到.c文件中。这个在编译之前修改源文件的方式提供了很大的灵活性,以适应不同的计算机和操作系统环境的限制。一个环境所需要的可执行代码跟另一个环境所需要的可执行代码可能有所不同,因为可用的硬件体系结构和操作系统不同所致。在许多情况下(特别是在嵌入式开发中),可以把用于不同环境的代码放在同一个文件中,再在预处理阶段修改代码,使之适应环境。

预处理阶段主要是以下几方面的处理:

(1)、宏定义指令,如#define M 9;

(2)、条件编译指令,如#ifdef、 #ifndef、#else、#elif、#endif等;

(3)、头文件包含指令,如#include;

(4)、特殊符号,预编译程序可以识别一些特殊的符号。

预编译程序所完成的基本上是对源程序的"替换"工作。经过此替换后,生成一个没有宏定义、没有条件编译指令、没有特殊符号的输出文件。这个文件的含义同没有经过预处理的源文件是相同的,但内容有所不同。下一步,此输出文件将作为编译程序的输出而被翻译成为机器指令。

第二个阶段是:编译、优化,经过预编译得到的输出文件中只有常量,一般都是一些指令。

编译程序所要做的工作就是通过词法分析和语法分析,在确认所有指令都是符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码。

汇编实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。目标文件由段组成。通常一个目标文件中至少有两个段:代码段和数据段;

代码段:该段中所包含的主要是程序的指令。该段一般是可读和可执行的,但一般却不可写。
数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。

链接过程是由汇编程序生成的目标文件并不能立即就被执行,其中可能还有许多没有解决的问题。 例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。所有的这些问题,都需要经链接程序的处理方能得以解决。
链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够按操作系统装入执行的统一整体。



0 0