************************************************************
************************************************************
控制结构
|
一个程序通常不只限是一个线形指令序列。在它执行的过程中它可以分支,做循环或做判断。为了这个目的,
C++
提供了控制结构,这些结果指明了在何时或在何条件下我们的程序将要做些什么。
在介绍控制结构的之前我们将不得不介绍一个新的概念:复合语句或块。块是一组像
C++
中的语句那样被分号
( ; )
分隔开的语句,但是组合在一起在一个块里用花括号
( {} )
括了起来:
{ statement1; statement2; statement3; }
我们在这节中将要看到的大部分控制结构都要求一个一般性的语句来作为他的语法的一部分。这个语句可以是一个简单的语句
(
由分号结束的一条简单命令
)
或一个复合语句
(
在一个块中的一组几条命令
)
,就像我们刚刚例子里那样。当我们想要那这语句是一个简单语句的时候,我们不需要把它用花括号
( {} )
括起来。但是在我们想让语句是复合语句的情况下,那它就必须被括在花括号之间
( {} )
构成一个块。
条件结构: if and else
if
关键字被用来当一个条件被完全满足时执行一条语句或一个块。它的格式为:
if (condition) statement
其中
condition
是要被判断的表达式。如果这个条件为
true
,
statement
被执行。如果为
false
,
statement
被忽略
(
不被执行
)
并且程序将从这个条件结构之后从继续执行。
例如,下面的代码片断只有在 x 的值为 100 时打印 x is 100 :
例如,下面的代码片断只有在 x 的值为 100 时打印 x is 100 :
if (x == 100) cout << "x is 100"; |
如果我们想要在条件为
true
时有多条语句被执行我们可一个用花括号
{ }
指明一个块:
if (x == 100) { cout << "x is "; cout << x; } |
另外,我们可以用关键字
else
来指定在条件不被满足时我们想让什么发生。它与
if
连用的格式为:
if (condition) statement1 else statement2
例如:
if (x == 100) cout << "x is 100"; else cout << "x is not 100"; |
如果
x
确实值为
100
将在屏幕上打印
x is 100
,但是如果它不是——当且仅当它不是——它打印
x is not 100
。
if + else
结构可以由于要检验值的范围的目的二连用。下面的例子展示了它用来指出保存在
x
中的值是正,负或者两者多不是
(
例如
零
)
:
if (x > 0) cout << "x is positive"; else if (x < 0) cout << "x is negative"; else cout << "x is 0"; |
记住,如果在我们想要多于一条语句被执行的情况下,我们必须发把它们组合到一个块里并用花括号
{ }
把它们括起来。
跌代结构 (循环)
循环的目的是重复执行一条语句指定的次数或当条件为真时执行。
while循环
它的格式是:
while (expression) statement
并且它的功能就是在
expression
设置的条件为
true
时简单的重复
statement
。
例如,我们将用 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!"; return 0; } | Enter the starting number > 8 8, 7, 6, 5, 4, 3, 2, 1, FIRE! |
但程序开始时,用户被要求输入一个要被倒计时的开始数字。然后
while
循环开始了,如果用户输入的值满足条件
n>0(n
大于
0)
条件后跟的块将被执行并且当条件
(n>0)
仍然为
true
是被重复执行
.
上面程序的整个执行过程能够用下面的脚本来解释:
1.
用户为
n
指定一个数值。
2.
while
的条件被检查
(n>0)
。在这时有两个可能的结果:
* 条件为 true: 语句被执行 ( 到 3)
* 条件为 false: 忽略语句并在它之后继续执行 ( 到 5)
* 条件为 true: 语句被执行 ( 到 3)
* 条件为 false: 忽略语句并在它之后继续执行 ( 到 5)
3.
执行语句:
cout << n << ", ";
--n;
( 在屏幕上打印 n 的值并把 n 的值减 1)
cout << n << ", ";
--n;
( 在屏幕上打印 n 的值并把 n 的值减 1)
4.
块结束。自动返回
2
。
5.
继续块之后的程序:
打印
FIRE!
并结束程序。
当创建了一个
while
循环,我们必须保证它一定要在某一点结束,因此我们必须保证在块中有一些方法是条件在某一点为
false
,否则的话循环将永远的循环下去了。在这个例子中我们引入了
–n
;它在每次循环中把判断条件
(n)
的值减少
1
——这将最终使条件
(n>0)
在确定次循环迭代之后为
false
:更确切的说,当
n
为
0
时,就是我们的
while
循环和我们倒计时的终点。
当然对于我们的计算机来说这只是一个简单的事情,这个倒计时被立即执行且数字之间没有任何实际的停顿。
do-while循环
它的格式是:
do statement while (condition);
它的功能和
while
循环是完全一样的,除了它是在
statement
被执行之后才判断
condition
,因此即使是在条件不满足时它也至少会执行一次
statement
。例如,下面的例程会输出你输入的任何数字直到你输入
0(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
循环通常在条件必须在循环后才能决定,也就是由
statement
自己来决定时使用,就像在前面的例子那种情况,在块中用户的输入是用来决定循环是否终止的条件。事实上,如果你不在上面的例子里输入一个
0
值,你会被永远要求输入更多的数字。
for循环
它的格式是:
for (initialization; condition; increase) statement;
它的主要功能是在
condition
为
true
时重复
statement
,就像
while
循环一样。另外,
for
循环提供了特定的选项,包括一条
initialization
语句和一条
increase
语句。因此这个循环被特别的设计为执行一项重复的活动,伴随这一个被初始化和在每次迭代中变化的计数器。
它以下面的方式工作:
1.
initialization
被执行
.
通常它为计数器赋初值。它只被执行一次。
2.
condition
被检查。如果它为
true
循环继续,否则循环结束
,
statement
被略过
(
不执行
)
。
3.
statement
被执行。通常,它或是一条单独的语句或是被花括号
{ }
括起来的一个块。
4.
最后,在
increase
中的指定的任何事情都被执行,并且循环返回
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!"; return 0; } | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! |
initialization
和
increase
是可选的。
他们可以是空的,但无论如何它们之间的分号是必须写的。例如,我们可以写:
for ( ; n < 10 ; )
如果我们不想做特别的初始化也不想改变计数器的值;或
for ( ; n < 10 ; n++ )
如果我们想要包括自增域
(increase field)
但不想要初始化
(initialization)(
或许因为变量已经在前面初始化了
)
。
可选的,使用逗号操作符
( , )
我们可以在
for
循环的任何域里指定多于一个表达式,例如像在
initialization
中。逗号操作符
( , )
是一个表达式分隔符,它用来分隔多个表达式但只有一个是期望的。例如,我们想在我们的循环中初始化多个变量:
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
次循环之后变成
false
,这是
n
和
i
将都等于
50
。
跳转语句。
break 语句
使用
break
我们能在即使它的结束条件没有满足时离开循环。它可以被用来结束一个死循环
(infinite loop)
,或强迫一个循环再它正常结束之前结束。例如,我们将在它正常结束之前来结束一个倒计时
(
或许是因为一个引擎的检查失败了?
)
:
// 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!"; return 0; } | 10, 9, 8, 7, 6, 4, 3, 2, 1, FIRE! |
goto 语句
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!"; return 0; } | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, FIRE! |
exit函数
exit
是在
cstdlib
库中定义的一个函数。
exit
的目的是结束当前的程序返回一个特定的结束代码
(exit code)
。它的原型为:
void exit (int 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
计算表达式并检查它是否和
constant1
相等,如果是,它执行
group of statements 1
直到它找到
break
语句。当它找到
break
语句程序跳到
switch
选择结构的结尾。
如果表达式和
constant1
不相等,它将被检查与
constant2
的相等关系。如果它和这个相等它将执行
group of statements 2
直到
break
关键字被找到,然后将跳到
switch
选择结构的结尾。
最后,如果表达式的值和任何一个特定常量都不相匹配
(
你可以包含尽可能多得你想要检测的
case
标记
)
,程序将执行
default
:标号后的语句,如果它存在的话
(
因为它是可选的
)
。
下面这两段代码片断有相同的行为:
switch example
|
if-else equivalent
|
switch (x) { | if (x == 1) { |
在
C++
语言中
switch
语句有一点特别,因为它使用标号而不是块。这强迫我们在我们想在特定条件下执行的一组语句之后加上一条
break
语句。不然的话,其他的语句——包含在其他相应的标号下——也将被执行直到
switch
选择块的结束或到达一个
break
语句。
例如,如果我们在
case 1
后面的第一组语句后没有包含一条
break
语句的话,程序将不会自动的跳转到
switch
选择块的结束,并且它将继续执行其余的语句直到它遇到一个
break
命令或到了
switch
选择块的结束。这使得使用花括号
{ }
把每个
case
的语句括起来变成不是必须的了,并且它也使表达式计算得到的不同的可能值执行同一个块变为可能。例如:
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
语句。