关于全局变量、局部变量、静态变量的思考

来源:互联网 发布:person php 编辑:程序博客网 时间:2024/06/05 19:50

最近刚刚开始接触编程,对于各种类型数据的储存,尤其是遇见前面有static修饰词修饰的变量,一脸懵逼,下面是结合百家之言总结的用法:

 对一个C++变量来说,有两个属性非常重要:作用域和生命周期,它们从两个不同的维度描述了一个变量——时间和空间。顾名思义,作用域就是一个变量可以被引用的范围,如:全局作用域、文件作用域、局部作用域;而生命周期就是这个变量可以被引用的时间段。不同生命周期的变量,在程序内存中的分布位置是不一样的。一个程序的内存分为代码区、全局数据区、堆区、栈区,不同的内存区域,对应不同的生命周期。

有很多方法来指定一个变量的作用域和生命周期。最常见的,如:{}static修饰符等。下面按照作用域与生命周期来对变量做一个分类:

全局变量(外部变量)

作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件。)

生命周期:程序运行期一直存在

引用方法:其他文件中要使用必须用extern关键字声明要引用的全局变量(或者在定义的文件中进行extern,然后将头文件在别的文件内#include一下)。

内存分布:静态存储区

注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义

全局静态变量

作用域:文件作用域(只在被定义的文件中可见,也即只在被定义时的源文件中可以使用)

生命周期:程序运行期一直存在

内存分布:静态存储区(全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同,这两者的区别在于:非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误

定义方法:static关键字,const关键字

注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量(可以被多次初始化

局部变量(内部变量)

作用域:局部作用域(只在局部作用域中可见,例如函数中定义则只在函数内可用)

生命周期:只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回(这就是为什么函数返回指针的时候要用static修饰)

内存分布:栈区

注意:auto指示符标示

局部静态变量

作用域:局部作用域(只在局部作用域中可见)

生命周期:程序运行期一直存在

内存分布:静态存储区

定义方法:局部作用域用中用static定义

注意:只被初始化一次,多线程中需加锁保护

(对静态局部变量是在编译时赋初值的,即只赋值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句

(如在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0或空字符。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。这是由于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配单元的值不确定。

 

还有一点要说明,掌握static关键字的使用很关键。以下是别人的一些经验之谈:

Tips:

静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。

变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

从以上分析可以看出,把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static这个说明符在不同的地方所起的作用是不同的

若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;

若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;

如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)

函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。 

 


阅读全文
0 0
原创粉丝点击