跳到主要内容

条件语句简介

到目前为止,我们创建的程序每次都以相同的方式工作。我们的程序无法做出决策。现在是时候改变这种状况了。在本课中,我们将根据用户输入的内容,为程序提供分支路径。这将是一个指导性课程,我们将制作一个应用程序,检查用户是否可以合法地获得驾驶执照。😎

代码准备

我们首先询问用户的出生年份。

#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

// Case A:
std::cout << "You can legally get a driver's license\n";

// Case B:
std::cout << "You cannot legally get a driver's license\n";
}

在这里,我强调了两段代码——一段是用户可以合法获得驾驶执照的情况,另一段是他们不能合法获得驾驶执照的情况。我们只想执行其中一个片段,而不是两个都执行。我们怎么能做到这一点呢?首先,我们应该明确“情况”是什么,以及在什么条件下它们应该执行。

  • 情况 A — 合法 — 仅当 age 大于或等于 18 时执行
  • 情况 B — 非法 — 仅当 age 小于 18 时执行

继续阅读,您将看到我们如何将这些情况转化为代码。

条件语句

C++ 中最简单的条件形式是 if 语句,其基本形式如下

if 语句的结构
if (/* boolean condition */) 
{
// The code in here executes only if the condition evaluates to true
}

// The code out here executes regardless of whether the condition is true or false

要使用 if 语句,我们需要两样东西

  1. 一个在评估后产生布尔值 true/false 的条件
  2. 当条件评估为 true 时执行的代码

if 关键字之后,我们将布尔条件放在括号内。然后,围绕 #2 的大括号创建了一个代码块此代码块中的所有内容都将且仅在条件为真时执行。在代码块中创建的变量与该代码块共存亡——当代码块结束时(以右大括号 } 结束),它们就会被销毁,并且从代码块外部完全无法访问。

让我们将此应用于我们的驾驶执照示例,将 if 语句与我们之前确定的情况相结合

首次尝试使用 if 语句
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

// Case A:
if (/* age is greater than or equal to 18*/)
{
std::cout << "You can legally get a driver's license\n";
}

// Case B:
if (/* age is less than 18 */)
{
std::cout << "You cannot legally get a driver's license\n";
}
}

请注意,这里我们有两个 if 语句,每个情况一个。第一个处理我们的情况 A,即他们可以合法获得驾驶执照的情况。第二个处理我们的情况 B,即他们不能合法获得驾驶执照的情况。

仔细检查后,一个事实应该很快变得显而易见——这些情况是互斥的。这意味着两种情况不可能同时为真;只能执行其中一种。C++ 提供了 else 关键字来界定互斥条件。虽然上面的代码会按预期工作,但我们可以这样改进它

if-else 语句的结构
if (/* boolean condition */)
{
// The code in here executes only if the condition evalutes to true
}
else
{
// The code in here executes only if the condition evalutes to false
}

// The code out here executes regardless of whether the condition is true or false

这个 else 块是可选的,只有当你需要互斥时才应该使用它。

现在我们可以回到我们的示例,看到只需要一个条件,因为如果一个为真,则另一个必定为假。

首次尝试使用 if-else 语句
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (/* age is greater than or equal to 18*/)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}
没有分号 ;

不要在 if 语句的括号后面加分号 (;)。这不会导致编译器错误,但会**导致**您的代码行为不正确。条件代码块将始终执行。

if (age >= 18) 
// ...
else
// ...

总结一下,我们已经学习了如何将代码中条件执行的情况分离到专用的 if 语句中。这使我们能够根据程序中的各种值选择要运行的代码。现在我们已经有了 if-else 语句的基本结构,我们可以看看如何通过创建布尔条件来完成我们的程序。

布尔表达式

if 语句的括号内是布尔表达式,即一个求值为 truefalse 的表达式。C++ 提供了几个新的运算符,允许我们形成这样的表达式。

布尔运算符

下面是一个表格,显示了 C++ 中可用的一些布尔运算符。布尔运算符是根据其输入返回布尔值 true/false 的运算符。它们就像您在之前课程中看到的其他数学运算符一样,但它们不是求值为像 int 这样的数字,而是求值为 bool (true/false)。

C++ 运算符数学等价描述
a == ba = ba 等于 b 吗?
a != ba ≠ ba 不等于 b 吗?
a > ba > ba 严格大于 b 吗?
a >= ba ≥ ba 大于或等于 b 吗?
a < ba < ba 严格小于 b 吗?
a <= ba ≤ ba 小于或等于 b 吗?

相等运算符

我们表格的前两行 ==!= 构成了相等运算符。这两个运算符允许我们检查两个值是否相同。相等运算符适用于大多数 C++ 类型,包括数字、字符串、布尔值等等。

危险

单个 = 与双个 == 不同。单个 =赋值运算符,例如当您创建或更改变量时。双个 ==相等运算符,当您想检查两个变量是否具有相同的值时使用。

因此,在 if 语句的条件中,当您想检查相等性时

  • if (a == b)
  • if (a = b)

关系运算符

我们表格的接下来四行构成了关系运算符。这两个运算符允许我们对两个值进行位置比较(例如在数轴上或按字母顺序)。关系运算符适用于某些 C++ 类型,例如数字和字符串;但是,我们尚未涵盖的许多其他类型不能这样比较。

我们现在掌握的知识足以让程序的第一版正常运行。提醒一下,我们需要创建一个条件,检查用户的年龄是否大于或等于 18。使用上表,最接近的匹配是 age >= 18。现在我们可以填充我们的 if 语句

驾驶执照神谕 2000
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (age >= 18)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}

作为一项额外挑战,尝试使用其他剩余的关系运算符为 age >= 18 形成其他三种等效的表达方式。

复合布尔表达式

您可以通过所谓的逻辑运算符来转换和组合布尔表达式。它们是上面最初介绍的布尔运算符的一个子集,但它们旨在将布尔值作为输入。

C++ 支持这两种等效形式的运算符,即文本版本和符号版本。虽然符号表示在实际中更常见,但您可能会发现文本表示更容易理解和记住。您可以使用您最喜欢的一种,但请尽量保持一致!

C++ 运算符替代表示描述
a and ba && bab 为真吗?
a or ba || bab 中任一为真吗?
not c!cc 为假吗?

逻辑 AND 运算符

逻辑 AND 运算符 and/&& 接受两个布尔输入,并且当且仅当它的两个输入都为 true 时才返回 true。当您想检查多个条件是否都为真,或者多个条件是否为 false(通过同时使用否定运算符)时,最好使用它。

例如,false && truefalse,而 true and truetrue

逻辑 OR 运算符

与 AND 类似,逻辑 OR 运算符 or/|| 接受两个布尔输入,并且当其中一个或两个输入都为 true 时返回 true。当您想检查多个条件中的任何一个是否为真,或者一个变量是否是多种可能性中的一个时,最好使用它。

例如,false or falsefalse,而 false || truetrue

逻辑 NOT 运算符

请密切注意上表中的最后一行;not/! 也称为逻辑非运算符。此运算符将翻转单个布尔输入的真值。因此,在表达式 !c 中,c 是一个布尔值(true/false),而 ! 非运算符将 true→falsefalse→true。这相当于询问 c 是否为 false。此运算符在您想检查某个条件是否不成立时很有用。

例如,!(a == b) 等价于 a != b。同样,not (a <= b) 等价于 a > b。请注意这里如何使用括号来首先评估内部表达式,然后再对其进行逻辑否定。

升级神谕

州通过了新的法规,现在我们必须升级我们的 Oracle 程序以遵守。新法律规定了驾驶执照的最高年龄——65 岁及以上的人不再允许驾驶机动车辆

我们需要扩展我们的布尔条件以遵守这项新要求。目前,age >= 18 设置了可接受值范围的下限。我们缺少设置上限的东西,它应该是 65。检查年龄是否小于 65 的布尔表达式可以写成 age < 65。请注意,我们使用 < 而不是 <=,因为 65 岁的人被禁止驾驶。

现在我们有 age >= 18age < 65,它们必须以某种方式组合。我们需要某种方式指定两者都必须为真——该人必须年满 18 岁或以上且小于 65 岁才能获得驾驶执照。

回顾复合布尔表达式中的表格,我们可以看到 and/&& 运算符最适合这种情况。我们可以这样写这个复合条件:age >= 18 and age < 65。请注意,这里的左右顺序无关紧要,这意味着 age < 65 and age >= 18 是一个等效条件。

驾驶执照神谕 3000
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 3000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (age >= 18 and age < 65)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}
链式相等或关系运算符

您可能想将上述复合条件改写为 18 <= age < 65。然而,这将不起作用。虽然它会编译,但会导致不正确的行为,因为它总是会评估为 true

使用相等运算符也会出现同样的不正确行为。例如,age1 == age2 == 18age1 != age2 != 35 都将与上述示例类似,要么始终返回 false,要么始终返回 true。

切勿尝试链式使用相等或关系运算符。始终使用逻辑运算符 and/&&or/|| 来组合布尔表达式。有关其原因的更多信息,请参阅布尔值 » int↔bool 转换

运算顺序

与数学运算符一样,布尔运算符也有其严格遵守的优先级顺序。类似于“PEMDAS”,括号内的内容总是首先被评估,其他运算符则根据下面列出的优先级进行计算。优先级最高在最上面。

运算符名称结合性
! not逻辑非右到左 🡠
* / %乘法/除法左到右 🡢
+ -加法/减法左到右 🡢
< <= > >=关系运算符左到右 🡢
== !=相等运算符左到右 🡢
&& and逻辑与左到右 🡢
|| or逻辑或左到右 🡢

让我们用它来分析一些例子。

运算顺序展示
a > 10 and a < 100 or a == 150
// equivalent to
(a > 10 and a < 100) or a == 150

a * 4 == b + 5
// equivalent to
(a * 4) == (b + 5)

not a or b < 3701
// equivalent to
(not a) or (b < 3701)

not a != false
// equivalent to
(not a) != false
使用括号进行消歧

最好不要过分依赖运算符优先级的隐式规则。程序员可能很难记住所有关于哪个运算符优先评估的规则,因此编写太多依赖于这些规则的代码可能会使代码更难阅读和理解。如果您打算首先评估子表达式,最好将其放在括号中。

因此,与其写 a and b and c or a and not b,不如考虑写 (a and b and c) or (a and not b)

条件语句简介

到目前为止,我们创建的程序每次都以相同的方式工作。我们的程序无法做出决策。现在是时候改变这种状况了。在本课中,我们将根据用户输入的内容,为程序提供分支路径。这将是一个指导性课程,我们将制作一个应用程序,检查用户是否可以合法地获得驾驶执照。😎

代码准备

我们首先询问用户的出生年份。

#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

// Case A:
std::cout << "You can legally get a driver's license\n";

// Case B:
std::cout << "You cannot legally get a driver's license\n";
}

在这里,我强调了两段代码——一段是用户可以合法获得驾驶执照的情况,另一段是他们不能合法获得驾驶执照的情况。我们只想执行其中一个片段,而不是两个都执行。我们怎么能做到这一点呢?首先,我们应该明确“情况”是什么,以及在什么条件下它们应该执行。

  • 情况 A — 合法 — 仅当 age 大于或等于 18 时执行
  • 情况 B — 非法 — 仅当 age 小于 18 时执行

继续阅读,您将看到我们如何将这些情况转化为代码。

条件语句

C++ 中最简单的条件形式是 if 语句,其基本形式如下

if 语句的结构
if (/* boolean condition */) 
{
// The code in here executes only if the condition evaluates to true
}

// The code out here executes regardless of whether the condition is true or false

要使用 if 语句,我们需要两样东西

  1. 一个在评估后产生布尔值 true/false 的条件
  2. 当条件评估为 true 时执行的代码

if 关键字之后,我们将布尔条件放在括号内。然后,围绕 #2 的大括号创建了一个代码块此代码块中的所有内容都将且仅在条件为真时执行。在代码块中创建的变量与该代码块共存亡——当代码块结束时(以右大括号 } 结束),它们就会被销毁,并且从代码块外部完全无法访问。

让我们将此应用于我们的驾驶执照示例,将 if 语句与我们之前确定的情况相结合

首次尝试使用 if 语句
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

// Case A:
if (/* age is greater than or equal to 18*/)
{
std::cout << "You can legally get a driver's license\n";
}

// Case B:
if (/* age is less than 18 */)
{
std::cout << "You cannot legally get a driver's license\n";
}
}

请注意,这里我们有两个 if 语句,每个情况一个。第一个处理我们的情况 A,即他们可以合法获得驾驶执照的情况。第二个处理我们的情况 B,即他们不能合法获得驾驶执照的情况。

仔细检查后,一个事实应该很快变得显而易见——这些情况是互斥的。这意味着两种情况不可能同时为真;只能执行其中一种。C++ 提供了 else 关键字来界定互斥条件。虽然上面的代码会按预期工作,但我们可以这样改进它

if-else 语句的结构
if (/* boolean condition */)
{
// The code in here executes only if the condition evalutes to true
}
else
{
// The code in here executes only if the condition evalutes to false
}

// The code out here executes regardless of whether the condition is true or false

这个 else 块是可选的,只有当你需要互斥时才应该使用它。

现在我们可以回到我们的示例,看到只需要一个条件,因为如果一个为真,则另一个必定为假。

首次尝试使用 if-else 语句
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (/* age is greater than or equal to 18*/)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}
没有分号 ;

不要在 if 语句的括号后面加分号 (;)。这不会导致编译器错误,但会**导致**您的代码行为不正确。条件代码块将始终执行。

if (age >= 18) 
// ...
else
// ...

总结一下,我们已经学习了如何将代码中条件执行的情况分离到专用的 if 语句中。这使我们能够根据程序中的各种值选择要运行的代码。现在我们已经有了 if-else 语句的基本结构,我们可以看看如何通过创建布尔条件来完成我们的程序。

布尔表达式

if 语句的括号内是布尔表达式,即一个求值为 truefalse 的表达式。C++ 提供了几个新的运算符,允许我们形成这样的表达式。

布尔运算符

下面是一个表格,显示了 C++ 中可用的一些布尔运算符。布尔运算符是根据其输入返回布尔值 true/false 的运算符。它们就像您在之前课程中看到的其他数学运算符一样,但它们不是求值为像 int 这样的数字,而是求值为 bool (true/false)。

C++ 运算符数学等价描述
a == ba = ba 等于 b 吗?
a != ba ≠ ba 不等于 b 吗?
a > ba > ba 严格大于 b 吗?
a >= ba ≥ ba 大于或等于 b 吗?
a < ba < ba 严格小于 b 吗?
a <= ba ≤ ba 小于或等于 b 吗?

相等运算符

我们表格的前两行 ==!= 构成了相等运算符。这两个运算符允许我们检查两个值是否相同。相等运算符适用于大多数 C++ 类型,包括数字、字符串、布尔值等等。

危险

单个 = 与双个 == 不同。单个 =赋值运算符,例如当您创建或更改变量时。双个 ==相等运算符,当您想检查两个变量是否具有相同的值时使用。

因此,在 if 语句的条件中,当您想检查相等性时

  • if (a == b)
  • if (a = b)

关系运算符

我们表格的接下来四行构成了关系运算符。这两个运算符允许我们对两个值进行位置比较(例如在数轴上或按字母顺序)。关系运算符适用于某些 C++ 类型,例如数字和字符串;但是,我们尚未涵盖的许多其他类型不能这样比较。

我们现在掌握的知识足以让程序的第一版正常运行。提醒一下,我们需要创建一个条件,检查用户的年龄是否大于或等于 18。使用上表,最接近的匹配是 age >= 18。现在我们可以填充我们的 if 语句

驾驶执照神谕 2000
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 2000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (age >= 18)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}

作为一项额外挑战,尝试使用其他剩余的关系运算符为 age >= 18 形成其他三种等效的表达方式。

复合布尔表达式

您可以通过所谓的逻辑运算符来转换和组合布尔表达式。它们是上面最初介绍的布尔运算符的一个子集,但它们旨在将布尔值作为输入。

C++ 支持这两种等效形式的运算符,即文本版本和符号版本。虽然符号表示在实际中更常见,但您可能会发现文本表示更容易理解和记住。您可以使用您最喜欢的一种,但请尽量保持一致!

C++ 运算符替代表示描述
a and ba && bab 为真吗?
a or ba || bab 中任一为真吗?
not c!cc 为假吗?

逻辑 AND 运算符

逻辑 AND 运算符 and/&& 接受两个布尔输入,并且当且仅当它的两个输入都为 true 时才返回 true。当您想检查多个条件是否都为真,或者多个条件是否为 false(通过同时使用否定运算符)时,最好使用它。

例如,false && truefalse,而 true and truetrue

逻辑 OR 运算符

与 AND 类似,逻辑 OR 运算符 or/|| 接受两个布尔输入,并且当其中一个或两个输入都为 true 时返回 true。当您想检查多个条件中的任何一个是否为真,或者一个变量是否是多种可能性中的一个时,最好使用它。

例如,false or falsefalse,而 false || truetrue

逻辑 NOT 运算符

请密切注意上表中的最后一行;not/! 也称为逻辑非运算符。此运算符将翻转单个布尔输入的真值。因此,在表达式 !c 中,c 是一个布尔值(true/false),而 ! 非运算符将 true→falsefalse→true。这相当于询问 c 是否为 false。此运算符在您想检查某个条件是否不成立时很有用。

例如,!(a == b) 等价于 a != b。同样,not (a <= b) 等价于 a > b。请注意这里如何使用括号来首先评估内部表达式,然后再对其进行逻辑否定。

升级神谕

州通过了新的法规,现在我们必须升级我们的 Oracle 程序以遵守。新法律规定了驾驶执照的最高年龄——65 岁及以上的人不再允许驾驶机动车辆

我们需要扩展我们的布尔条件以遵守这项新要求。目前,age >= 18 设置了可接受值范围的下限。我们缺少设置上限的东西,它应该是 65。检查年龄是否小于 65 的布尔表达式可以写成 age < 65。请注意,我们使用 < 而不是 <=,因为 65 岁的人被禁止驾驶。

现在我们有 age >= 18age < 65,它们必须以某种方式组合。我们需要某种方式指定两者都必须为真——该人必须年满 18 岁或以上且小于 65 岁才能获得驾驶执照。

回顾复合布尔表达式中的表格,我们可以看到 and/&& 运算符最适合这种情况。我们可以这样写这个复合条件:age >= 18 and age < 65。请注意,这里的左右顺序无关紧要,这意味着 age < 65 and age >= 18 是一个等效条件。

驾驶执照神谕 3000
#include <iostream>

int main()
{
std::cout << "Welcome to the Driver's License Oracle 3000\n";
std::cout << "Please enter your year of birth: ";

int year_of_birth;
std::cin >> year_of_birth;

// Year 2022 at the moment of writing this lesson
int age = 2022 - year_of_birth;

if (age >= 18 and age < 65)
{
std::cout << "You can legally get a driver's license\n";
}
else
{
std::cout << "You cannot legally get a driver's license\n";
}
}
链式相等或关系运算符

您可能想将上述复合条件改写为 18 <= age < 65。然而,这将不起作用。虽然它会编译,但会导致不正确的行为,因为它总是会评估为 true

使用相等运算符也会出现同样的不正确行为。例如,age1 == age2 == 18age1 != age2 != 35 都将与上述示例类似,要么始终返回 false,要么始终返回 true。

切勿尝试链式使用相等或关系运算符。始终使用逻辑运算符 and/&&or/|| 来组合布尔表达式。有关其原因的更多信息,请参阅布尔值 » int↔bool 转换

运算顺序

与数学运算符一样,布尔运算符也有其严格遵守的优先级顺序。类似于“PEMDAS”,括号内的内容总是首先被评估,其他运算符则根据下面列出的优先级进行计算。优先级最高在最上面。

运算符名称结合性
! not逻辑非右到左 🡠
* / %乘法/除法左到右 🡢
+ -加法/减法左到右 🡢
< <= > >=关系运算符左到右 🡢
== !=相等运算符左到右 🡢
&& and逻辑与左到右 🡢
|| or逻辑或左到右 🡢

让我们用它来分析一些例子。

运算顺序展示
a > 10 and a < 100 or a == 150
// equivalent to
(a > 10 and a < 100) or a == 150

a * 4 == b + 5
// equivalent to
(a * 4) == (b + 5)

not a or b < 3701
// equivalent to
(not a) or (b < 3701)

not a != false
// equivalent to
(not a) != false
使用括号进行消歧

最好不要过分依赖运算符优先级的隐式规则。程序员可能很难记住所有关于哪个运算符优先评估的规则,因此编写太多依赖于这些规则的代码可能会使代码更难阅读和理解。如果您打算首先评估子表达式,最好将其放在括号中。

因此,与其写 a and b and c or a and not b,不如考虑写 (a and b and c) or (a and not b)