4.链接
- 什么是连接器
- C语言可能是由多个分别编译的部分组成,这些不同部分通过一个通常叫做连接器的程序合并成一个整体
- 编译器一般每次只能处理一个文件,所以它不能检测出哪些需要一次了解多个源程序文件才能察觉的错误
- 连接器能够理解机械语言和内存布局
- 典型的连接器是把编译器或汇编器生成的若干个目标模块,整合成被称位载入模块或可执行文件的实体,该实体能够被操作系统直接执行。其中某些目标模块是直接作为输入提供给连接器的。而另外一些目标模块则是根据连接过程的需要,从包括有类型printf函数的库文件中取得的
- 连接器通常把目标模块看成是由一组外部对象组成的。每个外部对象代表着机器内存中的某个部分,通过一个外部名称来识别。因此程序中的每个函数和每个外部变量,如果没有被声明为static就都是一个外部对象
- 某些编译器会对静态函数和静态变量的名称做一定改变,将它们作为外部对象,因为经过了名称修饰,所以不会与其他的源程序文件中的同名函数或同名变量发生命名冲突。
- 大多数的连接器都禁止同一个载入模块中的两个不同外部对象拥有相同名称。连接器的一个主要工作就是处理这类的命名冲突问题
- 声明与定义
- int a;
- 全局声明的情况下,说明了a就是一个外部整型变量,同时为a分配存储空间,因为外部对象a并没有被明确指定任何初始值,所以他的初始值默认为0,(某些系统中连接器对以其他语言编写的程序并不保证这一点)
- int a = 7;
- 定义a同时也给a明确指定了初始值。
- extren int a;
- 这个语句并不是对a的定义,但是仍然说明了a是一个外部整型变量。显示地说明了a的存储空间是再程序的其他地方分配的。
- 从连接器的角度来看,上述声明是对外部变量a的引用,而不是对a的定义。
- 这种形式的声明是对一个外部对象的显示引用,即使它出现在一个函数的内部,也仍然具有相同的涵义。
- 命名冲突与static修饰符
- static int a;和int a ;含义相同把a的作用域限定在一个源文件内,对其他的源文件 a是不可见的
- 如果若干个函数需要共享一组外部对象,可以将这些函数放到一个源文件中,把它们需要用到的对象,也都在同—个源文件中以static修饰符声明
- 形参、实参与返回值
- 任何的C函数都有一个函数列表,列表中的每个参数都是一个变量。改变量在函数调用过程中被初始化
- 形参列表允许为空
- 函数调用时,调用方将实参列表传递给被调函数
- 任何一个C函数都有一个返回类型,要不就是void要么是函数生成的结果类型
- 依赖于调用者能够提供数目正确且类型恰当的实参查外部类型
- 保证一个特定名称的所有外部定义在每个目标模块中都有相同的类型应该是严格意义上的相同
- 头文件
- 每一个外部变量只在一个地方声明,这个声明的地方一般就在一个头文件中,需要用到该外部的所有模块都应该包括这个头文件。
- 推荐一个零声学院免费教程,个人觉得老师讲得不错, 服务器课程