fbpx
维基百科

静态变量

静态变量(英語:Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配英语Static memory allocation(也即在运行时中不再改变分配情况)存储空间的一类变量。与之相对应的是在运行时只暂时存在的自动变量(即局部变量)与以动态分配方式获取存储空间的一些对象,其中自动变量的存储空间在调用栈上分配与释放。

概念与定义 编辑

“静态变量”这一术语有两个容易混淆的定义:

  1. 语言无关的通用定义:与程序有着相同生命周期英语Object lifetime的变量;
  2. C族语言特有的定义:以static存储类声明的变量。

而在以Pascal为代表的许多程序语言中,所有局部变量都由系统自动分配存储空间,而所有全局变量的存储空间则以静态分配的方式获取(对应“静态变量”),因此由于实际上“局部变量”和“全局变量”这两个术语已足以涵盖所有的情况,在这些程序语言中通常不使用“静态变量”这一术语,而直接以“全局变量”代之。一般来说,在这些程序语言中,静态变量就是全局变量,而即使在有明确区分全局和静态变量的程序语言中,在编译后的代码里二者也以相同的方式获取存储空间。而今术语“静态变量”的概念则主要基于C族语言的“static”的定义(即定义2)。

作常量使用 编辑

静态变量也可以用于存储常数。具体来说,静态变量(全局变量及汇编语言里定义的符号亦同)可用const,constant或final(根据语言决定)等关键字标识,这时其值就会在编译时设定,并且无法在运行时改变。编译器通常将静态常量与文本一起置于目标文件的文本区域,而非常量初始化数据则置于数据区;而如若有需要,有些编译器还可选择为其开辟专用区;为防止常数变量被错误的指针写入覆盖,亦可在这块区域启用内存保护机制。

C族语言中的实现 编辑

C语言及由其衍生出的C++Objective-C等程序语言中,“static”是用于控制变量的生命周期和连接方式(即其作用域,亦即可见性)的保留字。确切来说,正如C族语言中的extern,auto与register这些保留字一样,static也是一种存储类(此处的“类”与面向对象语言的“”的定义不同)标识。每个变量与函数都有以上的一种存储类标识,如果在声明中没有明确标识其存储类,编译时就会根据上下文来选择其默认存储类,如在源文件里的所有文件级变量对应的默认存储类是extern,而在函数体内的变量对应的则是auto,各存储类的属性如下表所列。

存储类名 生命周期 作用域
extern 静态(程序结束后释放) 外部(整个程序)
static 静态(程序结束后释放) 内部(仅翻译单元,一般指单个源文件)
auto,register 函数调用(调用结束后释放)

易见存储类为extern的变量(包括上面提到的未明确声明存储类的文件级变量)符合前段所述静态变量的定义1,但不符合定义2。

不同情况下的作用 编辑

除明确标识出变量的生命周期英语Object lifetime外,将变量声明为static存储类还会根据变量属性不同而有一些特殊的作用:

  • 对于静态全局变量来说,针对某一源文件的以static声明的文件级变量与函数的作用域只限于文件内(只在文件内可见),也即“内部连接”,因而可以用来限定变量的作用域
  • 对于静态局部变量来说,在函数内以static声明的变量虽然与自动局部变量的作用域相同(即作用域都只限于函数内),但存储空间是以静态分配而非默认的自动分配方式获取的,因而存储空间所在区域不同(一般来说,静态分配时存储空间于编译时在程序数据段分配,一次分配全程有效;而自动分配时存储空间则是于调用栈上分配,只在调用时分配与释放),且两次调用间变量值始终保持一致;必须注意,静态局部变量只能初始化一次,这是由编译器来保证实现。[1]
  • 对于静态成员变量来说,在C++中,在类的定义中以static声明的成员变量属于类变量英语Class variable,也即在所有类实例中共享,与之相对的就是过程变量英语Instance variable

C示例 编辑

在C语言中,带有静态变量的程序如下所示:

#include <stdio.h> void func() {  static int x = 0; // 在对func的三次调用中,x只进行一次初始化  printf("%d\n", x); // 输出x的值  x = x + 1; } int main(int argc, char * const argv[]) {  func(); // 输出0  func(); // 输出1  func(); // 输出2  return 0; } 

C++示例 编辑

在C++中,带有含私有静态内部变量的类的程序如下所示:

class Request {  private:  static int count; // 不能为外部调用  string url; // 只能被成员函数调用    public:  Request() { count++; }  string getUrl() const { return url; }  void setUrl(string value) { url = value; }  static int getCount() { return count; } }; int Request::count = 0; // count 可以在类声明外进行初始化 

PHP示例 编辑

<?php function test(){ static $a = 0;//变量$a在第一调用test()时被初始化,每次调用 test() 函数都会输出 $a 的值并加 1 echo $a; $a++;//,每次调用 test() 函数都会输出 $a 的值并加 1 } ?> 

参见 编辑

参考 编辑

  1. ^ 例如,gcc编译器对静态局部变量,首先获取guard变量,判断低字节是否为 0,若非零,表示已经初始化,可以直接使用。否则,将 guard 作为参数调用 __cxa_guard_acquire,如果锁成功,执行初始化静态变量的语句,然后释放锁。如果锁失败,说明产生竞态条件,则会阻塞当前线程。利用该机制,可以很好的实现所谓 Singleton 模式。对于单线程程序,静态变量初始化的互斥保护是没有必要的,gcc的-fno-threadsafe-statics 选项可以禁掉该机制。

静态变量, 英語, static, variable, 在计算机编程领域指在程序执行前系统就为之静态分配, 英语, static, memory, allocation, 也即在运行时中不再改变分配情况, 存储空间的一类变量, 与之相对应的是在运行时只暂时存在的自动变量, 即局部变量, 与以动态分配方式获取存储空间的一些对象, 其中自动变量的存储空间在调用栈上分配与释放, 目录, 概念与定义, 作常量使用, c族语言中的实现, 不同情况下的作用, c示例, 示例, php示例, 参见, 参考概念与定义, 编辑, 这. 静态变量 英語 Static Variable 在计算机编程领域指在程序执行前系统就为之静态分配 英语 Static memory allocation 也即在运行时中不再改变分配情况 存储空间的一类变量 与之相对应的是在运行时只暂时存在的自动变量 即局部变量 与以动态分配方式获取存储空间的一些对象 其中自动变量的存储空间在调用栈上分配与释放 目录 1 概念与定义 2 作常量使用 3 C族语言中的实现 3 1 不同情况下的作用 3 2 C示例 3 3 C 示例 3 4 PHP示例 4 参见 5 参考概念与定义 编辑 静态变量 这一术语有两个容易混淆的定义 语言无关的通用定义 与程序有着相同生命周期 英语 Object lifetime 的变量 C族语言特有的定义 以static存储类声明的变量 而在以Pascal为代表的许多程序语言中 所有局部变量都由系统自动分配存储空间 而所有全局变量的存储空间则以静态分配的方式获取 对应 静态变量 因此由于实际上 局部变量 和 全局变量 这两个术语已足以涵盖所有的情况 在这些程序语言中通常不使用 静态变量 这一术语 而直接以 全局变量 代之 一般来说 在这些程序语言中 静态变量就是全局变量 而即使在有明确区分全局和静态变量的程序语言中 在编译后的代码里二者也以相同的方式获取存储空间 而今术语 静态变量 的概念则主要基于C族语言的 static 的定义 即定义2 作常量使用 编辑静态变量也可以用于存储常数 具体来说 静态变量 全局变量及汇编语言里定义的符号亦同 可用const constant或final 根据语言决定 等关键字标识 这时其值就会在编译时设定 并且无法在运行时改变 编译器通常将静态常量与文本一起置于目标文件的文本区域 而非常量初始化数据则置于数据区 而如若有需要 有些编译器还可选择为其开辟专用区 为防止常数变量被错误的指针写入覆盖 亦可在这块区域启用内存保护机制 C族语言中的实现 编辑在C语言及由其衍生出的C 与Objective C等程序语言中 static 是用于控制变量的生命周期和连接方式 即其作用域 亦即可见性 的保留字 确切来说 正如C族语言中的extern auto与register这些保留字一样 static也是一种存储类 此处的 类 与面向对象语言的 类 的定义不同 标识 每个变量与函数都有以上的一种存储类标识 如果在声明中没有明确标识其存储类 编译时就会根据上下文来选择其默认存储类 如在源文件里的所有文件级变量对应的默认存储类是extern 而在函数体内的变量对应的则是auto 各存储类的属性如下表所列 存储类名 生命周期 作用域extern 静态 程序结束后释放 外部 整个程序 static 静态 程序结束后释放 内部 仅翻译单元 一般指单个源文件 auto register 函数调用 调用结束后释放 无易见存储类为extern的变量 包括上面提到的未明确声明存储类的文件级变量 符合前段所述静态变量的定义1 但不符合定义2 不同情况下的作用 编辑 除明确标识出变量的生命周期 英语 Object lifetime 外 将变量声明为static存储类还会根据变量属性不同而有一些特殊的作用 对于静态全局变量来说 针对某一源文件的以static声明的文件级变量与函数的作用域只限于文件内 只在文件内可见 也即 内部连接 因而可以用来限定变量的作用域 对于静态局部变量来说 在函数内以static声明的变量虽然与自动局部变量的作用域相同 即作用域都只限于函数内 但存储空间是以静态分配而非默认的自动分配方式获取的 因而存储空间所在区域不同 一般来说 静态分配时存储空间于编译时在程序数据段分配 一次分配全程有效 而自动分配时存储空间则是于调用栈上分配 只在调用时分配与释放 且两次调用间变量值始终保持一致 必须注意 静态局部变量只能初始化一次 这是由编译器来保证实现 1 对于静态成员变量来说 在C 中 在类的定义中以static声明的成员变量属于类变量 英语 Class variable 也即在所有类实例中共享 与之相对的就是过程变量 英语 Instance variable C示例 编辑 在C语言中 带有静态变量的程序如下所示 include lt stdio h gt void func static int x 0 在对func的三次调用中 x只进行一次初始化 printf d n x 输出x的值 x x 1 int main int argc char const argv func 输出0 func 输出1 func 输出2 return 0 C 示例 编辑 在C 中 带有含私有静态内部变量的类的程序如下所示 class Request private static int count 不能为外部调用 string url 只能被成员函数调用 public Request count string getUrl const return url void setUrl string value url value static int getCount return count int Request count 0 count 可以在类声明外进行初始化 PHP示例 编辑 lt php function test static a 0 变量 a在第一调用test 时被初始化 每次调用 test 函数都会输出 a 的值并加 1 echo a a 每次调用 test 函数都会输出 a 的值并加 1 gt 参见 编辑变量 程序设计 参考 编辑C程序设计语言 第二版 布莱恩 柯林汉与丹尼斯 里奇著 Prentice Hall 1984 ISBN 0 13 110362 8 C 程序设计语言 特别版 比雅尼 斯特劳斯特鲁普著 Addison Wesley 2000 ISBN 0 201 70073 5 The GNU C Reference Manual 页面存档备份 存于互联网档案馆 英文 GNU org Static Variables 页面存档备份 存于互联网档案馆 英文 University of Hawaii 例如 gcc编译器对静态局部变量 首先获取guard变量 判断低字节是否为 0 若非零 表示已经初始化 可以直接使用 否则 将 guard 作为参数调用 cxa guard acquire 如果锁成功 执行初始化静态变量的语句 然后释放锁 如果锁失败 说明产生竞态条件 则会阻塞当前线程 利用该机制 可以很好的实现所谓 Singleton 模式 对于单线程程序 静态变量初始化的互斥保护是没有必要的 gcc的 fno threadsafe statics 选项可以禁掉该机制 取自 https zh wikipedia org w index php title 静态变量 amp oldid 72964801, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。