简单控制结构
程序通常不限于指令的线性序列。 在其过程中,它可能会分支、重复代码或做出决策。 为此,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 开始)解释先前程序的整个过程
- 用户为n
- 赋值。检查 while 条件 (n>0)。 此时有两种可能性
* 条件为真:执行语句(到第 3 步)
* 条件为假:忽略语句并在其后继续(到第 5 步)
- 执行语句
cout << n << ", ";
--n;
(在屏幕上打印n的值,并将n减小1)
- 块的结尾。 自动返回到步骤 2
- 在块之后继续程序:打印 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 循环一样。 但此外,
,对于循环提供了特定的位置来包含
初始化语句和
递增语句。 因此,此循环专门用于使用计数器执行重复操作,计数器在每次迭代时都会初始化和递增。
它的工作方式如下
- 初始化被执行。 通常,它是计数器变量的初始值设置。 这仅执行一次。
- 条件被检查。 如果为真,则循环继续,否则循环结束并且语句被跳过(不执行)。
- 语句被执行。 与往常一样,它可以是单个语句或括在大括号中的块{ }.
- 最后,无论在递增字段中指定什么,都会被执行,循环返回到步骤 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...
}
|
如果
n或
i在循环内未修改,则此循环将执行 50 次。
n以
0的值开始,而
i以
100开始,条件是
n!=i(即
n不等于
i)。 因为
n增加 1,而
i减少 1,循环条件将在第 50 个循环之后变为假,此时
n和
i将等于
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 语句的语法有点特殊。 它的目的是检查表达式的几个可能的常量值。 类似于我们在本节开头使用几个
if和
else 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++ 常量。
如果您需要检查范围或非常量的值,请使用
if和
else if语句的连接。