您现在的位置是:首页 >

全局变量和局部变量哪个优先 VB.NET循环体内的局部变量

火烧 2021-07-17 16:44:59 1049
VB.NET循环体内的局部变量   我们知道 在类或者结构初始化的时候 成员变量最好不要显式赋以 Nothi g Fal e等初值 这样不但没有必要而且会降低性能 因为成员变量首先会被分配内存空间 并

VB.NET循环体内的局部变量  

  我们知道 在类或者结构初始化的时候 成员变量最好不要显式赋以 Nothing False等初值 这样不但没有必要而且会降低性能 因为成员变量首先会被分配内存空间 并且该内存空间自动用 进行初始化 因此显式的赋值会增加指令操作而影响性能

  但如果是局部变量呢?

  一般情况下 如果不显式初始化局部变量 局部变量会被自动也赋以空值 或者false

例如以下代码

全局变量和局部变量哪个优先 VB.NET循环体内的局部变量
        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  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码