[心得]ASP.net 的For迴圈Bug

使用環境:Microsoft Visual Web Developer 2008 Express Edition
使用語言:ASP.net (Visual Basic)

我們好常用的For迴圈,一般來說是可以會更新終止值的(我暫時取叫  n  )
但在這裡出現了個很奇特的狀況,ASP.net 的For迴圈,終止值不會被更新

 

——————————————————————————————————————

在C語言裡,我們的For迴圈是由while所改良而成,寫法如下

int i, n;

n=10;

for(i=0;i<=n;i++)

{

        printf(“%d\n”, i);

}

以上大略的意思是,初始化 i 為0,若 i 還是小於或等於10的話,就繼續迴圈
執行完裡面的敘述後(就是印出 i 值),i  自己加1
如果用while寫,應該是長這樣子的

int i, n;

i=0;

n=10;

while(i<=n)

{

        printf(“%d\n”, i);

        i++;

}

——————————————————————————————————————

回到ASP.net (Visual Basic)裡,我寫了幾個測試程式,用好幾個按鈕來執行

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click

        Response.Write(“測試 n 值變小<br>”)

        Dim i, n As Integer

        n = 10

        For i = 0 To n

            If i = 5 Then

                n = 8

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “<br>” & vbCrLf)

        Next

    End Sub

 

    Protected Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click

        Response.Write(“測試 n 值變大<br>”)

        Dim i, n As Integer

        n = 10

        For i = 0 To n

            If i = 5 Then

                n = 20

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “<br>” & vbCrLf)

        Next

    End Sub

 

    Protected Sub Button3_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button3.Click

        Response.Write(“測試 i 值變小<br>”)

        Dim i, n As Integer

        Dim flag As Boolean

        n = 10

        For i = 0 To n

            If i = 7 And flag <> True Then

                i = 0

                flag = True

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “flag=” & CStr(flag) & “<br>” & vbCrLf)

        Next

    End Sub

 

    Protected Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click

        Response.Write(“測試 i 值變大<br>”)

        Dim i, n As Integer

        n = 13

        For i = 0 To n

            If i = 2 Then

                i = 7

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “<br>” & vbCrLf)

        Next

    End Sub

 

    Protected Sub Button5_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button5.Click

        Response.Write(“測試 n 值變小(while版)<br>”)

        Dim i, n As Integer

        n = 10

        i = 0

        While i <= n

            If i = 5 Then

                n = 8

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “<br>” & vbCrLf)

            i += 1

        End While

    End Sub

 

    Protected Sub Button6_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button6.Click

        Response.Write(“測試 n 值變大(while版)<br>”)

        Dim i, n As Integer

        n = 10

        i = 0

        While i <= n

            If i = 5 Then

                n = 20

            End If

            Response.Write(“i=” & CStr(i) & ”   “ & “n=” & CStr(n) & “<br>” & vbCrLf)

            i += 1

        End While

    End Sub

 執行結果:

測試 n 值變小
i=0 n=10
i=1 n=10
i=2 n=10
i=3   n=10
i=4   n=10
i=5   n=8
i=6   n=8
i=7   n=8
i=8   n=8
i=9   n=8
i=10 n=8

測試 n 值變大
i=0   n=10
i=1   n=10
i=2   n=10
i=3   n=10
i=4   n=10
i=5   n=20
i=6   n=20
i=7   n=20
i=8   n=20
i=9   n=20
i=10 n=20

測試 i 值變小
i=0   n=10  flag=False
i=1   n=10  flag=False
i=2   n=10  flag=False
i=3   n=10  flag=False
i=4   n=10  flag=False
i=5   n=10  flag=False
i=6   n=10  flag=False
i=0   n=10  flag=True
i=1   n=10  flag=True
i=2   n=10  flag=True
i=3   n=10  flag=True
i=4   n=10  flag=True
i=5   n=10  flag=True
i=6   n=10  flag=True
i=7   n=10  flag=True
i=8   n=10  flag=True
i=9   n=10  flag=True
i=10 n=10  flag=True

測試 i 值變大
i=0   n=13
i=1   n=13
i=7   n=13
i=8   n=13
i=9   n=13
i=10 n=13
i=11 n=13
i=12 n=13
i=13 n=13

測試 n 值變小(while版)
i=0 n=10
i=1 n=10
i=2 n=10
i=3 n=10
i=4 n=10
i=5 n=8
i=6 n=8
i=7 n=8
i=8 n=8

測試 n 值變大(while版)
i=0   n=10
i=1   n=10
i=2   n=10
i=3   n=10
i=4   n=10
i=5   n=20
i=6   n=20
i=7   n=20
i=8   n=20
i=9   n=20
i=10 n=20
i=11 n=20
i=12 n=20
i=13 n=20
i=14 n=20
i=15 n=20
i=16 n=20
i=17 n=20
i=18 n=20
i=19 n=20
i=20 n=20

 

從上面的程式執行結果看到,測試 n 值變小的時候,本來已經更改成8次就結束了
但程式還是執行10次。在while中同個寫法,就不會有這個問題。

測試n 值變大的時候也是一樣,應該程式應該迴圈執行滿20次,但只有執行10次

 

所以要注意For迴圈這個特殊的BUG,以避免資料有缺失或是索引超出範圍,怎麼抓都抓不到的BUG。

(註記1:在Visual Studio 2008 裡,在IDE環境裡複製程式碼,到Word 2007貼上,雖然有漂亮的程式碼顏色,但要注意中文字中文字之間夾雜的英文數字消失不見,關於這個BUG,改天再截圖給大家)

(註記2:同樣的方式貼上到FrontPage 2003,中文字會全部消失不見,這個嚴重的BUG也是其中之一,有空再實驗貼到哪裡才會正常顯示)

在〈[心得]ASP.net 的For迴圈Bug〉中有 1 則留言

  1. 這應該不是VB的bug唷!! 這是語言的特性,而且在MSDN文件中裡面就有說明了:
    「Visual Basic 在迴圈開始之前,只會評估反覆運算值 start、end 和 step 一次。如果陳述式區塊變更 end 或 step,這些變更並不會影響迴圈的重複值。」
    參考網址:http://msdn.microsoft.com/zh-tw/library/5z06z1kb%28v=VS.90%29.aspx
    版主回覆:(08/03/2010 03:00:28 AM)
    抱歉,可能是我措辭太重了,好手大 說的才是對的

留言功能已關閉。