3.程序流程控制

3. 程序流程控制

通过流程控制语句,让我们对代码的执行有着更多、更精确的控制,可以根据各种条件执行不同的程序逻辑。在VB.NET中,我们使用的流程控制语句主要包括条件语句结构、选择语句结构和循环语句结构。

本章,我们就来讨论相关内容,包括:

  • 条件语句结构
  • 选择语句结构
  • 循环语句结构
  • Exit语句
  • Continue语句
  • Goto语句与标签

3.1. 条件语句结构

在VB.NET中,条件语句结构的基本格式如下:

If <条件> Then
    <语句块>
End If

当<条件>成立(True值)时,执行<语句块>的代码,然后执行End If语句后面的内容;如果<条件>不成立,则直接执行End If后面的代码。对于这种格式的If...End If语句,如果<语句块>只有一条语句,我们还可以简写为一行,如下面的格式:

If <条件> Then <语句>

如下面的代码会判断一个整数是否为偶数。

Dim num As Integer = 10
If num Mod 2 = 0 Then
    Console.WriteLine("{0}是偶数", num)
End If

或者是:

Dim num As Integer = 10
If num Mod 2 = 0 Then Console.WriteLine("{0}是偶数", num)

一般情况下,我们应该处理条件成立或不成立的两种情况,此时,我们应该在If...End If语句结构中使用Else语句块,如下面的代码。

Dim num As Integer = 10
If num Mod 2 = 0 Then
    Console.WriteLine("{0}是偶数", num)
Else
    Console.WriteLine("{0}不是偶数", num)
End If

当然,在实际应用中,我们还可以使用更复杂的条件结构,如:

If <条件1> Then
    <语句块1>
ElseIf <条件2> Then
    <语句块2>
ElseIf <条件n> Then
    <语句块n>
Else
    <语句块n+1>
End If

其中,我们设定1到n个条件,当条件成立时就执行相应的语句块,如果条件都不成立就执行<语句块n+1>。

3.2. 选择语句结构

在VB.NET中的选择语句结构,我们使用Select Case语句,它的基本使用格式如下:

Select Case <表达式>
    Case <值1>
        <语句块1>
    Case <值2>
        <语句块2>
    Case <值n>
        <语句块n>
    Case Else
        <语句块n+1>
End Select

在选择语句结构中,确定代码执行的条件只有一个,即<表达式>的值;然后,每一个Case语句都对应指定值,如果<表达式>的值与其对应,则执行相应的代码块。如果没有相对应的值,则执行<语句块n+1>;虽然Case Else语句是可选的,但能够处理任何情况总是比较安全的。

如下面的代码,我们将根据不同的颜色英文名称显示其中文名称。

Dim colorEn As String = "red"
Select Case colorEn
    Case "red"
        Console.WriteLine("红色")
    Case "green"
        Console.WriteLine("绿色")
    Case "blue"
        Console.WriteLine("蓝色")
    Case Else
        Console.WriteLine("未知颜色")
End Select

我们使用Select Case语句结构时,如果你学习过C风格的switch语句结构,它们之间会有一些不同,如:

在Select Case语句中,不存在自动向下贯穿,也就是说每个Case语句执行完成后就会自动结束整个Select Case语句结构,不需要C语言中的break等语句来中断。

Case语句后面的值可以是一个,也可以有多个,并不像C语言中每个case语句只能指定一个值。如下面的代码,将根据年份和月份给出月份中的总天数。

Dim iYear As Integer = 2016
Dim iMonth As Integer = 2
Dim iDay As Integer = 0
Select Case iMonth
    Case 1, 3, 5, 7, 8, 10, 12
        iDay = 31
    Case 4, 6, 9, 11
        iDay = 30
    Case 2
        iDay = IIf(Date.IsLeapYear(iYear), 29, 28)
End Select
Console.WriteLine("{0}年{1}月共有{2}天", iYear, iMonth, iDay)

实际上,以上代码的功能在Date中的DaysInMonth()方法就可以实现,我们在这里只是为了演示Case语句同时指定多个值的情况。关于日期和时间的更多处理,会在第16章有更多讨论。

此外,当月份为2时,我们使用了IIf()函数,它的格式是:

IIf(<条件>, <值1>, <值2>)

当<条件>成立时,返回<值1>,否则返回<值2>。如果你在C风格的编程语言中使用过?:运算符,它们的功能是相同的。此外,这也可以看作是一个简单的If...Else...End If语句结构。

3.3. 循环语句结构

循环语句结构的功能就是在满足一定条件的情况下,可以多次执行相同或相似的代码,在VB.NET中,常用的循环语句结构包括:

  • For...Next
  • Do...Loop
  • While...End While
  • For Each...Next

接下来,我们就详细讨论它们的使用。

3.3.1. For...Next

使用For...Next语句结构,最基本的格式如下:

For <循环控制变量> = <初始值> To <终止值> Step <步长>
    <代码块>
Next

如下面的代码,我们将计算1到100整数的和。

Dim iSum As Integer = 0
For i = 1 To 100 Step 1
    iSum += i
Next
Console.WriteLine("计算结果是{0}", iSum)

在这个For...Next语句结构中,我们使用了循环控制变量i,它的初始值是1,最大值是100,步长(Step)是1;也就是说,i的值从1(最小值)开始,每一次循环后会自动加1(步长),当i的值大于100(最大值)时,执行循环语句后就终止整个For...Next语句结构。

请注意,当步长(Step)为1时,我们可以省略Step关键字及步长值,如下面的代码:

For i = 1 To 100
    iSum += i
Next

如果我们需要计算1到100中偶数的和,可以使用如下代码。

For i = 2 To 100 Step 2
    iSum += i
Next

在For...Next语句结构中,我们还可以指定循环控制变量的类型,如:

For i As Integer = 2 To 100 Step 2
    iSum += i
Next

实际应用中,循环控制变量可以使用整型、浮点型或Decimal类型。

此外,在循环语句中,我们使用了“iSum += i”语句,了解C风格编程语言的一定很熟悉它的功能了,它的功能和“iSum = iSum + i”语句是相同的。对于VB.NET中其它的一些运算符,我们也可以使用这样的组合,如/=、*=、-=等。

3.3.2. Do...Loop

Do...Loop的功能很强,使用起来也很灵活,比如,我们可以将循环的控制条件放在Do关键字后,也可以放在Loop关键字后,它们的区分在于对循环条件判断的时机不同。

我们先看下面的应用格式:

Do While <条件>
    <语句块>
Loop

当<条件>成立时,会执行<语句块>的内容。但我们应该注意,在<语句块>中,应该有改变<条件>的语句,否则,循环结构就无法结束,从而导致死循环,最终会导致应用的崩溃。

如下面的代码,我们使用Do...Loop语句结构来完成1到100的累加计算。

Dim iSum As Integer = 0
Dim i As Integer = 1
Do While i <= 100
    iSum += i
    i += 1
Loop
Console.WriteLine("计算结果是{0}", iSum)

请注意,在循环执行的代码中,我们使用了“i += 1”语句,在每次执行循环后,i的值都会加1。实际上,在本例中,我们同样是使用变量i作为循环的控制条件,只是需要我们的代码来改变它的值,而不是像For...Next语句结构中那样自动改变它的值。

使用Do...Loop语句结构的另一种格式是将<条件>放在Loop语句后面,如下面的格式。

Do
    <语句块>
Loop While <条件>

与前面一种使用方式的不同在于,当我们将循环条件放在Do语句后时,会在每一次执行循环代码之前检查条件是否成立;而将循环条件放在Loop语句后时,会在每一次执行循环代码之后检查条件是否成立,也就是说,当条件在Loop语句后时,循环结构中的<语句块>最少会执行一次。

我们应注意,在没有对条件进行检查之前就执行循环代码并不是一个好的方法,因为条件有可能在一开始就不成立,此时执行一次循环语句都是不正确的;所以,我们还是应该更多地使用将条件放在Do语句后面的循环结构,即在循环执行之前进行条件的判断。

在Do...Loop循环结构中,除了使用While语句指定条件,我们还可以使用Until语句来指定条件。从字面上,我们也可以看出它们的区别:

  • While语句指定条件时,当条件成立时才会执行循环结构中的代码。
  • Until语句指定条件时,指定的条件成立时就会退出循环结构的执行。

此外,Until语句指定条件,同样可以放在Do语句或Loop语句后。如下面的语句,同样是计算1到100的和。

Do Until i > 100
    iSum += i
    i += 1
Loop

3.3.3. While...End While

While...End While语句结构的使用格式如下:

While <条件>
    <语句块>
End While

实际上,我们可以看到,While...End While语句结构就是Do While...Loop语句结构的简化形式,如下面的代码,我们使用While...End While语句重写1到100累加计算。

Dim iSum As Integer = 0
Dim i As Integer = 1
While i <= 100
    iSum += i
    i += 1
End While
Console.WriteLine("计算结果是{0}", iSum)

3.3.4. For Each...Next

For Each...Next语句结构可以帮助我们快速的访问集合(Collection)中的所有成员,在第14章,我们还会有详细的讨论,现在,我们先来看一个简单示例。

Dim arr As New ArrayList
arr.Add("abc")
arr.Add("def")
arr.Add("ghi")
For Each item As String In arr
    Console.WriteLine(item)
Next

我们首先创建了一个数组列表对象arr,然后添加了三个字符串成员;最后,我们使用For Each...Next语句逐一访问这些成员,并输出到控制台。从这个示例中,我们可以了解For Each...Next语句结构的基本应用格式。

For Each <成员变量及类型> In <集合对象>
    <代码块>
Next

<成员变量及类型>中,我们定义了表示集合中一个成员的变量,并可以指定其类型(也可以不指定,默认为Object类型);不过,当我们指定了成员变量的类型以后中,在循环结构内就可以更精确地操作它们。

在第14章,学习了更多的集合类型以后,我们会看到集合类资源在开发中的功能和作用都是非常强大的。

3.4. Exit语句

在循环语句结构中,我们可以在满足某些特定条件时就立即终止循环的执行,此时,我们使用Exit语句,它有几个变形:

  • Exit For语句,用于退出For...Next或For Each...Next循环结构。
  • Exit Do语句,用于退出Do...Loop循环结构。
  • Exit While语句,用于退出While...End While循环结构。

比如下面的代码,其功能是,当item的内容等于"ghi"时就退出循环,不再显示内容。

For Each item As String In arr
    If item = "ghi" Then Exit For
    Console.WriteLine(item)
Next

Exit语句除了可以使用在循环语句中,还可以使用在其它语句结构中,如选择语句结构(Select Case),或者是我们在后续内容将要学习到的子程序(Sub)、函数(Function)、属性(Property)或Try语句结构。

3.5. Continue语句

Continue语句用于循环语句,它的功能是中断当前循环,并开始下一次的循环(当满足条件时)。如下面的代码,我们将利用Continue语句来完成1到100偶数的累加计算。

Dim iSum As Integer = 0
For i = 1 To 100
    If i Mod 2 <> 0 Then Continue For
    iSum += i
Next
Console.WriteLine("计算结果{0}", iSum)

我们可以看到,Continue语句同样使用了变形,即Continue For语句,它用于中断并执行下一个For循环。相应的Continue变形还有:

  • Continue Do语句,用于中断并执行下一个Do循环。
  • Continue While语句,用于中断并执行下一个While循环。

3.6. Goto语句与标签

首先,我们必须声明,非万不得已,不要使用Goto语句,因为它会造成代码结构的混乱,并极可能产生不易查找的错误。

在VB.NET代码中,我们可以在需要的位置定义标签,其格式如下:

<标签名称>:

然后,我们可以使用Goto语句跳转到指定的标签位置,如:

Goto <标签名称>

Goto语句和标签的是早期BASIC中的产物,在VB.NET保留它们是为了兼容早期的VB代码(也许只是情怀在作怪^^)。下面的代码,我们将使用标签和Goto语句模拟循环操作,以此向BASIC致敬!

Dim iSum As Integer = 0
Dim iCounter As Integer = 1
Tag_Add:
iSum = iSum + iCounter
iCounter = iCounter + 1
If iCounter <= 100 Then Goto Tag_Add
Console.WriteLine(iSum)

代码中,我们定了一个标签Tag_Add,然后进行累加操作,当计数变量iCounter小于等于100时,就跳转回Tag_Add标签,然后进行累加和计数变量加1的操作;当iCounter大于100时,会显示计算结果,即1到100累加的结果。

到这里,相信大家已经可以编写基本的代码了,下一章,我们将讨论如何在项目中组织和封装自己的代码。

目录

  • 前言
  • 1.概述
  • 2.基本数据类型
  • 3.程序流程控制
  • 4.代码组织与封装
  • 5.枚举
  • 6.结构
  • 7.面向对象编程
  • 8.类的继承
  • 9.接口
  • 10.设计模式基础
  • 11.事件与委托
  • 12.泛型
  • 13.异常处理
  • 14.数组与集合
  • 15.字符串与散列算法
  • 16.日期与时间
  • 17.文件系统
  • 18.图形图像
  • 19.网络
  • 20.数据库应用基础
  • 21.创建数据层组件
  • 22.获取系统信息
  • 23.Windows窗体应用代码封装
  • 24.ASP.NET应用开发基础