Skip to content
On this page

使用 if 语句

运用最广泛的分支语句是 if 语句。 if 语句依赖布尔表达式,后者用一组括号括起来。如果表达式为 true,则执行 if 语句后面的代码。如果表达式为 false,则跳过 if 语句后面的代码。

使用 if 语句创建随机数游戏

我们来创造一种游戏,用于帮助我们编写 if 语句。我们将为该游戏创建几条规则,然后在代码中实现它们。

我们将使用 Random.Next() 方法来模拟抛掷三个六面骰子。我们将评估值以计算得分。如果得分大于任意总和,则向用户显示一条获胜消息。否则,向用户显示一条失败消息。

  • 如果抛掷任何两个骰子得到相同的值,则因两个骰子投出同样的点数获得两点奖励得分。
  • 如果抛掷全部三个骰子都得到相同的值,则因三个骰子投出同样的点数获得六点奖励得分。
  • 如果三个骰子投出的点数之和加上所有奖励点数大于等于 15,则你赢得比赛。否则,就是你输了。

随着我们加深对 if 语句的理解,我们会增加规则数量。

重要

我们将广泛使用 System.Random 类,相关介绍请参阅 使用 C# 从 .NET 类库调用方法 模块。如果你需要了解 Random.Next() 的工作原理,请参考该模块。

编写代码以生成三个随机数字并在输出中显示它们

csharp
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

我们会创建 System.Random 类的新实例,并将对该对象的引用存储在 dice 变量中。然后,我们会对 dice 对象调用三次 Random.Next() 方法,同时提供下限和上限,将可能的值限制在 16 之间。我们将这三个随机数字分别存储在变量 roll1roll2roll3 中。

接下来,我们将三个骰子投出的点数相加,并将该值保存到 total 变量中。

最后,我们使用字符串内插显示所有值。

运行代码时,应会看到以下消息(数字将会不同,因为它们是随机生成的):

输出

bash
Dice roll: 4 + 5 + 2 = 11

步骤 1 是设置步骤。现在,我们可以将决策逻辑添加到代码中,使游戏更加有趣。

添加一个 if 语句,以基于 total 变量的值显示不同的消息

修改上一步中的代码以包含 if 语句:

csharp
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if (total > 14)
{
    Console.WriteLine("You win!");
}

if (total < 15)
{
    Console.WriteLine("Sorry, you lose.");
}

我们添加了两个 if 语句来处理获胜和失败的场景。我们来看第一个 if 语句。

if 语句由 3 个部分组成:

  • if 关键字。
  • () 括起来的布尔表达式。
  • 由大括号 { } 定义的代码块。

在运行时,会计算布尔表达式 total > 14。如果该表达式为 true,并且 total 的值大于 14,则执行流程将执行代码块中定义的代码。换言之,它会执行大括号中的代码。

但是,如果该布尔表达式为 false,则执行流程将跳过该代码块。换言之,它不会执行大括号中的代码。

最后,第二个 if 语句控制表明用户是否失败的消息。在下一单元,我们将使用 if 语句的变体来将这两个语句精简为一个语句,同时更明确地表达我们的意图。

什么是布尔表达式

布尔表达式是返回布尔值(truefalse)的任意代码。最简单的布尔表达式是值 truefalse。此外,布尔表达式可以是返回值 truefalse 的方法的结果。例如,下面是一个简单的代码示例,它使用 string.Contains() 方法计算某个字符串是否包含另一个字符串:

csharp
string message = "The quick brown fox jumps over the lazy dog.";
bool result = message.Contains("dog");
Console.WriteLine(result);

if (message.Contains("fox"))
{
    Console.WriteLine("What does the fox say?");
}

由于 message.Contains("fox") 返回 truefalse 值,因此它符合作为布尔表达式的条件,可在 if 语句中使用。

其他简单的布尔表达式可通过使用运算符比较两个值进行创建。运算符包括:

  • ==,用于测试是否相等的“等于”运算符。
  • >,用于测试左边的值是否大于右边的值的“大于”运算符。
  • <,用于测试左边的值是否小于右边的值的“小于”运算符。
  • >=,“大于或等于”运算符。
  • <=,“小于或等于”运算符。
  • 等等

备注

我们将用整个模块来介绍布尔表达式。我们可以从许多运算符中进行选择,以构造一个布尔表达式,此处只会介绍一些基础知识。有关详细信息,请参阅 计算布尔表达式以在 C# 中做出决策 模块。

在示例中,我们评估了布尔表达式 total > 14。但是,我们本可选择布尔表达式 total >= 15,因此这两者在此情况下是等效的。鉴于我们游戏的规则规定“如果两个骰子投出的点数加上所有奖励得分大于等于 15,则你赢得游戏”,我们更喜欢后者。我们将在练习的下一步中进行此更改。

什么是代码块

代码块是包含一行或多行代码的集合,其中代码行由左大括号和右大括号 { } 定义。它表示在软件系统中用途单一的完整代码单位。在此情况下,如果布尔表达式为 true,则会在运行时执行代码块中的所有代码行。反之,如果布尔表达式为 false,则会忽略代码块中的所有代码行。

C# 中存在许多级别的代码块。实际上,.NET 编辑器隐藏了这样一个事实,即我们的代码是在定义某一方法的代码块中执行的。随着你开始使用 Visual Studio Code 或 Visual Studio IDE 编写 C# 代码,你将更深刻地了解此结构。

代码块可以包含其他代码块。我们将在本模块的稍后部分对此进行介绍,到时我们会在另一语句中嵌入一个 if 语句。

备注

我们将用整个模块来介绍代码块。代码块对于理解代码组织和结构至关重要,它们还定义了变量范围的边界。有关详细信息,请参阅 在 C# 中使用代码块控制变量范围和逻辑 模块。

再添加一个 if 语句来实现双倍奖励

接下来,我们将实现一个新规则:“如果抛掷任何两个骰子得到相同的值,则因两个骰子投出同样的点数获得两点奖励得分”。修改上述步骤中的代码以匹配以下代码清单:

csharp
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3))
{
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

if (total >= 15)
{
    Console.WriteLine("You win!");
}

if (total < 15)
{
    Console.WriteLine("Sorry, you lose.");
}

我们在这里合并了三个布尔表达式,以便在单行代码中创建一个大型布尔表达式。这种代码有时称作“复合条件”。我们有一组外括号,它包含由双竖线分隔符分隔的三组内括号。

双竖线分隔符 || 是“逻辑或”运算符,主要表示“要使整个布尔表达式为 true,要么左侧表达式必须为 true,要么右侧表达式必须为 true”。如果两个布尔表达式均为 false,则整个布尔表达式为 false。我们使用两个“逻辑或”运算符,以便可将计算扩展到第三个布尔表达式。

首先,我们评估 (roll1 == roll2)。如果它为 true,则整个表达式为 true。如果它为 false,则评估 (roll2 == roll3)。如果它为 true,则整个表达式为 true。如果它为 false,则评估 (roll1 == roll3)。如果它为 true,则整个表达式为 true。如果这三个表达式均为 false,则整个表达式为 false。

如果复合布尔表达式为 true,则执行后面的代码块。此时,有两行代码。第一行代码会将消息打印发送给用户。第二行代码将 total 的值增加 2

最后,我们还更改了检查内容,以查看用户是否成功使用了 >= 运算符。此方案更类似于我们开始时创建的要求,但其功能应与我们之前编写的函数类似。

csharp
if (total >= 15)

再添加一个 if 语句来实现三倍奖励

接下来,我们添加另一个新规则:“如果掷出的所有三个骰子的结果相同,则掷出三倍可获得六分奖励”。修改前面步骤中的代码以匹配以下代码清单:

csharp
Random dice = new Random();

int roll1 = dice.Next(1, 7);
int roll2 = dice.Next(1, 7);
int roll3 = dice.Next(1, 7);

int total = roll1 + roll2 + roll3;

Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");

if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3))
{
    Console.WriteLine("You rolled doubles! +2 bonus to total!");
    total += 2;
}

if ((roll1 == roll2) && (roll2 == roll3))
{
    Console.WriteLine("You rolled triples! +6 bonus to total!");
    total += 6;
}

if (total >= 15)
{
    Console.WriteLine("You win!");
}

if (total < 15)
{
    Console.WriteLine("Sorry, you lose.");
}

我们在这里合并了两个布尔表达式,以在单行代码中创建一个复合布尔表达式。我们有一组外括号,它包含由两个“与”字符分隔的两组内括号。

双与字符 && 是“逻辑与”运算符,主要表示“只有当两个表达式均为 true 时,整个表达式才为 true”。在此情况下,如果 roll1 等于 roll2,并且 roll2 等于 roll3,那么 roll1 必须等于 roll3 且用户投出了三倍奖励分数。

如果运行此代码,可能会看到以下示例所示的输出:

bash
Dice roll: 3 + 6 + 1 = 10
Sorry, you lose.
bash
Dice roll: 1 + 4 + 4 = 9
You rolled doubles! +2 bonus to total!
Sorry, you lose.
bash
Dice roll: 5 + 6 + 4 = 15
You win!
bash
# 如果足够幸运,则会看到如下输出:
Dice roll: 6 + 6 + 6 = 18
You rolled doubles! +2 bonus to total!
You rolled triples! +6 bonus to total!
You win!

但是等一下,我们真的应该让玩家同时获得三倍奖励分数和两倍奖励分数吗?毕竟,三个骰子投出相同的点数表示他们两个骰子也投出了相同的点数。理想情况下,此奖励不会叠加。它们应该是两个单独的奖励。我们的逻辑上存在第一个 bug。

逻辑上的问题以及改进代码的机会

虽然这是一个好的开始,而且我们也学到了许多关于 if 语句、布尔表达式、代码块、“逻辑或”和“逻辑与”运算符等等的知识,但仍然有很多可改进的地方。我们将在下一单元进行改进。

回顾

  • 使用 if 语句对代码逻辑进行分支。如果 if 决策语句的布尔表达式等于 true,它将执行其代码块中的代码。否则,运行时会跳过代码块并转到代码块后面的下一行代码。
  • 布尔表达式是返回布尔值的任何表达式。
  • 布尔表达式会比较其两侧的值是否相等,进行比较等操作。
  • 代码块由大括号 { } 进行定义。它会收集应被视为单个单元的代码行。
  • 逻辑与运算符 && 聚合两个表达式,以便这两个子表达式都必须为 true,才能使整个表达式为 true。
  • 逻辑或运算符 || 聚合两个表达式,因此如果其中一个子表达式为 true,则整个表达式为 true。