今天在给学员讲课时,遇到了动、静态链接的内容。为了更清楚的阐述,我结合模块化程序设计,把这里相关的内容总结出来。方便后面查阅。这里主要涉及static
和extern
关键字的用法。
什么是模块
模块,就是可以完成某项特定任务的代码。 模块没有绝对的划分标准,只要是独立的,都叫模块。
最简单的模块,是函数。比如下面的 max
函数,它只求最大值。
int max(int x, int y)
{
return x > y : x : y;
}
代码容器
把具有类似功能的函数放在一个.cpp文件中,那么这个.cpp文件就变成了一个模块。比如,max()
和min()
功能类似,只不过一个求最大值,一个求最小值。 把这两个函数的实现放Calculator.cpp中,Calculator.cpp就是一个模块。
.cpp文件中的代码相互隔绝,彼此看不到。 也就是说, main.cpp中的代码不知道max()
的存在。我们把.cpp文件成为 代码容器。
为了让Main.cpp感知到max()
的存在,需要借助.h文件,也就是Header File。你想给外界暴露Calculator模块的哪些函数,就在 Calculator.h文件中写下它的声明。
信息隐藏
程序一大,就会出现重名的问题。 比如在下面的例子里,用户代码和模块中,都出现了StringLength()
的定义,虽然两个StringLength()
存在于各自的代码容器中,感知不到对方的存在,但是在链接时,由于名字相同,会导致冲突。
这时, static
关键字就出场了。 当给某个函数加上 static
后,别的模块就看不到它了。对于同时存在两个StringLength()
的情况,最后其实是 Main.cpp中的StringLength()
被调用,而不是Calculator.cpp中的那个。
从另一个角度来看,Calculator.cpp中的StringLength()
只能被本模块看到,那它也算是这个模块所私有的了。这恰好暗合了 C++ Class 中的 private
关键字。
所以,可以把.cpp文件看成一个”类“,把 .h中的内容看作public
的,而把.cpp中用static
修饰的变量、函数看作private
的。
全局变量
全局变量,就是定义在”全局“的变量。 那么”全局“是哪呢? 其实它指的是任何函数之外。比如,在下面的例子里,total
就是一个全局变量,它处于任何函数之外。
如何让别的函数感知到它的存在? 非常简单,使用extern
关键字修饰。 下面的例子中,同时提供了函数和全局变量的声明,可以对比。