【知识点1】静态变量作用域和链接性
首先看代码
int global = ;
static int one_file = ;
int main()
{
...
}
void function1(int n)
{
static int count = ;
int llama = ;
...
}
void function2(int q)
{
...
}
C++为静态存储持续性变量提供了3种链接性:
1)外部链接性,如变量
global
2)内部链接性,如变量
one_file
3)无链接性, 如变量
count
三种链接性的对应作用域:
要点1:外部链接性,如变量
global
可以在程序的其他文件中使用它;
要点2:内部链接性,如变量
one_file
只能在包含上述代码的文件中使用它;
要点3:无链接性,如变量
count
其作用域只在
function1()
函数中使用,和自动变量
llama
一样。但和llama不同的是,即使函数
function1()
没有被执行,变量
count
也存在于内存中。
【知识点2】单定义规则
-
What?是什么
C++有“单定义规则”(One Definition Rule,ODR),规则指出变量只能有一次定义。
-
How?解决办法
C++提供了两种声明办法:
1)定义声明:它给变量分配存储空间;
2)引用声明:它不给变量分配存储空间,因为它引用已有的变量。使用关键字
extern
声明但不进行初始化。
先看看代码的声明,代码如下:
double up; //这个是自动变量up,此处为声明并初始化为0(C++对静态变量的初始化自动设定为0),外部链接属性;
extern int blem; //引用声明,其他某个文件对其定义
extern char gr = 'z'; //此处为定义,因为初始化并分配了空间
【知识点3】全局变量(附const)
首先看代码:
/** 此处代码定义为全局变量 **/
const char* const months[]=
{
"January","February","March","April","May","June",
"July","August","September","October","November","December"
}
- 全局变量
months
含义
1)
months
代表一个常量数据,可以让多个函数使用同一个数据块;
2)
全局变量的第一个months
防止字符串被修改,第二个const
确保数组中每个指针始终指向它最初指向的字符串。const
- 问题:
和全局变量
局部变量
什么情况下该用?
要点1:
代表着所有的函数能访问全局变量
全局变量
,省去传递参数的麻烦;
要点2:
的易访问性质,代表可以对数据进行不必要的访问,就不能保证数据的完整性——全局变量
程序不可靠
;
要点3:使用
意味着,在需要知晓时才传递数据,而不在各种情况下使用全局变量的数据。局部变量
-
修饰的全局常量const
months
能被其他文件使用吗?
解答:
不能。C++认为,全局
的链接性为内部的;因此所有文件都可以使用相同的声明,但不能使用。const
若要想
months
的链接性为外部的,则必须使用
extern
来覆盖默认的内部链接性。
int global = ; //常规外部变量
extern const char* const months[]= //全局常量
{
"January","February","March","April","May","June",
"July","August","September","October","November","December"
}
在这种情况下,其他文件使用该常量
months
必须使用
extern
来声明它。
注意:与常规外部变量
global
不同,其也具有外部链接性,但是在当前文件中不必使用
extern
来声明。
【知识点4】函数和语言链接性
-
函数链接性
C/C++定义:一个函数内不能定义另一个函数。默认情况下,函数的链接性为外部的,可以在文件之间共享,意味着
所有函数的存储持续性都自动为静态的,即在整个程序执行期间都一直存在。
,要求在函数原型和函数定义中使用关键字函数设定为文件只在一个文件内使用
:static
这意味着:该函数只在这个文件中可见,也可以在其他文件中定义同名的函数。在定义静态函数的文件中,静态函数将涵盖外部定义,因此即使在外部定义了同名的函数,该文件仍将使用静态函数。static int private(double x); ... static int private(double x) { ... }
-
编译器怎么找函数
假设函数在某个文件A中调用了一个函数F,该函数F原型在该文件A中指出是静态的,则编译器将只在该文件中查找函数定义。否则,编译器将在所有的程序文件中查找。
如果编译器找到两个定义,则编译器发出错误信息。
假如编译器在所有的程序文件中都没找到,则将搜索库中的函数。此时意味着:
。如果定义了一个与库函数同名的函数,编译器将使用程序员定义的版本,而不是库函数
-
语言链接性
—>存在的问题:
举例:针对函数
C编译器:将其翻译成spiff(int)
_spiff
,即C语言链接性;
C++编译器:将其翻译成
,将函数_spiff_i
翻译成spiff(double,double)
_spiff_d_d
,即C++语言链接性;
—>解决的办法:
使用函数原型指出要使用的约定:
extern "C" void spiff(int);
extern void spiff(int);
extern "C++" void spiff(int);
第一个:使用C语言链接性;
第二个:默认使用C++语言链接性;
第三个:显示指出使用C++语言链接性。
end
下一篇预告:new与delete基础篇