第3章 程序控制结构
引言
语句是构成程序的基本单位,程序的运行过程就是执行语句的过程。程序中语句的执
行顺序称为流程控制。C++支持结构化程序设计,也称面向过程的程序设计,基于具体问
题的求解,主要包括顺序结构、选择结构和循环结构这3种基本控制结构。顺序结构是指按
照程序语句的顺序依次执行相应的语句,选择结构是指依据条件选择执行相应的语句,循环
结构是指根据条件重复执行某一程序块。大家要掌握顺序结构、条件结构和循环结构的语
法、执行过程和编程;循环嵌套的执行过程和应用;转移语句执行过程和使用,这是结构化程
序设计最重要的内容。
学习目标
. 理解:算法流程图表示。
. 熟悉:顺序结构、选择结构和循环结构语法和执行过程。
. 掌握:顺序结构、选择结构、循环结构和转移语句的编程。
课程思政
爱国教育:通过程序流程控制引入求真务实、严谨细致,培养学生严谨的逻辑思维和精
益求精的大国工匠精神。
3.1 顺序结构
顺序结构是程序设计中最简单、最常用的结构。在顺序结构中,程序中所有语句按照书
写顺序从前往后依次执行,中间没有跳转语句,不漏掉任何一行代码。在程序设计中,顺序
结构是最基本的控制结构,也常用作选择结构和循环结构的子结构。
顺序结构程序基本组成包括变量的定义、输入、赋值、数据处理和输出。顺序结构按照
语句的先后顺序依次执行,不能改变语句的执行顺序。
【例3.1】 求3个整数的最大值。 
#include<iostream> 
using namespace std; 
int main() 
{ 
long a,b,c,max; //a、b、c 为输入的数,max 为最大值 
cout<<"请输入3 个整数:"; 
cin>>a>>b>>c; 
max=a>b? a:b; //a 和b 的大者赋给max

41 
max=max>c? max:c; //max 和c 的大者赋给max 
cout<<"max="<<max<<endl; 
return 1; 
}
程序运行时,输入内容和运行结果如下: 
请输入3 个整数:123 -2324 243 
max=243 
在本例中,先求a和b的大值,然后再把a和b的大值和c进行比较,求出最大值,程序
按照语句顺序依次执行。
【例3.2】 分糖果。有3个小朋友,甲有x粒糖果,乙有y粒糖果,丙有z粒糖果。现在
他们玩一个游戏。甲将它的糖分成三等份,多余的自己吃掉,然后自己留一份,其余两份分
别给乙和丙;乙和丙也这样做。最后甲、乙、丙各有多少粒糖果? 输入甲、乙、丙最初的糖果
数,输出甲、乙、丙最后的糖果数。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int x, y, z, t; 
cout << "请输入甲最初的糖果数:"; 
cin >> x; 
cout << "请输入乙最初的糖果数:"; 
cin >> y; 
cout << "请输入丙最初的糖果数:"; 
cin >> z; 
//甲分 
t = x / 3; 
x = t; 
y = y + t; 
z = z + t; 
//乙分 
t = y / 3; 
y = t; 
x = x + t; 
z = z + t; 
//丙分 
t = z / 3; 
z = t; 
x = x + t; 
y = y + t; 
cout << "甲最后的糖果数:" << x << endl; 
cout << "乙最后的糖果数:" << y << endl; 
cout << "丙最后的糖果数:" << z << endl; 
return 1; 
}
程序运行时,输入和运行结果如下: 
分糖果

42 
请输入甲最初的糖果数:16 
请输入乙最初的糖果数:23 
请输入丙最初的糖果数:32 
甲最后的糖果数:29 
乙最后的糖果数:24 
丙最后的糖果数:15 
在本例中,按题目要求定义变量,根据提示输入甲、乙、丙最初的糖果数。甲先分糖果, 
然后是乙和丙分糖果,最后输出甲、乙、丙最后的糖果数。
3.2 选择结构之一———if语句
在学习和工作中,人们常常会用百度查询资料,查询到可能满足条件的信息时,系统是
如何判定的呢? 这里面就涉及条件判定问题,可以用if语句实现。if语句分为单分支if语
句、双分支if语句(if-else语句)和嵌套的if语句。
图3.1 单分支if语句的
执行过程
3.2.1 单分支if语句
单分支if语句的基本格式如下: 
if (表达式) 
语句
if是关键字,后面紧跟一对圆括号,括号里面是条件表达式。
单分支if语句的执行过程如图3.1所示,如果表达式成立,就执
行语句;否则结束if语句,执行if语句后面的语句。
注意 
(1)if语句中的表达式可以是任意表达式,表达式的值非0为真,0为假。例如: 
int x=3; 
if(x) 
cout<<x; 
(2)if语句只会控制后面一条语句。如果要控制多行,需要用花括号括起来,构成复合语句。
【例3.3】 输入两个整数,按从大到小的顺序输出这两个整数。 
#include <iostream> 
using namespace std; 
int main() 
{ 
int a, b, t; 
cout << "请输入两个整数:"; 
cin >> a >> b;; 
if (a < b) 
{ 
t = a; a = b; b = t; 
} 
cout <<"从大到小输出:"<< a << " " << b << endl; 
if语句

43 
return 1; 
}
程序运行时,输入和运行结果如下: 
请输入两个整数:12 34 
从大到小输出:34 12 
在本例中,如果a小于b,则交换a和b的值,要借助中间变量t暂时存放a的值。交换
a和b的值有3条语句,因此要使用花括号括起来,构成一条复合语句。
【例3.4】 设分段函数如下: 
f(x)= x0.5, x>0 
(x+1)2+2x+1/x, x≤0 { 
输入x 的值,输出函数f(x)的值。 
#include <iostream> 
#include<cmath> 
using namespace std; 
int main() 
{ 
float x, y; 
cin >> x; 
if (x >0) 
y = sqrt(x); 
if (x <= 0) 
y = pow(x + 1, 2) + 2 * x + 1 / x; 
cout << "x=" << x << ",y=" << y; 
return 0; 
}
程序运行时,输入5和运行结果如下: 
5x
=5,y=2.23607 
在本例中,函数sqrt的原型为doublesqrt(doublex),功能是返回x的算术平方根;函
数pow的原型为doublepow(doublex,doubley),功能为返回x的y次幂。调用sqrt和
pow函数,需要包含头文件cmath。
注意 数学中的表达式在程序中的书写格式要符合C++的规定。
3.2.2 双分支if语句
双分支if语句即if-else语句,其基本格式如下: 
if (表达式) 
语句1 
else 
语句2 
if-else语句的执行过程如图3.2所示。如果表达式成立,执行语句1;否则,执行语句2。
语句1和语句2两条分支只能选择一条执行。如果语句1、语句2是多条语句,需要使用花

44 
括号括起来,构成一条复合语句。
图3.2 if-else语句的执行过程
【例3.5】 输入一个年份,判断是否是闰年。如果是,输出该年是闰年的信息;否则输出
该年不是闰年的信息。 
#include <iostream> 
using namespace std; 
int main() 
{ 
int year; 
cout << "请输入一个年份:"; 
cin >> year; 
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 
cout << year << "年是闰年" << endl; 
else 
cout << year << "年不是闰年" << endl; 
return 1; 
}
程序运行时,输入和运行结果如下: 
请输入一个年份:2024 
2024 年是闰年
在本例中,要注意闰年判断的条件表示。判断条件为:闰年是能被4整除但不能被100 
整除的年份或能被400整除的年份。
3.2.3 嵌套的if语句
嵌套的if语句是指if语句里面再嵌套if语句,其基本格式为 
if(表达式1) 
if(表达式2) 
语句1 
else 
语句2 
else 
if(表达式3) 
语句3 
else 
语句4

45 
嵌套的if语句要用缩进和对齐体现结构性。内嵌的if-else语句可以不加大括号,但为
了增强程序的结构性和可读性,也可以加上大括号。同理,语句1、语句2、语句3和语句4 
如果是多条语句,则要加大括号。
在嵌套的if语句中,if与else的配对非常重要。当if与else出现多次时,在省略大括
号的情况下,else与前面最近的未配对的if配对。例如: 
if(a==b) 
if(b==c) 
cout<<"a==b==c"; 
else 
cout<<"a!=b"; 
上面的代码的功能是判断3个变量a、b、c是否相等。在省略大括号情况下,else与前
面最近的未配对的if,即第2个if配对。但是,这样配对的执行过程与条件表达不一致。上
面的代码应修改为 
if(a==b) 
{ 
if(b==c) 
cout<<"a==b==c"; 
}e
lse 
cout<<"a!=b"; 
在程序中,经常会用大括号把一条或者多条语句括起来,构成一个整体,以增强程序的
逻辑性和可读性。
判定一个整数的符号用if-else的嵌套结构实现的代码如下: 
#include<iostream> 
using namespace std; 
int main( ) 
{ 
int x, y; 
cin>>x; 
if(x < 0) 
y = -1; 
else 
if(x == 0 ) 
y = 0; 
else 
y = 1; 
cout<<"x="<<x<<",y="<<y; 
return 0; 
}
程序基本结构为两层if-else语句的嵌套结构,它在else后面内嵌了一个if-else语句, 
实际上是多分支结构。
【例3.6】 编程求解一元二次方程ax2+bx+c=0的根。 
#include<iostream>

46 
#include<cmath> 
using namespace std; 
int main() 
{ 
float a, b, c, d, x1, x2; //a、b、c 为方程系数 
cin >> a >> b >> c; 
if (a != 0) //一元二次方程判定 
{ 
d = b * b - 4 * a*c; 
if (d >= 0) //求实根 
{ 
x1 = (-b + sqrt(d)) / (2 * a); 
x2 = (-b - sqrt(d)) / (2 * a); 
cout << "方程实根解为:"<< endl; 
cout<<"x1 = " << x1 << endl<<"x2 = " << x2 << endl; 
} 
else //求虚根 
{ 
x1 = b / (2 * a); 
x2 = sqrt(-d) / (2 * a); 
cout << "方程虚根解为:" << endl; 
cout << "x1 = " << x1 << " + " << x2 << "i" << endl; 
cout << "x2 = " << x1 << " - " << x2 << "i" << endl; 
} 
} 
else //非一元二次方程 
cout << "输入数据有误\n"; 
return 1; 
}
程序运行时,输入和运行结果如下: 
5 1 2 
方程虚根解为: 
x1 = 0.1 + 0.6245i 
x2 = 0.1 - 0.6245i 
在本例中,程序整体结构就是if-else双分支结构,a!=0条件为真时执行的语句块中包
括两条语句,分别是d=b*b-4*a*c;以及内嵌的if-else语句。在内层if-else语句中, 
d>=0条件为真求实根,为假求虚根。要注意大括号的使用。
3.3 选择结构之二———switch语句
观察下面这些问题有什么共同点,学生成绩分类处理问题,把百分制成绩转换成对应的
等级;人口统计分类问题,根据年龄分为老年、中年、青年、少年和儿童;菜单命令操作问题, 
根据系统菜单命令选择执行不同的操作;个人所得税问题,根据收入分成多个档次。这些问
题的共同点就是要把数据分成几类分别进行处理,属于多分支结构。
多分支结构可以用if嵌套语句处理,也可以用switch语句处理。switch语句有两种形

47 
式,带break的switch语句和不带break的switch语句。
3.3.1 带break的switch语句
带break的switch语句基本格式如下: 
switch(表达式P ) 
{ 
case e 1: 
语句1;break; 
case e 2: 
语句2;break; 
. 
case en : 
语句n ;break; 
default: 
语句n +1;break; 
} 
switch是系统提供的关键字,switch后面的圆括号中的表达式是算术表达式,其值为
整型或者字符型。大括号里面有多个case,case后面的e1,e2,…,en 是常量,再后面的冒号
是标号符。
带break的switch语句的执行过程如图3.3所示。首先计算switch后面的圆括号中
的表达式P ,如果其值等于某个case后面的常量表达式e1~en ,就执行对应的语句,当遇到
break时,则立即结束switch语句的执行,执行大括号后面的语句。如果P 不等于e1~en 
中的任何一个常量,当有default时,就执行default后面的语句组;否则,就结束switch语
句,执行大括号后面的语句。
图3.3 带break的switch语句执行过程
注意 
(1)case后可包含多条语句,且不必加大括号。
(2)default是可选的。如果没有一个case分支可以执行,同时也没有default,则不会
执行switch语句中的任何语句。
(3)e1,e2,…,en 必须是整型或字符型常量表达式,且值必须不相同。
switch语句

48 
(4)语句组后面的break用来结束switch语句,执行大括号后面的语句。
(5)多个case可共用一组语句,只保留最后一个case后面的语句,前面的可以省略。
例如: 
case 'A': 
case 'B': 
case 'C': 
cout<<" score>60\n"; 
break; 
(6)最后一条语句可以不用break,因为遇到右大括号结束。
【例3.7】 输入成绩等级,等级为1~5的整数,5为Verygood,4为Good,3为Pass,2 
和1为Fail,输出相应的成绩等级。 
#include <iostream> 
using namespace std; 
int main() 
{ 
int score; 
cin >> score; 
switch (score) 
{ 
case 5: cout << "Very good!"; break; 
case 4: cout << "Good!"; break; 
case 3: cout << " Pass!"; break; 
case 2: 
case 1: cout << "Fail!"; break; 
default: cout << " Data error!"; break; 
} 
system("pause"); 
return 1; 
}
程序运行时,输入和运行结果如下: 
5V
ery good!请按任意键继续. . . 
注意 system 用于调用Windows下的DOS命令函数,函数原型为 
int system(char *command); 
pause命令的功能是暂停屏幕,以方便用户观察程序运行结果。
3.3.2 不带break的switch语句
不带break的switch语句的基本结构如下: 
switch(表达式P ) 
{ 
case e 1: 
语句1; 
case e 2:

49 
语句2; 
. 
case en : 
语句n ; 
default: 
语句n +1; 
} 
图3.4 不带break的switch 
语句执行过程
不带break的switch语句的执行过程如图3.4所示。
如果表达式P 的值与常量表达式e1,e2,…,en 中的某个
匹配,就执行相应的语句,然后往下继续执行其余的语
句。实际上不带break的switch语句不是真正意义上的
多分支结构。
将例3.7的代码改为不带break的switch语句,代码
如下: 
switch(score) 
{ case 5: cout<<"Very good!"; 
case 4: cout<<"Good!"; 
case 3: cout<<"Pass!"; 
case 2: cout<<"Fail!"; 
default: cout<<"data error!"; 
}
程序运行时,输入和运行结果如下: 
5V
ery good! Good! Pass! Fail! data error! 
【例3.8】 输入一个字母,输出相应的问候语。 
#include<iostream> 
using namespace std; 
int main() 
{ 
char c; 
cout <<"Enter m or n or h or other:"; 
c = getchar(); //输入一个字母赋值给c 
switch (c) 
{ 
case 'm': cout << "Good morning!\n"; break; 
case 'n': cout << "Good night!\n"; break; 
case 'h': cout << "Hello!\n"; break; 
default: cout << "How are you.\n"; break; 
} 
system("pause"); //系统函数,暂停屏幕显示 
return 0; 
}
程序运行时,输入和运行结果如下:

50 
Enter m or n or h or other:m 
Good morning! 
在本例中,c=getchar()表示从键盘输入一个字母并赋给c,getchar为系统的无参函
数,可以接收从键盘输入的任意字符。switch语句的条件表达式就是变量c的取值。如果
为m,则输出“Good morning!”;如果为n,则输出“Goodnight!”;如果为h,则输出
“Hello!”;如果不是这3个字母,则输出“Howareyou.”。
【例3.9】 输入百分制成绩,输出相应的成绩等级。 
#include<iostream> 
using namespace std; 
int main() 
{ 
float score; 
cin >> score; 
switch((int)score / 10) 
{ 
case 10: 
case 9: cout << "优秀!"; break; 
case 8: cout << "良好!"; break; 
case 7: cout << "中等!"; break; 
case 6: cout << "及格!"; break; 
default: cout << "不及格!"; break; 
} 
system("pause"); 
return 1; 
}
程序运行时,输入和运行结果如下: 
88.5 
良好!请按任意键继续. . . 
在本例中,成绩score为浮点型,switch后面圆括号中的表达式是把score强制转换为
整型,再除以10,即去掉个位。然后根据score的十位数字判断等级。如果为10或者9,则
输出“优秀!”;如果为8,则输出“良好!”……如果十位数字小于6,则成绩低于60分,输出
“不及格!”。
case后面只能是常量表达式,不能写成条件表达式,不能含有变量。例如,在本例中, 
case后面写成score>=90&&score<=100是错误的。
【例3.10】 菜单程序。 
#include<iostream> 
using namespace std; 
int main() 
{ 
void action1(int,int),action2(int,int); / /函 数原型声明 
char ch; int a=15,b=23; 
ch=getchar(); 
switch(ch)

51 
{ 
case 'a': 
case 'A': action1(a,b);break; 
case 'b': 
case 'B': action2(a,b);break; 
default: putchar('\a'); 
} 
return 0; 
}v
oid action1(int x,int y) //定义函数
{ 
cout<<"x+y="<<x+y>>endl; 
}v
oid action2(int x,int y) //定义函数
{ 
cout<<"x*y="<<x*y>>endl; 
}
在本例中,switch语句的条件表达式是变量ch的值。如果为字母a,无论大小写,均调
用action1函数,输出a、b的和;如果为字母b,无论大小写,均调用action2,输出a、b的乘
积。如果既不是a也不是b,则输出响铃警报。转义字符\' a'表示响铃警报。
3.4 循环结构之一———while和do-while语句
大家回顾一下如何求1+2+…+100。数学上的计算过程是从左往右依次进行累加计
算。可以设置一个累加器sum,其初始值为0,然后利用sum = sum +n进行累加计算,n 
依次取1,2,…,100。累加需要解决3个问题:①将n的初始值置为1;②每次执行sum = 
sum+ n后,n增1;③当n增到101时停止计算。其中的累加求和sum=sum+n和n= 
n+1需要重复进行,编程求解需要用到循环结构。
循环结构是在给定条件成立的情况下重复执行某些操作。C++ 的循环结构主要有
while循环、do-while循环和for循环3种。本节主要学习while语句和do-while语句。
3.4.1 while语句
图3.5 while语句的
执行过程
while语句的一般格式如下: 
while(表达式) 
{ 
循环体
}
while是系统提供的关键字,表达式为条件表达式。循环体
中的语句如果是两条或两条以上,要用大括号括起来,构成一条
复合语句。while语句的执行过程如图3.5所示,当表达式为真
(非0)时,执行循环体语句,然后继续下一次条件判断,如果为真
执行循环体;如果表达式为假(0)时就结束。
while和
do-while

52 
while语句特点是先判断后执行,是当循环,当条件成立就执行循环体。
【例3.11】 利用while循环编程输出1~10的平方。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i=1; 
while(i<=10) 
{ 
cout<<i*i<<" "; 
i++; 
} 
return 1; 
}
程序运行结果如下: 
1 4 9 16 25 36 49 64 81 100 
在本例中,循环变量i的初始值为1,循环条件是i<=10,循环体是输出i*i并将循环
变量i加1。
注意 循环结构有3个要素: 
(1)循环变量赋初始值。
(2)循环条件。
(3)循环变量的改变。循环变量一定要向着最终使循环条件为假的方向改变,否则就
是一个死循环。
【例3.12】 用while循环编程求1+2+…+100的和。 
#include<iostream> 
using namespace std; 
void main() 
{ 
int i,sum=0; 
i=1; 
while(i<=100) 
{ 
sum=sum+i; 
i++; 
} 
cout<<sum; 
}
程序运行结果如下: 
5050 
在本例中,定义了循环变量i和累加求和变量sum,sum 的初始值为0。循环变量的初
始值为1,i<=100为循环条件,100为循环终值。在循环体中进行累加求和并将循环变量
加1。

53 
【例3.13】 输入两个整数,求它们的最大公约数和最小公倍数。 
#include <iostream> 
using namespace std; 
int main() 
{ 
int a, b,ma,mb,t,gcd,lcm; 
cout << "请输入两个整数:"; 
cin >> a >> b; 
ma = a; mb = b; 
while(a%b!= 0) 
{ 
t = a % b; 
a = b; 
b = t; 
} 
gcd = b; 
lcm = ma * mb / gcd; 
cout << "最大公约数为:" << gcd << endl; 
cout << "最小公倍数为:" << lcm << endl; 
return 1; 
}
程序运行时,输入和运行结果如下: 
请输入两个整数:15 25 
最大公约数为:5 
最小公倍数为:75 
在本例中,求最大公约数采用的是欧几里得算法,即辗转相除法。其具体思想是:如果
a除以b的余数等于0,则最大公约数为b;否则把b赋值给a,把余数赋值给b,再进行下一
次循环判定。在辗转相除的过程中,a和b的值发生了改变,需要定义ma和mb两个变量
分别保存a和b的值,就可以使用ma和mb求最小公倍数了。
图3.6 do-while语句的
执行过程
3.4.2 do-while语句
do-while循环语句的一般格式如下: 
do 
{ 
循环体
} while(表达式); 
do-while语句先执行循环体,再进行条件判断,直到条件为假
时结束。do-while语句的执行过程如图3.6所示。
【例3.14】 用do-while语句求1+2+…+100的和。 
#include<iostream> 
using namespace std; 
int main() 
{

54 
int i,sum=0; 
i=1; 
do 
{ 
sum=sum+i; 
i++; 
}while(i<=100); 
cout<<sum; 
return 1; 
}
在本例中,i为循环变量,初值为1;sum 为累加求和变量。先执行sum=sum+i,然后i 
增加1,然后判断i<=100是否成立。若成立,则继续执行;否则结束循环,输出sum 的值。
3.4.3 while语句和do-while语句的区别
while语句先判断后执行,是当型循环,当条件成立时就执行,循环体有可能一次也不
执行。while表达式后面没有分号。
do-while语句先执行后判断,是直到型循环,直到条件不成立时结束,循环体至少执行
一次。while表达式后面有分号。
【例3.15】 分析下列两个程序的运行结果。
(1)do-while循环: 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i=11,sum=0; 
do 
{ 
sum+=1; 
i++; 
}while(i<=10); 
cout<<sum; 
}
(2)while循环: 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i=11,sum=0; 
while(i<=10) 
{ 
sum+=1; 
i++; 
} 
cout<<sum; 
}

55 
在do-while循环中,循环变量i=11,先执行累加(sum+=1),i自身加1,循环条件i<=10 
不成立,循环结束,输出结果为11。在while循环中,循环变量i=11,循环条件i<=10不
成立,循环体不执行,输出结果为0。
【例3.16】 输入一个整数,输出其各位数字之和。 
#include<iostream> 
#include<cmath> 
using namespace std; 
int main() 
{ 
int a, x, n, sum = 0; 
cin >> x; 
n = abs(x); 
while (n != 0) 
{ 
a = n % 10; 
sum = sum + a; 
n = n / 10; 
} 
cout << x << "各位数之和为:" << sum; 
return 1; 
}
程序运行时,输入和运行结果如下: 
-123 
-123 各位数之和为:6 
在本例中,while语句的循环变量为n,初值为x的绝对值,n!=0为循环条件。如果满
足条件,则执行循环体的3条语句,首先将n的个位数字赋给a,然后累加a,最后循环变量n 
除以10取整再赋值给n,即n去掉个位数字。下一轮循环继续判断循环条件,当n=0时结
束循环,就实现了求整数各位数字之和的目的。本例的算法思想是:求个位数字,累加个位
数字,去掉个位数字后开始下一轮循环,直到n为0时结束。
注意 abs为系统求绝对值函数,包含在头文件cmath中。
【例3.17】 按以下规则将明文变成密文:将字母A 变成字母E,即变成其后的第4个
字母,W 变成A,X变成B,Y变成C,Z变成D;小写字母采用相同规则。 
#include<iostream> 
using namespace std; 
int main() 
{ 
char c; 
while ((c = getchar()) != '\n') 
{ 
if (c >= 'a' && c <= 'z') 
{ 
c = c + 4; 
if (c > 'z') c = c - 26; 
}

56 
if ((c >= 'A' && c <= 'Z')) 
{ 
c = c + 4; 
if (c > 'Z') c = c - 26; 
} 
cout << c; 
} 
return 1; 
}
程序运行时,输入和运行结果如下: 
ZDSAGhsa 
DHWEKlwe 
在本例中,while语句先执行getchar函数读入一个字符赋值给c,再判定c是否是换行
符。循环体用if语句判定是否是大写字母或者小写字母,如果是,则c=c+4,即变成其后
的第4个字母。然后继续判定C+4后是否已超出字母范围,如果c>Z' ',或者c>z' '成立,执
行c=c-26,即c往回移26个字符位置,以解决字母循环移位的问题。
3.5 循环结构之二———for语句
分析以下问题的共同点:①1-12
+13
-14
+…+1 
99- 1 
100,分母从1到100递增,每
一项符号交替变化;②1! +2! +3! +…+10!,依次求阶乘,然后累加求和;③输出所
有的水仙花数,所谓“水仙花数”是指一个三位数,其各位数字的3次方之和等于该数本
身(例如153=13+53+33),需要对100~999依次进行判定。它们的共同点是:有明确
的开始值和结束值以及按一定规律变化的步长,需要逐项进行处理。这类问题适合用for 
循环实现。
3.5.1 for语句的基本形式
图3.7 for语句的执行过程
for语句的基本形式如下: 
for(表达式1;表达式2;表达式3) 
循环体
for后面的圆括号中,表达式1和表达式2后面有分号,表达
式3后面没有。表达式1是循环变量初始值,表达式2是循环条
件,表达式3是循环变量的变化规律。循环体如果有多条语句, 
要用大括号构成一条复合语句。
for语句的执行过程如图3.7所示。先执行表达式1,给循环
变量赋初始值;再执行表达式2,判断循环条件是否成立,如果成
立,则执行循环体;最后执行表达式3,使循环变量改变。随后进
入下一轮循环,直到循环条件为假时结束循环。
for循环

57 
【例3.18】 输入一个整数,求它的阶乘。 
#include<iostream> 
#include<iostream> 
using namespace std; 
int main() 
{ 
long n, i, s = 1; 
cout << "请输入一个整数:"; 
cin >> n; 
for (i = 1; i <= n; i++) 
s *= i; 
cout << n << "!=" << s; 
return 1; 
}
程序运行时,输入和运行结果如下: 
请输入一个整数:5 
5!=120 
在本例中,阶乘的值很大,注意变量值的溢出,最好把存放阶乘值的变量s定义为取值
范围较大的数据类型,例如长整型或者双精度浮点型。累乘变量要赋初始值(为1)。本例
求n 的阶乘使用的公式为n!=1×2×…×n。
【例3.19】 输入一个整数n,求1!+2!+…+n!。 
#include<iostream> 
using namespace std; 
int main() 
{ 
double n, i, s = 0,f=1; 
cout << "请输入一个整数:"; 
cin >> n; 
for (i = 1; i <= n; i++) 
{ 
f = f * i; 
s = s + f; 
} 
cout << "阶乘和:" << s << endl; 
return 1; 
}
程序运行时,输入和运行结果如下: 
请输入一个整数:5 
阶乘和:153 
本例是一个累加求和问题,存放累加结果的变量s的初始值为0。累加项为i的阶乘。
f用于存放阶乘的值,其初始值为1。如果本例求阶乘用例3.18的公式,则要用循环的嵌套
结构。

58 
3.5.2 for语句形式的变化
for语句中的表达式1、表达式2和表达式3可以是任意类型的表达式,都可以省略,但
分号不可以省略。例如,求1+2+…+100有以下4种情况。
(1)3个表达式都不省略,这是基本用法。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i,sum; 
for(i=1,sum=0;i<=100;i++) 
sum=sum+1; 
cout<<sum; 
return 1; 
}
(2)省略表达式1,将其放到for循环之前。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i,sum; 
i=1,sum=0; 
for(;i<=100;i++) 
sum=sum+1; 
cout<<sum; 
return 1; 
}
(3)在(2)的基础上省略表达式3,将其放在循环体的最后。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i,sum; 
i=1,sum=0; 
for(;i<=100;) 
{ 
sum=sum+1; 
i++; 
} 
cout<<sum; 
return 1; 
}
(4)在(3)的基础上省略表达式2,循环条件默认为真。需要在循环体中用if语句对循
环条件进行判定,当循环条件为假时要用break语句退出循环。

59 
#include<iostream> 
using namespace std; 
int main() 
{ 
int i,sum; 
i=1,sum=0; 
for(;;) 
if(i<=100) 
{ 
sum=sum+1; 
i++; 
} 
else 
break 
cout<<sum; 
return 1; 
}
【例3.20】 输出所有的水仙花数。水仙花数是指一个3位数,其各位数字立方和等于
该数本身,例如,153=13+53+33。 
#include<iostream> 
using namespace std; 
int main() 
{ 
int a, b, c, x; 
for (x = 100; x <= 999; x++) 
{ 
a = x / 100; 
b = x % 100 / 10; 
c = x % 10; 
if (a*a*a + b * b*b + c * c*c == x) 
cout << x << " "; 
} 
return 1; 
}
程序运行结果如下: 
153 370 371 407 
在本例中,水仙花数是一个三位数,需要对100~999依次进行判定,因此可以用for循
环实现。定义x为循环变量,赋初值为100,循环条件为x<=999,循环体实现求百位(a= 
x/100),求十位(b=x%100/10),求个位(c=x%10),再用if语句对该数是否为水仙花数进
行判定,如果是就输出该数。求立方和可以使用pow()函数,其原型为doublepow(doublex, 
doubley),求幂运算,表示x的y次方,如pow(b,3)为b的3次方。
【例3.21】 评委评分程序。在一次运动会方队表演中,学校安排了10名老师进行打
分。对于每个参赛班级的10个打分(百分制整数),去掉一个最高分和一个最低分,再算出
平均分,作为该班级的最后得分,保留3位小数输出。