深入学习静态变量

原创 zhaoliang  2015-08-24 23:58  阅读 795 views 次

写了多年的程序,提到变量这个词,大多数写过代码的人可能都会有同样的感觉,耳熟能详,我自己也不例外。前几天看到一个含有静态变量的示例程序,突然让自己真正意识到,变量其实真的不是如好多书本资料上讲述的那么简单,因此自己也特意的百度了一下,发现没有一个比较好的定义,于是特地又翻了一下大学刚接触编程语言时的经典入门教材--谭浩强老师的《C程序设计》,发现谭老师是这么给变量定义的:“对于基本数据类型量,按其取值是否可改变又分为常量和变量两种。在程序执行过程中,其值不发生改变的量称为常量, 其值可变的量称为变量。”,果然是简要扼要哈。

发现这次的寻根问底,真的是很有必要的,写了这么多年的程序,突然才发现自己水平挺Low的,竟然连静态变量的工作原理都没弄清,这次是该大补一下了。

在变量的前面加上关键词static,变量就变成了静态变量。变量按照作用域来划分可分为全局变量和局部变量,所以静态变量按照作用域也可分为静态全局变量和静态局部变量。不要小瞧这个static关键词,有它没它程序的执行结果差别可大着呢。

在这里补点偷师而来的知识----程序在执行时的内存分配:

一个由c/C++编译的程序占用的内存由低地址到高地址分为以下几个部分

  1. 程序段(text):程序段为程序代码在内存中的映射,是用来存放程序语句进行编译后,形成机器的代码。一般此内存区是只读的,防止程序意外修改指令
  2. 初始化过的数据段(initialized data):在程序运行之初已经对变量进行初始化的,通常是用来存放程序中已初始化的全局变量的一块内存区域,又分为只读和读写两种,此数据段属于静态内存分配;
  3. 未初始化过的数据段(uninitialized data):在程序运行初未对变量进行初始化的数据,这些变量在程序运行之前不需要占用存储器的空间.BSS(Block Started by Symbol)段也属于静态内存分配;
  4. 栈(heap):存储动态内存分配,需要程序员手工分配,手工释放,在操作系统下,如果程序员没释放,一般操作系统可以在程序结束后回收内存;
  5. 存放程序的局部变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的最大特点后进先出,所以栈特别方便用来保存/恢复调用现场。

从图上可以看到,栈(stack)是自顶向下生长的,即由高地址向低地址;堆(heap)是自底向上生长。右图是栈的进出示意图,很明显的后进先出。

静态变量都在全局数据区分配内存(initialized data),是静态存储方式,普通的全局变量也是如此,而局部变量则使用的是动态存储方式。

全局变量与静态全局变量

  1. 未经初始化的静态全局变量会被程序自动初始化一个初值
  2. 在一个文件内定义的全局变量,作用域是整个工程,在另一个文件中可以使用;静态全局变量在声明它的整个文件都是可用的,不能被其它文件所用
  3. 静态全局变量可以在其它文件中定义相同名字的变量,不会发生冲突

局部变量与静态局部变量

  1. 局部变量是动态存储方式,在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放;静态局变量在全局数据区分配内存,是静态存储方式,在变量定义时就分定存储单元并一直保持不变,直至整个程序结束,也就是说它的生存期为整个源程序;
  2. 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化
  3. 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化赋初值;
  4. 静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。

但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。静态局部变量正好可以解决这个问题。

静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。

本文地址:http://blog.58cm.cn:8088/archives/143.html
版权声明:本文为原创文章,版权归 zhaoliang 所有,欢迎分享本文,转载请保留出处!

评论已关闭!