For...Next 语句 (Visual Basic)

重复一组语句,直到循环计数器达到其最终值。

语法

For counter [ As datatype ] = start To end [ Step step ]
    [ statements ]
    [ Continue For ]
    [ statements ]
    [ Exit For ]
    [ statements ]
Next [ counter ]

部件

部件 DESCRIPTION
counter 在 For 语句中是必需的。 数值变量。 用于循环的控制变量。 有关详细信息,请参阅本主题后面的“反驳论点”。
datatype 可选。 counter 的数据类型。 有关详细信息,请参阅本主题后面的“反驳论点”。
start 必填。 数值表达式。 counter 的初始值。
end 必填。 数值表达式。 counter 的最终值。
step 可选。 数值表达式。 每次通过循环递增 counter 的量。
statements 可选。 一个或多个语句在 For 和 Next 之间按照指定的次数运行。
Continue For 可选。 将控制权传输到下一循环迭代。
Exit For 可选。 将控制从 For 循环转移出去。
Next 必填。 终止For循环的定义。

注释

此 To 语句中使用关键字来指定计数器的范围。 您还可以在 Select...Case 语句 和数组声明中使用此关键字。 有关数组声明的信息,请参阅 Dim Statement。

简单示例

当你想要重复一组语句若干次时,请使用 For...Next 结构。

在下面的示例中,index 变量以值 1 开始,并在循环的每次迭代中递增,直到 index 的值达到 5 后结束。

For index As Integer = 1 To 5
    Debug.Write(index.ToString & " ")
Next
Debug.WriteLine("")
' Output: 1 2 3 4 5

在下面的示例中,变量 `number` 从 2 开始,每次循环迭代减少 0.25,循环在 `number` 变为 0 时结束。 Step 的 -.25 参数在循环每次迭代时将值减少 0.25。

For number As Double = 2 To 0 Step -0.25
    Debug.Write(number.ToString & " ")
Next
Debug.WriteLine("")
' Output: 2 1.75 1.5 1.25 1 0.75 0.5 0.25 0 

小窍门

当您事先不知道循环中语句运行的次数时,While...End While 语句 或 Do...Loop 语句 是很好的选择。 但是,当你期望运行循环的特定次数时, For...Next 循环是更好的选择。 首次进入循环时,可以确定迭代数。

嵌套循环

可以通过将一个循环置于另一个循环中来嵌套 For 循环。 以下示例演示具有不同步骤值的嵌套ForNext结构。 外部循环为循环的每个迭代创建一个字符串。 内部循环中,在每次迭代时递减一个循环计数器变量。

For indexA = 1 To 3
    ' Create a new StringBuilder, which is used
    ' to efficiently build strings.
    Dim sb As New System.Text.StringBuilder()

    ' Append to the StringBuilder every third number
    ' from 20 to 1 descending.
    For indexB = 20 To 1 Step -3
        sb.Append(indexB.ToString)
        sb.Append(" ")
    Next indexB

    ' Display the line.
    Debug.WriteLine(sb.ToString)
Next indexA
' Output:
'  20 17 14 11 8 5 2
'  20 17 14 11 8 5 2
'  20 17 14 11 8 5 2

嵌套循环时,每个循环必须具有唯一的counter变量。

还可以相互嵌套不同类型的控件结构。 有关详细信息,请参阅 嵌套控件结构。

退出并继续

语句 Exit For 会立即退出 For... Next 循环并立即将控制转移到 Next 语句后面的语句。

该 Continue For 语句将控制权立即传输到循环的下一次迭代。 有关详细信息,请参阅 Continue 语句。

下面的示例说明了如何使用 Continue For 和 Exit For 语句。

For index As Integer = 1 To 100000
    ' If index is between 5 and 7, continue
    ' with the next iteration.
    If index >= 5 AndAlso index <= 8 Then
        Continue For
    End If

    ' Display the index.
    Debug.Write(index.ToString & " ")

    ' If index is 10, exit the loop.
    If index = 10 Then
        Exit For
    End If
Next
Debug.WriteLine("")
' Output: 1 2 3 4 9 10

可以在Exit For中放置任意数量的For语句。 Next 循环。 在嵌套For 中使用 ... Next 循环,Exit For 退出最内部的循环,将控制转移到下一个更高级别的嵌套。

Exit For 通常在你评估某个条件(例如,在 If...Then...Else 结构中)之后使用。 你可能想要在以下情况中使用Exit For:

  • 继续循环迭代是不必要的或不可能的。 错误值或终止请求可能会创建此条件。

  • A Try...Catch...Finally 语句用于捕获异常。 可以在Exit For块末尾使用Finally。

  • 你有一个无休止的循环,这是一个循环,可以运行大量甚至无限次数。 如果检测到此类条件,可以使用 Exit For 来跳出循环。 有关详细信息,请参阅 Do...Loop 语句。

技术实现

当 For...Next 循环启动时,Visual Basic 会依次计算 start、end 和 step。 Visual Basic 在此时仅计算这些值,然后将其分配给 startcounter。 在语句块运行之前,Visual Basic 会将 counter 与 end 进行比较。 如果 counter 已大于 end 值(或小于值,如果 step 为负值),则 For 循环结束,控制权将传递给紧跟在 Next 语句后面的语句。 否则,语句块将运行。

每次 Visual Basic 遇到Next语句时,它会将counter递增step然后返回For语句。 再一次,它将 counter 与 end 进行比较,根据结果,要么运行代码块,要么退出循环。 此过程将继续执行,直到 counter 超过 end 或遇到 Exit For 语句。

循环直到counter已经超过end才会停止。 如果 counter 等于 end,循环将继续。 判断是否运行该块的比较为:当counter为正时,<end= step,当counter为负时,>end= step。

如果在循环中更改值 counter ,则代码可能更难读取和调试。 更改值 start, end或 step 不会影响首次输入循环时确定的迭代值。

如果嵌套循环,则编译器在内部级别的 Next 语句之前遇到外部嵌套级别的 Next 语句时,会发出错误信号。 只有当在每个counter语句中指定Next时,编译器才能检测到此重叠错误。

Step 参数

值可以是正值或负值 step 。 此参数根据下表确定循环处理:

步骤值 如果条件为真,循环执行
正数或零 counter <= end
消极 counter >= end

默认值 step 为 1。

反驳论点

下表指示 counter 是否定义在整个 For…Next 循环中有效的新局部变量。 此决定取决于是否存在 datatype 以及 counter 是否已定义。

datatype 是否存在? counter 是否已定义? 结果(counter 是否定义了一个作用域覆盖整个 For...Next 循环的新局部变量)
否 是的 否,因为 counter 已定义。 如果 counter 的作用域不是局部的,将会发生编译时警告。
否 否 是的。 从表达式start、end和step中推断数据类型。 有关类型推理的信息,请参阅 Option Infer 语句 和 本地类型推理。
是的 是的 是,但前提是现有 counter 变量在过程外部定义。 该变量保持独立。 如果现有 counter 变量的范围是过程本地的,则会发生编译时错误。
是的 否 是的。

确定迭代类型的数据类型 counter ,该类型必须是下列类型之一:

  • AByte、、SByte、UShort、Short、UInteger、Integer、ULongLong、、 Decimal或SingleDouble。

  • 使用Enum 语句声明的枚举。

  • 一个 Object。

  • 具有以下运算符的类型 T ,其中 B 是可在表达式中使用的 Boolean 类型。

    Public Shared Operator >= (op1 As T, op2 As T) As B

    Public Shared Operator <= (op1 As T, op2 As T) As B

    Public Shared Operator - (op1 As T, op2 As T) As T

    Public Shared Operator + (op1 As T, op2 As T) As T

可以选择在counter语句中指定Next变量。 此语法可提高程序的可读性,尤其是在具有嵌套 For 循环的情况下。 必须指定出现在相应 For 语句中的变量。

start、end 和 step 表达式的计算结果可以是扩大到类型 counter 的任何数据类型。 如果使用用户定义的类型counter,可能需要定义CType转换运算符,以便将类型start、end或step转换为counter类型。

示例 1

以下示例从泛型列表中删除所有元素。 而不是 For Each...Next 语句, 示例显示按降序循环访问的 For...Next 语句。 该示例使用此技术, removeAt 因为该方法会导致移除的元素之后的元素具有较低的索引值。

Dim lst As New List(Of Integer) From {10, 20, 30, 40}

For index As Integer = lst.Count - 1 To 0 Step -1
    lst.RemoveAt(index)
Next

Debug.WriteLine(lst.Count.ToString)
' Output: 0

示例 2

下面的示例循环访问通过使用 Enum 语句声明的枚举。

Public Enum Mammals
    Buffalo
    Gazelle
    Mongoose
    Rhinoceros
    Whale
End Enum

Public Sub ListSomeMammals()
    For mammal As Mammals = Mammals.Gazelle To Mammals.Rhinoceros
        Debug.Write(mammal.ToString & " ")
    Next
    Debug.WriteLine("")
    ' Output: Gazelle Mongoose Rhinoceros
End Sub

示例 3

在以下示例中,语句参数使用一个类,该类对+、-、>=和<=运算符进行了重载。

Private Class Distance
    Public Property Number() As Double

    Public Sub New(ByVal number As Double)
        Me.Number = number
    End Sub

    ' Define operator overloads to support For...Next statements.
    Public Shared Operator +(ByVal op1 As Distance, ByVal op2 As Distance) As Distance
        Return New Distance(op1.Number + op2.Number)
    End Operator

    Public Shared Operator -(ByVal op1 As Distance, ByVal op2 As Distance) As Distance
        Return New Distance(op1.Number - op2.Number)
    End Operator

    Public Shared Operator >=(ByVal op1 As Distance, ByVal op2 As Distance) As Boolean
        Return (op1.Number >= op2.Number)
    End Operator

    Public Shared Operator <=(ByVal op1 As Distance, ByVal op2 As Distance) As Boolean
        Return (op1.Number <= op2.Number)
    End Operator
End Class

Public Sub ListDistances()
    Dim distFrom As New Distance(10)
    Dim distTo As New Distance(25)
    Dim distStep As New Distance(4)

    For dist As Distance = distFrom To distTo Step distStep
        Debug.Write(dist.Number.ToString & " ")
    Next
    Debug.WriteLine("")

    ' Output: 10 14 18 22 
End Sub

另请参阅