当前位置: 首页 > 互联网, 翻译 > 正文

c语言变量存储类别

变量的存储类别是指变量的值在内存中的存储类型。变量的存储类别确定着变量的创建,销毁和变量值保存的时间长度。有三个变量可能的存储位置:普通内存,运行时堆栈和硬件寄存器。变量存储在这三个不同的位置有着不同的特性。

变量默认的存储类别由变量声明的位置决定。在任何代码块之外声明的变量往往存储在静态内存空间中,即内存中的非堆栈空间。无法为这类变量使用除此之外其它的存储类别。静态变量创建于程序运行开始之前,并存在于程序运行的整个过程。静态变量保存所赋的值不变,直到重新赋一个不同值,或是直到程序运行结束。

在代码块内声明变量的默认存储类型是automatic,就是说变量存储在堆栈(stack)上,关键字是auto。但这个关键字很少使用,因为默认的存储类别不会改变。自动变量在程序刚刚运行进入到程序块之前,在变量声明的地方创建,在程序执行离开当前程序块时删除。如果一个程序块被反复执行多次,比如一个函数被反复调用,就会在每次调用的时候重新复制变量。这些新变量与之前实例中所使用的相同名称变量并不一定占用相同的堆栈空间。甚至无法保证相关内存空间不被用作其它用途。因此,我们说自动变量在代码块结束后就被删除了,通常来讲当再次进入代码块时,之前变量存储的值已经不在了。

代码块里声明的变量,使用关键字static会将变量的存储类别由自动类别变成静态类别。静态类别存储的变量会存在于程序运行的始终,而不是只局限于变量声明的代码块之内。切记,改变变量的存储类型并不改变变量的作用域范围,也就是说此变量名称只能在声明的代码块内访问。函数的的参数格式不能声明成static类型,因为参数往往在堆栈上传递以支持递归循环。

最后,register关键字可用在自动变量的声明,用来指明这些变量需要存储在机器硬件寄存器而不是内存中。通常情况下,这种类型的变量访问比存储在内存中的访问效率更高。但是,编译器也可能会随意的忽略register关键字。如果有很多变量定义成register,事实上只有最先声明的那个变量的才会真正的存储在寄存器中,剩下的变量都是自动存储。当编译器开启寄存器优化时,可能会完全忽略register关键字,因为编译器比我们能更好的决定哪个值应当存储在寄存器中。

很显然,在声明变量时人们会想将那些使用最频繁的变量声明成register类型变量。在一些计算机上,如果我们将指针声明成寄存器变量时,运行的程序会受益很多,尤其是那些间接取值用的最多的指针。你也也可以将一个函数的形式参数声明成寄存器型变量,这样编译器会在函数的开始位置会将堆栈上的值拷贝到寄存器的指令插入。但是,同样有可能,接下的参数访问所节省的空间和时间还不足以抵销这种拷贝带来的时间开销。

寄存器变量与自动变量同时产生,同时消亡,但同时会有一些额外的工作。在函数使用寄存器变量返回之前,先前寄存器的内容必须先存储起来,确保调用者的寄存器变量不被破坏。很多机器使用运行时堆栈来完成这项任务。当一个函数开始后,所有函数将使用的寄存器内容都先被保存在堆栈上。这些值在函数返回后重新复制到各自对应的寄存器上。

很多硬件不允许指派寄存器地址。当然也是因为在存储或是还原寄存器值时,特定的寄存器在不同的时间可能包含多种不同的值,所以也就不允许获取寄存器地址变量。

本文固定链接: http://www.byhard.com/?p=868 | 海纳百川

该日志由 byhard 于2013年02月07日发表在 互联网, 翻译 分类下,
原创文章转载请注明: c语言变量存储类别 | 海纳百川
关键字: ,

c语言变量存储类别:目前有6 条留言

  1. 路过,写得不错,支持一下!

    2013-02-08 11:14
    • byhard:

      谢谢支持。欢迎再来,回访去了。

      2013-02-16 09:48
  2. 还好我没学代码,好复杂。

    2013-02-09 12:24
    • byhard:

      隔行如隔山,懂了也就那样的。

      2013-02-16 09:48
  3. 沙发
    88娱乐城:

    在上班的苦逼程序猿一枚~

    2013-02-16 09:46
    • byhard:

      哈哈,同是程序员,我也今天回来上班了。

      2013-02-16 09:47