For循环中的奇怪行为...? [英] Weird behaviour in For loop...?

查看:104
本文介绍了For循环中的奇怪行为...?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是看着我编写的一些代码,想知道为什么它不起作用.
简而言之,它看起来像这样...

I was just looking at a bit of code I had written and wondered why it didn''t work.
Down to basics, it looked something like this...

For i As Integer = 0 To 9
   Dim j As Integer
   j += 10
   If j = 10 Then
      Console.WriteLine("j is 10")
   End If
Next

您多久会打印一次"j is 10"?我确信它将被打印10次,每次迭代一次.我错了!它仅在第一次打印,因为第二次迭代将是20,然后是30,依此类推.这让我感到非常奇怪,因为j是在For循环内声明的,并且在每次迭代时都声明,但是它的行为就像在迭代外声明的一样,并且该值携带"到下一个迭代中.

我不认为这种行为会在C#中引起,因为您需要在使用变量之前为它分配一个值(因此j每次迭代之前总是必须将其设置为默认值).您可以在每次迭代之前检查j是否具有值,但是可以通过设置断点来检查j是否具有值,但是它永远不会在运行时中断".

我使用了很多For循环,但从未遇到过.
任何人都可以解释为什么j在迭代之后没有超出范围吗?还是我只是在疯狂地说话?
谢谢.

How often do you think "j is 10" would be printed? I was sure it would be printed 10 times, once for each iteration. How wrong I was! It is only printed the first time because the second iteration it will be 20, then 30 and so on. This strikes me as very odd because j is declared within the For loop and is declared at every iteration, yet it behaves as if it was declared outside the iteration and the value is ''carried onto'' the next iteration.

I don''t think this behaviour can be caused in C# since you need to assign a value to a variable before you use it (so j will always have to be set at a default value before each iteration). You can check that j has a value before each iteration, but the first by setting a breakpoint, but it will never ''break'' at runtime.

I''ve used many For loops, but never came across this one.
Could anyone explain why j does not go out of scope after an iteration? Or am I just talking crazy?
Thanks.

推荐答案

我在MSDN上找到了它:
I found this on MSDN:

即使变量的范围仅限于块,其寿命仍然是整个过程的寿命.如果在此过程中多次输入该块,则每个块变量将保留其先前的值.为了避免在这种情况下出现意外结果,明智的做法是在块的开头初始化块变量.

Even if the scope of a variable is limited to a block, its lifetime is still that of the entire procedure. If you enter the block more than once during the procedure, each block variable retains its previous value. To avoid unexpected results in such a case, it is wise to initialize block variables at the beginning of the block.

因此,j变量在第一次迭代时仅为其赋予默认值0,然后保留该默认值

So the j variable is only given it''s default value 0 the first iteration and after that retains the value it has at the end of the block.


并确认André,此VB代码为:
And to confirm André, this VB code:
Sub Main()
    For i As Integer = 0 To 9
        Dim j As Integer
        j += 10
        If j = 10 Then
            Console.WriteLine("j is 10")
        End If
    Next

    Dim jp As Integer

    For i As Integer = 0 To 9
        jp += 10
        If jp = 10 Then
            Console.WriteLine("j is 10")
        End If
    Next

End Sub


通过ILSpy提供此反编译的VB:


Gives this decompiled VB via ILSpy:

' ForNextTest.Module1
<stathread()>
Public Shared Sub Main()
	Dim i As Integer = 0
	' The following expression was wrapped in a checked-statement
	Dim arg_2B_0 As Integer
	Dim num As Integer
	Do
		Dim j As Integer
		j += 10
		Dim flag As Boolean = j = 10
		If flag Then
			Console.WriteLine("j is 10")
		End If
		i += 1
		arg_2B_0 = i
		num = 9
	Loop While arg_2B_0 <= num
	Dim k As Integer = 0
	Dim arg_57_0 As Integer
	Do
		Dim jp As Integer
		jp += 10
		Dim flag As Boolean = jp = 10
		If flag Then
			Console.WriteLine("j is 10")
		End If
		k += 1
		arg_57_0 = k
		num = 9
	Loop While arg_57_0 <= num
End Sub


IE.两个Do...Loop While块都相同.

有趣的是,编译器决定,由于第二个For...Next循环使用相同的标识符(i),它将使用不同的标识符,大概是因为For...Loop指定了一个起始值(在这种情况下为0),等效于,并且优先于在其中填充i = 0行(您没有写过).

因此,如果您没有为变量指定一个新值,而For...Loop会这样做,那么如果您再次使用它,它将保留先前的值-这就是André(MSDN)所说的那样,令人讨厌. ,总会正确(ish).

IL代码为:


I.e. both Do...Loop While blocks are identical.

Interestingly, the compiler decides that since the second For...Next loop uses the same identifier (i), it will use different ones, presumably since a For...Loop specifies a starting value (0 in this case), equivalent to i = 0, and it does that in preference to stuffing an i = 0 line (that you didn''t write) in there.

So, if you don''t specify a new value for a variable, which a For...Loop does, then it will retain the prior value if you use it again - which is what André (MSDN) says, elephanting annoying folk they are, always elephanting right(ish).

The IL Code is:

.method public static 
	void Main () cil managed 
{
	.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = (
		01 00 00 00
	)
	// Method begins at RVA 0x2108
	// Code size 91 (0x5b)
	.maxstack 2
	.entrypoint
	.locals init (
		[0] int32 jp,
		[1] int32 i,
		[2] int32 j,
		[3] int32 i,
		[4] bool VB


CG


这篇关于For循环中的奇怪行为...?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆