简单控制结构

程序通常不限于指令的线性序列。 在其过程中,它可能会分支、重复代码或做出决策。 为此,C++ 提供了控制结构,用于指定我们的程序必须做什么、何时以及在什么情况下执行。

通过引入控制结构,我们将不得不引入一个新概念:复合语句。 块是一组用分号 (;) 分隔的语句,就像所有 C++ 语句一样,但分组在一个用大括号括起来的块中{ }:

{ 语句1; 语句2; 语句3; }

我们将在本节中看到的大多数控制结构都需要一个通用语句作为其语法的一部分。 语句可以是简单语句(以分号结尾的简单指令)或复合语句(分组在一个块中的多个指令),就像刚刚描述的那样。 如果我们希望该语句是简单语句,则不需要用大括号括起来({})。 但是,如果我们希望该语句是复合语句,则必须将其括在大括号之间({}),形成一个块。

条件结构:if 和 else

要放回的字符的if关键字用于仅在满足条件时执行语句或块。 它的形式是

if (条件) 语句

其中条件是被评估的表达式。 如果此条件为真,语句将被执行。 如果为假,则语句将被忽略(不执行),程序在此条件结构之后继续执行。
例如,以下代码片段打印x 是 100只有当x变量中存储的值确实是100:

1
2
if (x == 100)
  cout << "x is 100";

如果希望在条件为真时执行多个语句,我们可以使用大括号指定一个块{ }:

1
2
3
4
5
if (x == 100)
{
   cout << "x is ";
   cout << x;
}

我们还可以指定如果条件不满足时我们希望发生什么,方法是使用关键字else。它与if的 C++ 等效文件是

if (条件) 语句1 else 语句2

例如:

1
2
3
4
if (x == 100)
  cout << "x is 100";
else
  cout << "x is not 100";

一起使用,在屏幕上打印x 是 100如果确实x的值为100,但如果没有——并且只有在没有的情况下——它会打印x 不是 100.

要放回的字符的if + else结构可以连接起来,以验证一系列值。 以下示例显示了它的使用,用于判断当前存储在x中的值是正数、负数还是零

1
2
3
4
5
6
if (x > 0)
  cout << "x is positive";
else if (x < 0)
  cout << "x is negative";
else
  cout << "x is 0";

请记住,如果希望执行多个语句,我们必须通过将它们括在大括号中将它们分组到一个块中{ }.

迭代结构(循环)


循环的目的是重复一个语句一定次数或在满足条件时重复执行。

while 循环

它的格式是

while (表达式) 语句

它的功能很简单,就是重复执行语句,只要表达式中设置的条件为真。
例如,我们将使用 while 循环制作一个倒计时程序

// custom countdown using while

#include <iostream>
using namespace std;

int main ()
{
  int n;
  cout << "Enter the starting number > ";
  cin >> n;

  while (n>0) {
    cout << n << ", ";
    --n;
  }

  cout << "FIRE!\n";
  return 0;
}
Enter the starting number > 8
8, 7, 6, 5, 4, 3, 2, 1, FIRE!

当程序启动时,会提示用户插入倒计时的起始数字。 然后while循环开始,如果用户输入的值满足条件n>0(即n大于零),则将执行并重复条件后面的块,只要条件(n>0)仍然为真。

可以根据以下脚本(从 main 开始)解释先前程序的整个过程

  1. 用户为n
  2. 赋值。检查 while 条件 (n>0)。 此时有两种可能性
    * 条件为真:执行语句(到第 3 步)
    * 条件为假:忽略语句并在其后继续(到第 5 步)
  3. 执行语句
    cout << n << ", ";
    --n;
    (在屏幕上打印n的值,并将n减小1)
  4. 块的结尾。 自动返回到步骤 2
  5. 在块之后继续程序:打印 FIRE! 并结束程序。

在创建 while 循环时,我们必须始终考虑到它必须在某个时刻结束,因此我们必须在块内提供某种方法来强制条件在某个时刻变为假,否则循环将永远循环下去。 在这种情况下,我们包含了--n;,它将条件中正在评估的变量 (n) 的值减 1 - 这最终会使条件 (n>0) 在一定数量的循环迭代后变为假:更具体地说,当n变成0时,我们的 while 循环和倒计时结束。

当然,对于我们的计算机来说,这是一个非常简单的操作,整个倒计时都会立即执行,数字之间没有任何实际延迟。

do-while 循环


它的格式是

do 语句 while (条件);

它的功能与 while 循环完全相同,除了条件在 do-while 循环中,是在语句执行之后而不是之前评估,从而至少执行一次语句,即使条件永远无法满足。 例如,以下示例程序会回显您输入的任何数字,直到您输入0.

// number echoer

#include <iostream>
using namespace std;

int main ()
{
  unsigned long n;
  do {
    cout << "Enter number (0 to end): ";
    cin >> n;
    cout << "You entered: " << n << "\n";
  } while (n != 0);
  return 0;
}
Enter number (0 to end): 12345
You entered: 12345
Enter number (0 to end): 160277
You entered: 160277
Enter number (0 to end): 0
You entered: 0

do-while 循环通常用于必须确定循环结束的条件循环语句本身内确定,例如在前面的情况中,块内的用户输入用于确定循环是否必须结束。 事实上,如果您从未输入值0在前面的示例中,您可以永远被提示输入更多数字。

for 循环


它的格式是

for (初始化; 条件; 递增) 语句;

它的主要功能是重复语句while条件保持为真,就像 while 循环一样。 但此外,,对于循环提供了特定的位置来包含初始化语句和递增语句。 因此,此循环专门用于使用计数器执行重复操作,计数器在每次迭代时都会初始化和递增。

它的工作方式如下

  1. 初始化被执行。 通常,它是计数器变量的初始值设置。 这仅执行一次。
  2. 条件被检查。 如果为真,则循环继续,否则循环结束并且语句被跳过(不执行)。
  3. 语句被执行。 与往常一样,它可以是单个语句或括在大括号中的块{ }.
  4. 最后,无论在递增字段中指定什么,都会被执行,循环返回到步骤 2。

这是一个使用 for 循环进行倒计时的示例

// countdown using a for loop
#include <iostream>
using namespace std;
int main ()
{
  for (int n=10; n>0; n--) {
    cout << n << ", ";
  }
  cout << "FIRE!\n";
  return 0;
}
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

要放回的字符的初始化递增字段是可选的。 它们可以保持为空,但在所有情况下,它们之间的分号必须书写。 例如,我们可以写for (;n<10;)如果我们不想指定初始化和递增;或者for (;n<10;n++)如果我们想包含递增字段但没有初始化(也许是因为变量已经在之前初始化了)。

可选地,使用逗号运算符 (,) 我们可以指定多个表达式,对于循环中包含的任何字段,例如在初始化中。 逗号运算符 (,) 是表达式分隔符,它用于分隔多个表达式,而通常只期望一个表达式。 例如,假设我们想在循环中初始化多个变量

1
2
3
4
for ( n=0, i=100 ; n!=i ; n++, i-- )
{
   // whatever here...
}

如果ni在循环内未修改,则此循环将执行 50 次。


n0的值开始,而i100开始,条件是n!=i(即n不等于i)。 因为n增加 1,而i减少 1,循环条件将在第 50 个循环之后变为假,此时ni将等于50.

跳转语句。


break 语句


使用break我们可以离开循环,即使循环结束的条件没有满足。 它可用于结束无限循环,或强制其在自然结束之前结束。 例如,我们将停止倒计时,在自然结束之前(可能是因为发动机检查失败?)

// break loop example

#include <iostream>
using namespace std;

int main ()
{
  int n;
  for (n=10; n>0; n--)
  {
    cout << n << ", ";
    if (n==3)
    {
      cout << "countdown aborted!";
      break;
    }
  }
  return 0;
}
10, 9, 8, 7, 6, 5, 4, 3, countdown aborted!

continue 语句


要放回的字符的continue语句使程序跳过当前迭代中循环的其余部分,就好像已到达语句块的末尾一样,从而导致它跳转到以下迭代的开始。 例如,我们将在倒计时中跳过数字 5

// continue loop example
#include <iostream>
using namespace std;

int main ()
{
  for (int n=10; n>0; n--) {
    if (n==5) continue;
    cout << n << ", ";
  }
  cout << "FIRE!\n";
  return 0;
}
10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE!

goto 语句

goto允许绝对跳转到程序中的另一个点。 您应该谨慎使用此功能,因为它的执行会导致无条件跳转,而忽略任何类型的嵌套限制。
目标点由标签标识,然后该标签用作 goto 语句的参数。 标签由有效的标识符后跟冒号 (::).

一般来说,除了那些低级编程爱好者可能找到的用途外,此指令在结构化或面向对象的编程中没有具体的用途。 例如,这是我们使用goto:

// goto loop example

#include <iostream>
using namespace std;

int main ()
{
  int n=10;
  loop:
  cout << n << ", ";
  n--;
  if (n>0) goto loop;
  cout << "FIRE!\n";
  return 0;
}
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE!

exit 函数


exit是一个在cstdlib库中定义的函数。

的目的exit是使用特定的退出代码终止当前程序。 它的原型是

1
void exit (int exitcode);

要放回的字符的exitcode被某些操作系统使用,并且可能被调用程序使用。 按照惯例,退出代码为0意味着程序正常完成,任何其他值意味着发生了一些错误或意外结果。

选择性结构:switch。

switch 语句的语法有点特殊。 它的目的是检查表达式的几个可能的常量值。 类似于我们在本节开头使用几个ifelse if指令连接所做的事情。 它的形式如下

switch (expression)
{
case constant1:
group of statements 1;
break;
case constant2:
group of statements 2;
break;
.
.
.
default:
default group of statements
}

它的工作方式如下:switch 评估表达式并检查它是否等效于常量1,如果是,它将执行语句组 1直到找到break语句。 当它找到这个break语句时,程序跳转到switch选择性结构的结尾。

如果表达式不等于常量1,则将针对常量2进行检查。 如果它等于这个,它将执行语句组 2直到找到 break 关键字,然后将跳转到switch选择性结构的结尾。

的结尾。最后,如果表达式的值与任何先前指定的常量都不匹配(您可以根据要检查的值包括任意数量的case标签),程序将执行包含在default标签之后的语句(如果存在)(因为它是可选的)。

以下两个代码片段具有相同的行为

switch 示例if-else 等效
switch (x) {
case 1:
cout "x is 1";
break;
case 2:
cout "x is 2";
break;
default:
cout "value of x unknown";
}
if (x == 1) {
cout "x is 1";
}
else if (x == 2) {
cout "x is 2";
}
else {
cout "value of x unknown";
}

要放回的字符的switch语句在 C++ 语言中有点特殊,因为它使用标签而不是块。 这迫使我们在我们想要为特定条件执行的语句组之后放置break语句。 否则,其余语句——包括那些对应于其他标签的语句——也将被执行,直到到达switch选择性块的末尾或到达break语句。

例如,如果我们不在第一个 case 组之后包含break语句,程序将不会自动跳转到switch选择性块的结尾,并且它将继续执行其余语句,直到它到达break指令或switch选择性块的结尾。 这使得没有必要包含大括号{ }围绕每个 case 的语句,并且它也可以用于为表达式的不同可能值执行相同的指令块。 例如

1
2
3
4
5
6
7
8
9
switch (x) {
  case 1:
  case 2:
  case 3:
    cout << "x is 1, 2 or 3";
    break;
  default:
    cout << "x is not 1, 2 nor 3";
  }

请注意,switch 只能用于将表达式与常量进行比较。 因此,我们不能将变量作为标签(例如case n,其中n是一个变量)或范围 (case (1..3)),因为它们不是有效的 C++ 常量。

如果您需要检查范围或非常量的值,请使用ifelse if语句的连接。
Index
目录