9.2.3 静态持续变量(1)
和C语言一样,C++(www.cppentry.com)也为静态存储持续性变量提供了3种链接性:外部链接性(可在其他文件中访问)、内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)。这3种链接性都在整个程序执行期间存在,与自动变量相比,它们的寿命更长。由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊的装置(如栈)来管理它们。编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存在。另外,如果没有显式地初始化静态变量,编译器将把它设置为0。在默认情况下,静态数组和结构将每个元素或成员的所有位都设置为0。
注意:传统的K&R C不允许初始化自动数组和结构,但允许初始化静态数组和结构。ANSI C和C++(www.cppentry.com)允许对这两种数组和结构进行初始化,但有些旧的C++(www.cppentry.com)翻译器使用与ANSI C不完全兼容的C编译器。如果使用的是这样的实现,则可能需要使用这3种静态存储类型之一,以初始化数组和结构。
下面介绍如何创建这3种静态持续变量,然后介绍它们的特点。要想创建链接性为外部的静态持续变量,必须在代码块的外面声明它;要创建链接性为内部的静态持续变量,必须在代码块的外面声明它,并使用static限定符;要创建没有链接性的静态持续变量,必须在代码块内声明它,并使用static限定符。下面的代码片段说明这3种变量:
正如前面指出的,所有静态持续变量(上述示例中的global、one_file和count)在整个程序执行期间都存在。在funct1( )中声明的变量count的作用域为局部,没有链接性,这意味着只能在funct1( )函数中使用它,就像自动变量llama一样。然而,与llama不同的是,即使在funct1( )函数没有被执行时,count也留在内存中。global和one_file的作用域都为整个文件,即在从声明位置到文件结尾的范围内都可以被使用。具体地说,可以在main( )、funct1( )和funct2( )中使用它们。由于one_file的链接性为内部,因此只能在包含上述代码的文件中使用它;由于global的链接性为外部,因此可以在程序的其他文件中使用它。
所有的静态持续变量都有下述初始化特征:未被初始化的静态变量的所有位都被设置为0。这种变量被称为零初始化的(zero-initialized)。
表9.1总结了引入名称空间之前使用的存储特性。下面详细介绍各种静态持续性。
表9.1指出了关键字static的两种用法,但含义有些不同:用于局部声明,以指出变量是无链接性的静态变量时,static表示的是存储持续性;而用于代码块外的声明时,static表示内部链接性,而变量已经是静态持续性了。有人称之为关键字重载,即关键字的含义取决于上下文。
表9.1 5种变量储存方式
|
存 储 描 述< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
持续性 |
作用域 |
链接性 |
如 何 声 明 |
|
自动 |
自动 |
代码块 |
无 |
在代码块中 |
|
寄存器 |
自动 |
代码块 |
无 |
在代码块中,
使用关键字register |
|
静态,无链接性 |
静态 |
代码块 |
无 |
在代码块中,
使用关键字static |
|
静态,外部链接性 |
静态 |
文件 |
外部 |
不在任何函数内 |
|
静态,内部链接性 |
静态 |
文件 |
内部 |
不在任何函数内,
使用关键字static |
静态变量的初始化
除默认的零初始化外,还可对静态变量进行常量表达式初始化和动态初始化。您可能猜到了,零初始化意味着将变量设置为零。对于标量类型,零将被强制转换为合适的类型。例如,在C++(www.cppentry.com)代码中,空指针用0表示,但内部可能采用非零表示,因此指针变量将被初始化相应的内部表示。结构成员被零初始化,且填充位都被设置为零。
零初始化和常量表达式初始化被统称为静态初始化,这意味着在编译器处理文件(翻译单元)时初始化变量。动态初始化意味着变量将在编译后初始化。