第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位小数输出。