我们知道,变量的一些属性决定了一个变量的“可视性”(它可以在什么地方使用)和“生命期”(它的值将保存多久),对于我们编写程序非常重要。
受此启发,最近总结一下变量所应具有的属性,特别总结记录下来。
1,名字属性
2,类型属性
3,值属性
4,作用域
5,链接属性
6,存储类型(包含生命期)
1,名字属性
所谓名字,其实就是标识符(identity),它由大小写字母、数字和下划线组成,但不能以数字开头。
2,类型属性
在C/C++语言中,仅有四种基本类型(type):整型、浮点型、指针和聚合类型(如数组和结构等),其他的所有类型都是从这4中基本类型的某种组合派生而来。
3,值属性
值属性就是根据自身类型,解析自身所占空间所获的值(value)。变量能够修改,常量来说,并不允许改变。
4,作用域
当变量在程序的某个部分被声明时,它只有在程序的一定区域内才能被访问。这个区域由标识符的作用域(scope)而定。标识符的作用域就是程序中,该标识符可以被使用的区域。例如,函数的局部变量的作用域就是该函数的函数体。在命名空间内定义的变量,作用域即是那个命名空间。
这个规则意味着两点:
(1)作用域之外的其他函数都无法通过这些变量的名字访问它们,因为,变量在作用域之外就无效
(2)只要分属不同的作用域,你可以给不同的变量其同一个名字。
C语言中,编译器可以确认4中不用的作用域:
(1)文件作用域(file scope):任何在代码块之外声明的标识符都具有文件作用域,这些标识符从他们开始声明之处直到他所在源文件结尾处都是可以访问的。
(2)函数作用域(function scope):它只是用与语句标签,语句标签用于goto语句,一个函数的所有语句标签必须唯一。
(3)代码块作用域(block scope):声明位于由一对大括号之间的变量,表示可以为这个代码块中的所有语句访问。
(4)原型作用域(prototype scope):只是用于在函数原型中声明的参数名。
C++中又多了两种:
(5)命名空间作用域(namespace scope):类似于代码块作用域。
(6)类作用域(class scope):在类中定义的变量,在类中可以访问。再类外时,’需要考虑三中访问限定符:public、protected、private。
5,链接属性
当组成一个程序的各个源文件被编译之后,所有的目标文件,以及那些从一个或多个函数库中引用的函数连接在一起,形成可执行程序。
就有可能出现:”相同的标识符出现在几个不同的源文件中。
标识符的链接属性(linkage)决定如何在不同文件中出现的标识符。
链接属性分3种:
(1)外部的(external):属于external链接属性的标识符不论声明多少次,位于几个源文件中,都表示同一个实体。
(2)内部的(internal):属于internal的标识符在同一个源文件内的所有声明都指向同一个个体,但位于不同源文件中的多个声明则分属不用的实体。
(3)无(none):没有链接属性的标识符总是别当做单独的个体,也就是说,该标识符的多个声明被当做独立不同的实体。
6,存储类型(包含生命期)
变量的存储类型(storage class)是指存储变量值的内存类型。
变量的存储类型决定变量何时创建、何时销毁以及他的值将保存多久。
有三个地方可以存储变量,并且变量具有不同的特性(主要是生命期):
(1)普通内存:在所有代码块之前声明,或在代码块中声明,用static修饰。存在静态内存中,称为静态(static)变量,值初始化为0,在程序运行之前创建,在程序的整个执行期间始终存在,它始终保存原来的值,除非给它赋值或程序结束。
(2)运行时堆栈:在代码块内声明的变量的缺省存储类型都是自动的(automatic),存储与堆栈中,称为自动变量(auto)。自动变量在代码块执行完毕后消失,当代码块再次执行时,它们的值与原来的值没有关系。
(3)硬件寄存器:register关键字可以用于自动变量的声明,提示它们应该存储在机器的硬件寄存器中,而不是内存中,这类变量称为寄存器变量。只是编译器并不一定理睬register关键字,将其作为自动变量处理。寄存器变量的创建和销毁和自动变量相同(生命期相同),只是需要一些额外的工作。
注:我们通常所说的变量的“可见性”和“生命周期”是由作用域、链接属性、存储类型相互影响所决定的。