导图社区 头文件的编写
头文件的编写、我们可以将程序的扩展模块定义成弱引用。于是当我们将扩展模块和程序链接时,程序能够正常运行。当我们拿掉扩展模块时,程序也不会报错。
编辑于2022-11-10 21:34:56时间管理-读书笔记,通过学习和应用这些方法,读者可以更加高效地利用时间,重新掌控时间和工作量,实现更高效的工作和生活。
本书是法兰教授的最新作品之一,主要阐明了设计史的来源、设计史现在的状况以及设计史的未来发展可能等三个基本问题。通过对设计史学科理论与方法的讨论,本书旨在促进读者对什么是设计史以及如何写作一部好的设计史等问题的深入认识与反思。
《计算机组成原理》涵盖了计算机系统的基本组成、数据的表示与运算、存储系统、指令系统、中央处理器(CPU)、输入输出(I/O)系统以及外部设备等关键内容。通过这门课程的学习,学生可以深入了解计算机硬件系统的各个组成部分及其相互之间的连接方式,掌握计算机的基本工作原理。
社区模板帮助中心,点此进入>>
时间管理-读书笔记,通过学习和应用这些方法,读者可以更加高效地利用时间,重新掌控时间和工作量,实现更高效的工作和生活。
本书是法兰教授的最新作品之一,主要阐明了设计史的来源、设计史现在的状况以及设计史的未来发展可能等三个基本问题。通过对设计史学科理论与方法的讨论,本书旨在促进读者对什么是设计史以及如何写作一部好的设计史等问题的深入认识与反思。
《计算机组成原理》涵盖了计算机系统的基本组成、数据的表示与运算、存储系统、指令系统、中央处理器(CPU)、输入输出(I/O)系统以及外部设备等关键内容。通过这门课程的学习,学生可以深入了解计算机硬件系统的各个组成部分及其相互之间的连接方式,掌握计算机的基本工作原理。
头文件的编写
15.12 static变量和函数
static 的使用
对象:
1. 修饰 全局变量或函数
防止重复定义相同名称的全局变量/函数,出现报错
2. 修饰 局部变量
防止函数结束时,其内部数据也随之消失,但自己需要该函数内部变量的数据一直存在
作用:
修饰全局变量或函数时,
static 声明的全局变量和函数只在当前文件下起作用,其他文件(模块)不起作用
修饰局部变量时
被static修饰的局部变量会存储于 全局变量区
注意:全局变量区 中的变量,只能被初始化(定义)一次,后面再遇到初始化的语句时,该语句失效
可以让该变量在整个程序运行中一直存在,而不是在其所在的函数结束时,该变量也同样消失
意义:
1.隐藏
防止在不同的文件里面定义了相同名称的全局变量/函数,造成麻烦
2. 保持变量内容的持久性
将局部变量存储到 全局数据区 。防止局部变量随着函数进程的结束而被销毁
局部变量仍然只在所在的函数起作用,但是不会随着函数调用的结束而被销毁)
15.11 防止偷文件被重复包含
解决办法:
代码:
15.10 C语言头文件的路径
当使用标准头文件时,include<stdio.h>……
使用自己定义的头文件时,include “tool.h”
“”是先从当前文件开始查找tool.h头文件,没有找到再从系统文件开始找
<>跳过当前文件,直接就从系统文件开始找
就记住,自己定义的头文件,使用“”引用,标准的头文件,使用<>引用即可。
15.9 C语言的标准库和标准头文件
15.8 C语言模块化编程中的头文件
main.c 文件和main.h文件
.c文件
专门负责实现目的,即对函数、变量的定义
.h文件
专门负责声明
对函数和变量的声明(不定义)
定义宏(包括带参 和 不带参)
存放 结构体、自定义的数据类型
好处
.c 和 .h 文件负责的内容不属于c语言的规则,但是长期以来默认遵守的习俗,方便交流
可以保护版权
当自己使用一组相关的变量和函数 卸载一个.c 文件中,并同时用 同名的.h文件 进行声明。
这样一来,其他用户想要使用我们程序编写的功能时,就可以将.h文件提供给用户,而不告诉其具体实现的代码
15.7 强引用和弱引用
引用:
也就是对符号的使用
如:
第一行是对符号的定义,第二行是对符号的引用。
强引用:
当生成可执行程序时,发现有符号没有被定义,就会报错
弱引用:
当生成可执行程序时,有些符号并没有被定义,但是也不会报错
强弱引用的作用
弱引用:
我们可以将程序的扩展模块定义成弱引用。于是当我们将扩展模块和程序链接时,程序能够正常运行。当我们拿掉扩展模块时,程序也不会报错
15.6 强符号和弱符号
产生两个名词的原因:
在编写代码的时候,可能在不同的文件中,都定义了相同的变量名、函数名。这时候在链接的时候,链接器就会一脸懵逼:a变量在两个源文件中都进行了定义,我到底该听哪一个文件的呀?
为了方便链接器进行工作,程序员就设定了强符号和弱符号的概念,并且制定了规则
强符号:
编译器默认 函数和初始化了的全局变量是强符号
弱符号:
没有被初始化的全局变量是弱符号
规则:
1) 不允许强符号被多次定义,也即不同的目标文件中不能有同名的强符号;如果有多个强符号,那么链接器会报符号重复定义错误。
2) 如果一个符号在某个目标文件中是强符号,在其他文件中是弱符号,那么选择强符号。
3) 如果一个符号在所有的目标文件中都是弱符号,那么选择其中占用空间最大的一个。
15.5 链接的实现机理
比如对于main.c 和 module.c 两个源文件来说
在module.c中定义了fun()函数,在main.c中多次调用了这个函数。
我已经知道,源文件在编译生成目标文件的时候,是一个一个生成的。所以当对main.c一个源文件生成一个目标文件的时候,程序并不知道fun()这个函数到底是个什么东西,它该怎么办。机器这时候只能在每一个需要修正的地方,标记一下。每一个需要被修正的地方都叫做重定位入口
然后链接就粉墨登场了。链接会找到所有符号(变量、函数……等都是符号,是地址的助记符)的地址(扫描目标文件中的所有符号symbol)(目标文件有一个专门的section 叫做:.symtab专门来记录当前文件的所有符号)。然后将在编译的时候标记的所有重定位入口的符号都换成。即将main.c中的所有fun()的地址都换成module.c中fun()的地址。
链接的工作
1. 找到所有目标文件 的全部符号地址
2. 将所有重定位入口都改成已经找到的真正的符号地址
有专门的的重定位表记录 所有需要重定位的符号和重定位入口: .rel.text 和 .rel.data
15.4 链接的作用
还是有些懵,先就认为,链接 这个黑匣子,让进行 多文件编程(模块化编程) 得以实现
15.3 目标文件&可执行文件
目标文件的组织形式
目标文件被划分成很多部分,每个部分叫做段(section)每一部分专门负责存放一种类型的信息
可执行文件的组织形式
链接
目标文件和可执行文件的区别
目标文件含有段表(section table),关注 段(section)
可执行文件含有程序表头(program header table),关注 (segment)
15.2 源代码生成可执行文件的内部机理
预处理
编译
链接
网址
那些被编译器隐藏了的过程 (biancheng.net)
15.1 exter关键字
功能:
声明 一个变量或者函数
声明和定义的区别:
声明:有extern修饰的变量/函数。仅仅是说一下有这个变量/函数,让系统不要报错。
对于函数而言,除了extern关键字声明以外,还可以用函数体来区分是定义还是声明
而对于变量而言,只能通过extern来区别是声明还是定义
定义:没有extern修饰的变量/函数。直接给出这个变量,并且可以赋值
extern 关键字用来声明全局变量和函数
仅仅是声明,不需要定义(赋值),但是可以定义(赋值),不过这样写不规范。
全局变量和函数的意义:
除了当前这个文件可以调取 用extern 声明的变量或函数以外,这个工程(程序)下的其他文件也可以调取
代码理解:
变量
声明
extern int a;
定义
int a;
int a = ~;
函数
声明:
datatype function (datatype1, datatype2,……);
datatype function( datatype1 name1, datatype2 name2,……);
extern datatype function (datatype1, datatype2,……);
extern datatype function( datatype1 name1, datatype2 name2,……);
定义
dataype function (datatype1 name1, ……){ function body}