8.2 局部变量和常量
相对于类的字段变量,定义在方法内的本地变量叫做局部变量,它在使用前必须初始化,而字段变量不需要,字段变量如果没有初始化,会被自动初始化为默认值。在4.1.4节我们学习了var关键字,编译器可以根据变量的初始值来推断变量的类型,要知道var关键字只能用于局部变量,关于var关键字和类型推断的详细知识请参考4.1.4节。
方法体本身是一个代码块,在它之中还可以包含更多的代码块,不管这些块是顺序的还是在更深的嵌套块中。局部变量,顾名思义,它的有效范围仅在定义它的块及其内部块有效,而出了这个范围则是无效的,这个有效范围称做变量的作用域。因此,下面这段代码在C++中有效,而在C#中却是无效的,这一点需要引起大家注意。如代码清单8-1所示。
代码清单8-1 局部变量的作用域
1 int m=1;
2 if(m!=0)
3{
4 double m=1.0f;
5}
上述代码编译器会产生如下错误信息:
不能在此范围内声明名为"m"的局部变量,因为这样会使"m"具有不同的含义,而它已在“父级或当前”范围中表示其他内容了
这是因为定义在if嵌套块中的变量m和其父代码块中的m产生了冲突,可见定义于第1行的int型变量m,其作用域不但在所在的代码块,还“穿透”了其中的嵌套块,导致和定义于第4行的double型变量冲突。
下面,我们使用图8-3来说明变量的作用域。
图 8-3 局部变量的作用域
图8-3显示了两个局部变量的作用域,并展示了它们在托管堆栈中的情况:
❑变量a声明在方法体中,在if语句的代码块之前,此刻对应状态①;
❑变量b声明在if语句的代码块内部,它从声明之后开始存在,此刻对应状态②;
❑if代码块结束,变量b从托管堆栈中弹出,此刻对应状态③。
上面我们讲述了局部变量,现在来说说作用域相同的局部常量,我们在4.2节已经讲了常量的概念,此处的局部常量也是常量的一种,只是其某些特性更加类似局部变量,如其作用域仅限于在声明它的块范围内,包括块中的嵌入块,其他则和一般常量无异,如:
❑必须在声明的时候就立即初始化,其值在初始化后将无法再进行更改;
❑必须使用显式类型声明,不能使用类型推断关键字:var;
❑无法接受变量的赋值,哪怕该变量是static并且是readonly也不行,常量在初始化时只能使用另一个常量为它赋值,当然,直接赋予一个具体的值更好。