基本控制结构
蓝桥云课学习实录 2021/11/19
前言
C++ 语言的基本控制结构包括顺序结构、选择结构和循环结构三种。前面实验涉及到的控制结构均为顺序结构,即程序是顺序执行的语句序列。但若想解决稍复杂的问题,例如求解分段函数、输入一个班级的学生成绩并计算其平均值等,则需要利用选择结构或循环结构。
知识点
顺序结构
选择结构
循环结构
循环嵌套和死循环
break、continue 以及 goto 语句的使用
一、顺序结构
顺序结构是最简单的控制结构,也是 C++ 程序默认的执行流程。在此结构中,程序将按照书写的先后顺序自上而下依次执行。一般情况下,若程序中不包含选择结构、循环结构和跳转语句,则此程序为顺序结构。
例如新建 sequence.cpp 文件,输入:
#include<iostream>
using namespace std;
int main()
{
int a,b;
a=3;
b=5;
cout<<a+b<<endl; //输出 a+b 的值。
return 0;
}
此程序中,语句按照从上至下的顺序依次执行:首先定义了 a 和 b 两个 int 型变量,然后给 a 赋值为 3,b 赋值为 5,最后输出 a+b 的结果。
程序结果:
8
二、选择结构
根据判定条件的结果,选择相应执行语句的控制结构称为选择结构。
1.使用条件运算符实现选择结构
利用条件运算符 ? 可以实现一个简单的选择结构,其基本形式为:
条件表达式 ? 表达式1 : 表达式2
此方式需根据条件表达式的判断结果,选择表达式 1 或者表达式 2。其具体意义是:若条件表达式的布尔值为 TRUE ,则返回 表达式1 的值,否则返回 表达式2 的值。例如新建 choose1.cpp 文件,输入:
#include<iostream>
using namespace std;
int main ()
{
int x,y=7; //声明局部变量 x 和 y 并给 y 赋值为 7。
x=(y<6) ? 1 : 0; //使用条件运算符实现选择结构
cout<<"choose:"<<x<<endl; //输出返回结果
return 0;
}
程序中 x=(y<6) ? 1 : 0; 表达的是:若 y 小于 6 的布尔值为 TRUE,则返回 1 给 x,否则返回 0 给 x。显然,y 的值为 7,7 < 6 的值为 FALSE,即返回 0。
程序结果:
0
2.使用 if 语句实现选择结构
if 是典型的用于实现选择结构的语句,例如if(X==1) i++;
当满足条件 X==1 时,执行语句 i++。if 语句一般分为简单的 if…else 语句、嵌套的 if 语句和 if…else if 语句三类。
简单的 if…else 语句 的基本结构为:
if(判定条件){
判定条件为 TRUE 时的执行语句
}
else{
判定条件为 FALSE 时的执行语句
}
和使用条件运算符实现选择结构的方式类似。首先进入判定条件,若判定条件的布尔值为 TRUE 则执行 if 花括号内的语句,不执行 else 花括号内的语句;若判定条件的布尔值为 FALSE 则执行 else 花括号内的语句,不执行 if 花括号内的语句。例如新建 choose2.cpp 文件,输入:
#include<iostream>
using namespace std;
int main ()
{
int x,y=7; //声明局部变量 x 和 y 并给 y 赋值为 7。
if(y<6){ //判定 y 是否小于 6。
x=1; //判定条件为 TRUE 时,x = 1。
}
else{
x=0; //判定条件为 FALSE 时,x = 0。
}
cout<<"choose:"<<x<<endl; //输出 x 的值。
return 0;
}
因为 y = 7 即 y < 6 的布尔值为 FALSE,所以 x 最后输出的值为 0。
程序结果:
0
嵌套的 if 语句 的基本结构为:
if(判定条件 1){
if(判定条件 2){
判定条件 1 和判定条件 2 均为 TRUE 时的执行语句
}
else{
判定条件 1 为 TRUE 且判定条件 2 为 FALSE 时的执行语句
}
}
else{
if(判定条件 3){
判定条件 1 为 FALSE 且判定条件 3 为 TRUE 时的执行语句
}
else{
判定条件 1 和判定条件 3 均为 FALSE 时的执行语句
}
}
嵌套的 if 语句只是把简单的 if…else 语句中的执行语句换成了 if…else 语句。当判定条件 1 的布尔值为 TRUE 时,进入判定条件 2;当判定条件 1 的布尔值为 FALSE 时,进入判定条件 3。例如新建 choose3.cpp 文件,输入:
#include<iostream>
using namespace std;
int main ()
{
int x;//声明局部变量 x。
int y=7; //声明局部变量 y 且赋值为 7。
int z=3;//声明局部变量 z 且赋值为 3。
if(y<6){ //判定 y 是否小于 6。
x=1; //判定条件 y<6 为 TRUE 时,x = 1。
}
else{ //判定条件 y<6 为 FALSE 时。
if(z>2){ // 判定 z 是否大于 2。
x=2; //判定条件 z>2 为 TRUE 时。
}
else{
x=3; //判定条件 z>2 为 FALSE 时。
}
}
cout<<"choose:"<<x<<endl; //输出 x 的值。
return 0;
}
因为 y = 7 即 y < 6 的布尔值为 FALSE,所以进入 else 分支继续判定 z 是否大于 2,又因为 z=3 即 z>2 的布尔值为 TRUE,所以 x 输出 2。
程序结果:
choose:2
if…else if 语句 的基本结构为:
if(判定条件1){
满足判定条件 1 时执行的语句
}
else if(判定条件2){
满足判定条件 2 时执行的语句
}
else{
既不满足判定条件 1,也不满足判定条件 2 时的执行语句
}
注意:嵌套 if 语句的判定条件可针对不同对象进行判定,例如上例,先判定条件 y<6,然后在 y<6 的布尔值为 FALSE 的情况下嵌套另一个针对不同对象的判定条件 z>2。而 if…else if 语句只能针对同一对象进行判定,例如新建 choose4.cpp 文件,输入:
#include<iostream>
using namespace std;
int main ()
{
int x,y=7; //声明局部变量 x 和 y 并给 y 赋值为 7。
if(y>8){ //判定 y 是否大于 8。
x=1; //当 y>8 时 x = 1。
}
else if(y>5){
x=2; //当 y>5 时 x = 2。
}
else{
x=3; //若既不满足 y>8,也不满足 y>5 时,x = 3。
}
cout<<"choose:"<<x<<endl; //输出 x 的值。
return 0;
}
因为 y=7 不满足 y>8 而满足 y>5,所以 x 的值为 2。
程序结果:
choose:2
使用 switch 语句实现选择结构
switch 语句比较特殊,其目的是检查常量表达式中的值,其基本结构为:
switch(表达式){
case 值1:
代码块1
break;
case 值2:
代码块2
break;
...
default:
默认执行的代码块
}
当 switch 表达式的值和 case 语句选择的值相同时,从此 case 位置开始向下执行,直到遇到 break 语句或 switch 语句块结束;如果没有匹配的 case 语句则执行 default 块的默认代码。例如新建 choose5.cpp 文件,输入:
#include<iostream>
using namespace std;
int main ()
{
cout<<"输入(a/s/d/w)"<<endl; //输出提示信息。
char ch; //定义 char 型变量 ch。
cin>>ch; //从键盘输入 ch 的值。
switch(ch){
case 'w': //键入 w 时。
cout<<"上"<<endl;
break;
case 's': //键入 s 时。
cout<<"下"<<endl;
break;
case 'a': //键入 a 时。
cout<<"左"<<endl;
break;
case 'd': //键入 d 时。
cout<<"右"<<endl;
break;
default: //键入值不是 a/s/d/w 时。
cout<<"输入错误!"<<endl;
}
return 0;
}
键入 w 输出文本 “上” 并跳出 switch 语句;键入 s 输出文本 “下” 并跳出 switch 语句;键入 a 输出文本 “左” 并跳出 switch 语句;键入 d 输出文本 “右” 并跳出 switch 语句;键入非 a/s/d/w 中的字符,则输出提示信息 “输入错误!”。
键入 ‘a’ 的程序结果:
左
键入 ‘c’ 的程序结果:
输入错误!
三、循环结构
允许多次执行某一条语句或某个语句组的控制结构称为循环语句,在 C++ 中有 while 语句、do…while 语句、for 语句三种循环控制语句。
1.使用 while 语句实现循环结构
while 语句的执行过程是先判断,再执行。其基本结构为:
while(条件){
代码块
}
执行 while 语句时,首先判断 while 后面的条件是否成立( TRUE or FALSE )。若成立,则执行循环内的代码,直到条件不成立;若不成立,则执行 while 语句后的其他语句。例如新建 circle1.cpp 文件,输入:
#include<iostream>
using namespace std;
int main()
{
int sub = 0; //定义变量 sub 并赋值为 0。
int i = 1; //定义变量 i 并赋值为 1。
while(i<5){ //判定 i<5 是否成立,若成立则执行循环体内的语句,若不成立则执行 while 语句后的其他语句。
sub += i; //执行 sub = sub + i。
i++; //i 累加 1
}
cout<<sub<<endl; //输出 sub 的值。
return 0;
}
在此程序中,sub 的初始值为 0,i 的初始值为 1。执行到 while 语句时,i<5 成立,进入循环体执行。
第一次循环:sub=0+1=1;执行 i++ 语句后的 i 值为 2,i<5 成立,继续执行循环体内的语句。
第二次循环:sub=0+1+2=3;执行 i++ 语句后的 i 值为 3,i<5 成立,继续执行循环体内的语句。
第三次循环:sub=0+1+2+3=6;执行 i++ 语句后的 i 值为 4,i<5 成立,继续执行循环体内的语句。
第四次循环:sub=0+1+2+3+4=10;执行 i++ 语句后的 i 值为 5,i<5 不成立,执行 while 语句后的其他语句。
最后输出 sub 的值为 10。
2.使用 do…while 语句实现循环结构
do…while 语句的执行过程是先执行,再判断。其基本结构为:
do{
代码块
}while(条件);
执行 do…while 语句时,先执行一次循环体内的语句,然后再判断循环条件是否成立。如果条件成立,则继续执行,直到循环条件不成立;若条件不成立,执行 while 语句后的其他语句。例如新建 circle2.cpp 文件,输入:
#include<iostream>
using namespace std;
int main()
{
int sub = 0; //定义变量 sub 并赋值为 0。
int i = 1; //定义变量 i 并赋值为 1。
do{
sub += i; //执行 sub = sub + i。
i++; //i 累加 1
}while(i<5);//判定 i<5 是否成立,若成立则执行循环体内的语句,若不成立则执行 do...while 语句后的其他语句。
cout<<sub<<endl; //输出 sub 的值。
return 0;
}
在此程序中,sub 的初始值为 0,i 的初始值为 1。执行到 do…while 语句时,直接进入循环体执行。
第一次循环:sub=0+1=1;执行 i++ 语句后的 i 值为 2。
i<5 成立,执行第二次循环:sub=0+1+2=3;执行 i++ 语句后的 i 值为 3。
i<5 成立,执行第三次循环:sub=0+1+2+3=6;执行 i++ 语句后的 i 值为 4。
i<5 成立,执行第四次循环:sub=0+1+2+3+4=10;执行 i++ 语句后的 i 值为 5。
i<5 不成立,执行 do…while 语句后的其他语句。
最后输出 sub 的值为 10。
3.使用 for 语句实现循环结构
for 语句允许指定循环的增量。其基本结构为:
for(循环变量初始化;循环条件;循环增量)
{
代码块
}
使用 for 语句实现循环结构的第一步就是初始化循环变量,然后判定循环条件,如果布尔值为 TRUE 则执行代码块中的语句,直到条件判定的布尔值为 FALSE 时终止循环;否则,循环结束。例如新建 circle3.cpp 文件,输入:
#include<iostream>
using namespace std;
int main()
{
int sub = 0; //定义变量 sub 并赋值为 0。
int i; //定义变量 i。
for(i=1;i<5;i++) //设定 i 的初始值为 1,循环条件为 i<5,循环增量为 i++。
{
sub += i; //执行 sub = sub + i。
}
cout<<sub<<endl; //输出 sub 的值。
return 0;
}
执行 for 语句。设定 i 的初始值为 1,判定条件为 i<5,循环增量为 i++。
i<5 成立,执行第一次循环:sub=0+1=2;返回到循环增量处,执行 i++ 语句,此时 i=2,i<5 成立。
执行第二次循环:sub=0+1+2=3;返回到循环增量处,执行 i++ 语句,此时 i=3,i<5 成立。
执行第三次循环:sub=0+1+2+3=6;返回到循环增量处,执行 i++ 语句,此时 i=4,i<5 成立。
执行第四次循环:sub=0+1+2+3+4=10;返回到循环增量处,执行 i++ 语句,此时 i=5,i<5 不成立,退出 for 循环。
最后输出 sub 的值为 10。
拓展
与 if 嵌套语句类似,循环结构也可以进行 循环嵌套。循环结构为:
for 嵌套
for(循环变量初始化1; 循环条件1; 循环增量1)
{
for(循环变量初始化2; 循环条件2; 循环增量2){
代码块2
}
代码块1
}
while 嵌套
while(条件1){
while(条件2){
代码块2
}
代码块1
}
do-while 循环
do{
代码块1
do{
代码块2
}while(条件2);
}while(条件1);
注意:尽量避免设计层次过多的循环嵌套。
循环结构和选择结构可以互相嵌套,例如在 for 语句中嵌套 if 语句:
for(循环变量初始化;循环条件;循环增量)
{
...
if(判定条件){
判定条件为 TRUE 时的执行语句
}
else{
判定条件为 FALSE 时的执行语句
}
}
判定条件永恒为 TRUE 的循环称为 死循环。例如:
int i=1
while(i==1){
cout<<"1"<<endl;
}
由于判定条件 i==1 的布尔值永恒为 TRUE,所以程序将无限循环输出字符串 “1”。值得注意的是,程序中应不含死循环,除非有特殊需求。
四、其他控制语句
continue 与 break 语句的区别
continue:结束本次循环,所在循环体并未结束。
例如新建 other.cpp 文件,输入:
#include<iostream>
using namespace std;
int main(){
int i;
for (i=0;i<5;i++)
{
if (i==3) continue;
cout<<i<<endl;
}
return 0;
}
循环至 i=3 时,满足条件 i==3 执行 continue 语句:直接跳出本次循环且不执行循环体内 continue 后的其他语句。随后再次执行循环增量 i++ 语句,判定循环条件,执行循环体。
程序结果:
0
1
2
4
break:结束整个循环体,所在循环体已结束。
将 other.cpp 文件中的 continue 修改为 break,如下:
#include<iostream>
using namespace std;
int main(){
int i;
for (i=0;i<5;i++)
{
if (i==3) break;
cout<<i<<endl;
}
return 0;
}
循环至 i=3 时,满足条件 i==3 执行 break 语句,直接退出 for 循环,结果只输出数字 3 前面的数字 0 1 2。
程序结果:
0
1
2
goto 语句的使用
goto 语句允许把控制无条件转移到同一函数内的标记语句。
但在任何的编程语言中,都不建议使用 goto 语句,因为它使得程序的控制流难以跟踪。
goto 语句的语法:
goto label;
...
label: statement;
当执行 goto label; 语句时,直接跳转并执行 label 标记的语句。例如新建 gtacc.cpp 文件,输入:
#include<iostream>
using namespace std;
int main(){
int i=3;
if (i==3){
goto acc;
}
else{
cout<<i<<endl;
}
acc:cout<<"acc"<<endl; //执行 goto acc 时跳转至本条语句。
return 0;
}
因为 if 语句中判定条件 i==3 的布尔值为 TRUE ,所以执行语句 goto acc; 后直接跳转到语句 cout<<“acc”<<endl;,输出字符串 “acc”。
程序结果:
acc
挑战
请编写一个 C++ 程序:
使用 for 语句计算 4 的阶乘。
目标
在屏幕上输出阶乘的结果
提示
语句 sub _= i 等于 sub = sub _ i。
代码
#include<iostream>
using namespace std;
int main()
{
int sub = 1;
int i;
for(i=2;i<5;i++)
{
sub *= i
}
cout<<sub<<endl;
return 0;
}
结果
24