变量的四个属性:数据类型,存储类别,作用域,生存周期。
变量的分类:
一、根据数据类型:
二、根据存储类别可分为静态存储方式和动态存储方式。
三、根据作用域可分为全局变量和局部变量。
四、根据生存周期可分为静态存储方式和动态存储方式,具体地又分为自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。
auto存储类型:(自动变量)(局部变量和函数参数,动态存储区(即栈区))
函数的形参和在函数中定义的变量都属于自动变量。
编译系统对自动变量是动态地分配存储空间的,并在函数调用结束或语句结束时自动释放这些空间。
默认情况下的局部变量均属于自动变量。
自动变量只可能是局部变量,因为全局变量属于静态存储,与auto变量是相互冲突的。
static存储类型:(局部变量或全局变量,静态存储区)
一、静态局部变量:
静态局部变量的生命期在函数调用结束后会依然存在,在下次调用函数时,会依然保存上一次函数调用结束之后的值。
静态局部变量在静态存储区内分配存储单元,且在程序整个运行期间都不释放。
对于静态局部变量只执行一次初始化(无论函数调用多少次)。
如果在定义静态局部变量时不赋初值的话,会自动赋初值为0(对数值型变量)或空字符(对字符型变量)。
静态局部变量的作用域为当前的函数,而不能被外界函数或文件访问。
如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以免每次调用时都重新赋值。
二、静态全局变量:
静态全局变量只限于被本文件引用,而不能被其他文件应用。
extern存储类型:(全局变量,静态存储区)
一、在一个文件内声明全局变量:
如果在定义全局变量之前的函数想引用该全局变量,则应该在引用之前用关键字extern对该变量作全局变量声明(如“extern int a;”),表示该变量是一个将在下面定义的全局变量。(这种声明称为提前引用声明)
一般都把全局变量的定义放在引用它的所有函数之前,这样可以避免在函数中多加一个extern声明。
二、在多文件的程序中声明全局变量:
如果一个程序由多个源文件组成,那么可以在一个文件中定义一个全局变量,而在另一些文件中用extern对该变量作全局变量声明。(externint a;)
变量的声明只是告知编译器变量的名称和数据类型,而不会为变量分配存储空间;变量的定义则将为变量分配存储空间。通常情况下,变量的声明也被认为是变量的定义。但是可以使用extern关键字只声明而不定义变量,这样就可以在其他文件中共享同一个全局变量了。
register存储类型:(寄存器变量) (局部变量和函数参数,CPU寄存器)
如果有一些变量使用频繁,C++允许将局部变量的值放在CPU的寄存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。由于对寄存器的存取速度远高于对内存的存取速度,因此这样做可以提高执行效率。
寄存器变量只能用于局部变量或作为函数的形式参数,而不能够定义全局的寄存器变量。
寄存器变量不能够保证将变量放置在寄存器中,也不能保证提高访问速度,它只是对编译器的一个“建议”。当今的编译系统能够识别使用频繁的变量,从而自动地将这些变量放在寄存器中,而不需要程序设计者指定。
注意:
因为全局变量一直占用存储单元,且会使函数的通用性降低,使程序的清晰性降低,所以应限制使用全局变量。
如果在同一个代码块中,全局变量与局部变量同名,则在该局部变量的作用范围内,全局变量被屏蔽,即它不起作用。(就近原则)
用静态变量要多占内存(长期占用不释放,不能像动态存储那样一个存储单元可先后供多个变量使用,节约内存),而且降低了程序的可读性。因此,如不必要,不要多用静态变量。
auto,static和register三种存储类别只能用于变量的定义语句中;extern只能用来声明已定义的全局变量,而不能用于变量的定义。