深入理解计算机系统(CSAPP) 链接 -笔记

回顾链接这一章
我对链接的理解

可以将一个大型的源文件分解成更小的模块,其目的是更加易于管理,修改和编译这些模块。

将一个大型文件分离后肯定是会产生问题的
1.符号多重定义

要理解符号多重定义,那么就先得明白什么是符号,什么是符号定义,什么是符号解析,什么是强符号,什么是弱符号。

符号: csapp中是这样定义符号,每一个符号对应每一个函数,每一个全局变量和每一个静态变量。

 int a;
 void b();
 statc int c;
 // 这些都是符号

符号定义: 对该符号进行解释/定义,既为符号定义。严格来说每个符号都必须定义,但是未初始化变量一般编译器都会给予默认值,这个过程默认定义了这些未初始化的变量。符号定义不一定需要符号,在编译的时候只会警告,但是最好都加上,这样比较符合逻辑,有符号才有符号定义。函数未定义的符号和符号定义可以是多对一的关系,可以好几个在不同模块的符号对应到同一个模块的符号定义。

int a = 1;
void b(){};
statc int c = 1;
// 这些都是符号定义

符号解析: 有了符号定义才有符号解析,符号解析就是将每个符号和它的定义一一对应起来。(同时编译器还将每个引用都链接到定义处,确定运行时符号的位置,当然具体还是得去看《csapp》里 7.7 重定位这节,更加详细。)
在这里插入图片描述
如上图,void foo(void)只是个符号,缺少定义。因此编译器就无法解析该符号,因为找不到定义;

符号引用: 顾名思义,就是我使用了/引用了这个符号,就叫符号引用。一般来说,每个局部符号都对应着一个定义,当这个符号被引用时,编译器才会去做符号解析这个事情。就例如上图,我们将代码改动一下。

void foo(void);

int main()
{
	// foo(); 注释掉了foo()
	return 0;
}

这样编译器就不会报错了,因为我们并没有去引用这个符号,自然不会去解析这个符号,不去解析符号,那么也就不需要去理会这个符号有没有定义了。

强符号: 函数和已定义的全局变量,称为强符号。
弱符号: 未定义的全局变量,成为弱符号。

明白了以上几点,就知道如何解决多重符号定义的问题了。
在这里插入图片描述
通常来说我们一般都把符号写在头文件中,把符号定义写在源文件中,但在早期的c中是没有头文件的,

头文件#include,它的作用只是嵌入一段代码的作用,发生在编译时期。

有空再来整理整理吧,只是想到啥写啥。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值