全局变量
生命周期:程序运行期一直存在
引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量。
内存分布:全局数据区
注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义
全局静态变量
生命周期:程序运行期一直存在
内存分布:全局数据区
定义方法:static关键字,const 关键字
注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量
静态局部变量
生命周期:程序运行期一直存在
内存分布:全局数据区
定义方法:局部作用域用中用static定义
注意:只被初始化一次,多线程中需加锁保护
局部变量
生命周期:程序运行出局部作用域即被销毁
内存分布:栈区
注意:auto指示符标示
还有一点要说明,掌握static关键字的使用很关键
Tips:
若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。
谭浩强书:
从存储模型可以看到,谭浩强和钱能的模型有一定的对应关系:
静态存储区 -> 全局数据区
动态存储区 -> 栈(stack)
变量的类型:
1. 局部变量和全局变量
局部变量也称为内部变量。 局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再
使用这种变量是非法的。
全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其
作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变
量才能使用。全局变量的说明符为 extern。但在一个函数之前定义的全局变量,在该函数内使用可不再加
以说明。
从变量的作用域(全局作用域,局部作用域,文件作用域)(即从空间)角度来分,可以分为
全局变量(静态全局变量的作用域是该文件范围(文件作用域)
局部变量。
从另一个角度,从变量值存在的作时间(即生存期)角度来分,可以分为静态存储方式和动态存储方式。
可见生存周期只是和变量存储的位置相关。
auto变量:
函数中的局部变量,如不专门声明为 static 存储类别,都是动态地分配存储空间的,数
据存储在动态存储区中。函数中的形参和在函数中定义的变量(包括在复合语句中定义的变
量),都属此类,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释
放这些存储空间。这类局部变量称为自动变量。自动变量用关键字 auto 作存储类别的声明。
关键字 auto可以省略,auto 不写则隐含定为“自动存储类别”,属于动态存储方式。
用 static声明局部变量 :
有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,这时就应该指定局部变量为“静态
局部变量”,用关键字 static 进行声明
register变量:
为了提高效率,C 语言允许将局部变量得值放在 CPU 中的寄存器中,这种变量叫“寄存器变量”,用
关键字 register 作声明。
1) 只有局部自动变量和形式参数可以作为寄存器变量;
2) 一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量;
3) 局部静态变量不能定义为寄存器变量
用extern声明外部变量:
外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到
本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到
文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字 extern
对该变量作“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可
以从“声明”处起,合法地使用该外部变量。
总结:
从作用域来划分分为:
- 自动变量auto,即动态局部变量(离开函数,值消失)
局部变量 - 静态局部变量static(离开函数,值还保留)
- 寄存器局部变量register(离开函数,值消失)
- 形式参数可以定义为自动变量或者register变量
- 静态外部变量(作用域只能在该文件中,文件作用域)
全局变量 - 外部变量(非静态外部变量,全局变量,可以被其它文件使用)
从变量的生存周期来分:
- 自动变量auto
动态存储 - 寄存器变量register
- 形式参数
- 静态局部变量
静态存储 - 静态外部变量
- 外部变量(全局变量)
从变量值存放的位置:
- 静态局部变量
内存中的静态存储区(全局数据区) - 静态外部变量
- 外部变量(全局变量)
- 自动变量auto
内存中的动态存储区(栈) - 形式参数
CPU中的寄存器 - 寄存器变量register