本文主要是介绍C语言--连接器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
连接
概述
一个 C
程序可能是由多个分别编译的部分组成,这些不同部分通过一个通常叫做连接器的程序合并成一个整体。
什么是连接器
C
语言中的一个重要思想就是分别编译,即若干个源程序可以在不同的时候单独进行编译,然后在恰当的时候整合在一起。但是连接器一般是与 C
编译器分离的,它不可能了解 C
语言的诸多细节。尽管连接器并不理解 C
语言,然而它却能够理解机器语言和内存布局。编译器的责任就是把 C
源程序 翻译
成对连接器有意义的形式,这样连接器就能够 读懂
C
源程序了。
典型的连接器把由编译器或汇编器生成的若干个目标模块,整合成一个被称为载入模块或可执行文件的实体,该实体能够被操作系统直接执行。其中,目标模块是直接作为输入提供给连接器的;而另外一些目标模块则是根据连接过程的需要,从包括类似 printf
函数的库文件中取得的。
连接器的输入时一组目标模块和库文件,连接器的输出时一个载入模块。连接器读入目标模块和库文件,同时生成载入模块。对每个目标模块中的每个外部对象,连机器都要检查载入模块,看是否已有同名的外部对象。如果没有,连接器就将该外部对象添加到载入模块中;如果有,连接器就要开始处理命名冲突。
声明与定义
这是定义
int a;
这是声明
extern int a;
每个外部变量之定义一次
命名冲突与 static
修饰符
两个具有相同名称的外部对象实际上代表的是同一个对象,即使编程者的本意并非如此,但系统却会如此处理,static
修饰符是一个能够减少此类命名冲突的有用工具。
static
修饰符不仅适用于变量,也适用于函数。
检查外部类型
假定有一个 C
程序,它由两个源文件组成。一个文件中包含外部变量 a
的声明
extern int n;
另一个文件中包含外部变量 n
的定义
long n;
假定两个语句都不在任何一个函数体内,因此 c
是外部变量。
这是一个无效的 C
程序,因为同一个外部变量在两个不同的文件中被声明为不同的类型,因此,保证一个特定名称的所有外部定义在每个目标模块中都有相同的类型,一般来说是程序猿的责任,而且,相同的类型
应该是严格意义上的相同。例如下面的程序
在一个文件中包含定义:
char filename[] = "hello tyustli";
在另一个文件中包含声明:
extern char *filename;
在第一个文件中 filename
是一个字符数组的名称,而不是字符指针,在第二个文件中 filename
是一个指针,这两个对 filename
的声明使用存储空间的方式是不同的,他们无法以一种合乎情理的方式共存。
要更正上例改法如下:
char filename[] = "hello world"; /* 文件1 */
extern char filename[]; /* 文件2 */
或者:
char *filename = "hello world"; /* 文件1 */
extern char *filename; /* 文件2 */
关于外部类型,C
语言规则是如果一个未声明的标识符后跟一个开括号,那么它将被视为一个返回整型的函数。
头文件
在 file.h
中包含声明
extern char filename[];
需要用到外部变量 filename
的每个 C
源文件都应该加上这样一个语句:
#include "file.h"
最后在一个源文件 file.c
中,给出 filename
的初始值
#include "file.h"
char filename[] = "hello world";
特别需要指出的是,定义该外部对象的模块也应该包含这个头文件。
这篇关于C语言--连接器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!