|
静态变量,又叫静态存储持续性变量,它有 3 种链接性:外部链接性( 可在其他文件中访问 ),内部链接性( 只能在当前文件中访问 ) 和 无链接性( 只能在当前函数或代码块中访问 )。
在编译程序时,编译器会分配固定的内存块来存储所有的静态变量,它们在整个程序的执行期间一直存在。对于没有显式初始化的静态变量,编译器将把它们设置为 0 ,因此静态数组和静态结构中的每个成员都初始化为0。
要创建外部链接性的静态变量,必须在代码块的外面声明;要创建内部链接性的静态变量,必须在代码块外面声明并使用 static 限定符;要创建没有链接性的静态变量,必须在代码块内声明,也需要有 static 声明。见下示例程序:- int global = 1000; // 全局变量,外部链接性
- static int one_file = 50; // 内部链接性
- int main()
- {
- ...
- }
- void funct1(int n)
- {
- static int count = 0; // 没有链接性
- int llama = 0;
- ...
- }
- void funct2(int q)
- {
- ...
- }
复制代码 链接性为外部的变量称为外部变量,也称为全局变量,它们的存储持续性为静态,作用域为整个文件。如果要在多个文件中使用外部变量,只需要在一个文件中包含该变量的定义,在其它所有文件中都必须使用关键字 extern 声明它,比如:- // file01.cpp
- extern int cats = 20; // 定义并初始化,extern 关键字可不要
- int dogs = 22; // 定义
- int fleas; // 定义
- ...
- // file02.cpp
- // use cats and dogs from file01.cpp
- extern int cats; // 非定义,只是声明,从别处引
- extern int dogs; // extern
- ...
- // file98.cpp
- // 引用 file01.cpp 中的 cats, dogs, and flea
- extern int cats;
- extern int dogs;
- extern int fleas;
- ...
复制代码 如果在 file01.cpp 中定义了一个变量,而在 file02.cpp 中也定义了相同名称的一个变量,因为我们不打算从 file01.cpp 中引用它,即省略掉 extern 关键字,那么这是否可行?答案是否定的,因为这违反了“单定义规则”。
单定义规则( One Definition Rule, ODR )指出,变量只能有一次定义。为了满足这种需求,C++ 提供了两种变量声明:一种是定义声明(简称定义),它给变量分配存储空间;另一种是引用声明(简称声明),它不给变量分配存储空间,因为它只是引用已有的变量。引用声明正是使用了关键字 extern 。
但是,如果文件定义了一个静态外部变量,其名称与另一个文件中中声明的常规外部变量相同,那么在该文件中,静态变量将隐藏常规外部变量:- // file1
- int errors = 20; // 外部声明
- ...
- ---------------------------------------------
- // file2
- static int errors = 5; // 静态外部变量,仅为 file2 所知
- void froobish()
- {
- cout << errors; // errors 变量来自 file2 而非 file1, file1 中的被隐藏
- ...
- }
复制代码 上面代码并没有违反单定义规则,因为关键字 static 指出 errors 的链接性是为内部的,并非要提供外部定义。
因此,外部变量在多文件程序的不同部分之间共享数据;链接性为内部的静态变量在同一个文件中的多个函数之间共享数据。如上,如果将作用域为整个文件的变量变为静态的,就不必担心其名称与其他文件中的作用域为整个文件的变量发生冲突。
|
|