全局变量和局部变量哪个优先 VB.NET循环体内的局部变量
VB.NET循环体内的局部变量
我们知道 在类或者结构初始化的时候 成员变量最好不要显式赋以 Nothing False等初值 这样不但没有必要而且会降低性能 因为成员变量首先会被分配内存空间 并且该内存空间自动用 进行初始化 因此显式的赋值会增加指令操作而影响性能
但如果是局部变量呢?
一般情况下 如果不显式初始化局部变量 局部变量会被自动也赋以空值 或者false
例如以下代码

Dim b As Boolean Console WriteLine(b) Dim rnd As Random If rnd Is Nothing Then Console WriteLine( yes ) End If
最终会输出 false yes
不过对于引用类型的Random 编译器会给出 变量 rnd 在赋值前被使用 可能会在运行时导致 null 引用异常 的警告 值类型则没有任何警告
ok 再来看下这段代码
Module Module Module Module Sub Main()Sub Main() Dim rnd As New Random( ) For i As Integer = To Dim b As Boolean Console WriteLine(b) If rnd NextDouble > Then b = True End If Next End Sub End Module
Module Module
Sub Main() Dim rnd As New Random( ) For i As Integer = To Dim b As Boolean Console WriteLine(b) If rnd NextDouble < Then b = True End If Next For i As Integer = To Dim rnd As Random If rnd Is Nothing Then Console WriteLine( yes ) Else Console WriteLine( no ) End If rnd = New Random Next End Sub
End Module
照说每次循环都重新定义并初始化该局部变量 期望的输出值应该一直都是false
但猜猜实际最终输出结果是什么 false false false true true!!
就是这个怪诞的行为让我困扰了很久
ok 我们看看对应的il代码
method public static void Main() cil managed{ custom instance void [mscorlib]System STAThreadAttribute:: ctor() entrypoint maxstack locals init ( [ ] class [mscorlib]System Random rnd [ ] bool b [ ] int i [ ] bool VB$CG$t_bool$S [ ] int VB$CG$t_i $S [ ] int num) L_ : nop L_ : ldc i x e L_ : newobj instance void [mscorlib]System Random:: ctor(int ) L_ b: stloc L_ c: ldc i L_ d: stloc L_ e: ldloc L_ f: call void [mscorlib]System Console::WriteLine(bool) L_ : nop L_ : ldc i L_ : stloc L_ : nop L_ : ldloc L_ : ldc i L_ a: add ovf L_ b: stloc L_ c: ldloc L_ d: ldc i L_ e: stloc s num L_ : ldloc s num L_ : ble s L_ e L_ : ldc i L_ : stloc s VB$CG$t_i $S L_ : ldloc L_ : call void [mscorlib]System Console::WriteLine(bool) L_ d: nop L_ e: ldc i L_ f: stloc L_ : nop L_ : ldloc s VB$CG$t_i $S L_ : ldc i L_ : add ovf L_ : stloc s VB$CG$t_i $S L_ : ldloc s VB$CG$t_i $S L_ : ldc i L_ a: stloc s num L_ c: ldloc s num L_ e: ble s L_ L_ : nop L_ : ret }
晕 编译器居然自动把变量b声明提升到循环体之外 因此就出现了上述的行为 (注 晕啊 以前学c的时候 就学过for(;;){int i= ;}里 i只在第一次声明 以前的基础知识全部忘光光 感谢psic的指正 )
我个人猜测 编译器这样做的原因大概是为了性能 可是这样实在是容易造成奇异的行为 最郁闷的是 值类型的变量 编译器根本连警告都没有
所以 VB NET中使用局部变量 尤其在循环体内使用局部变量 一定要进行初始化
lishixinzhi/Article/program/net/201311/15512