第十一章 流程控制拾遗与混合训练
说“拾遗”,可能你会以为本章的内容不是重点?那可不是,流程控制的内容并不多,却支撑着所有程序的框架!所所有有关流程的内容都是基础加重点。只是本章中继续讲到一些关键字可以改变流程,但并不独自构成完整流程结构。 另外,作为流程控制内容的结束章节,我们于最后安排了一些各流程混合使用的训练。
11.1 break11.1.1 break的作用与用法
循环就象绕圈子。比如,体育课,跑1200米,跑道一圈400米,所以我们要做的事就是一边跑一边在心里计数(当然要已数,否则老师万一少计一圈,我们可就玩完了),当计数到3圈时,“循环”结束。 如果,我在跑步时不幸由于体力不支而晕倒……怎么办?
有两种办法,一种是在判断是否继续循环的条件中加入新增条件的判断: 假设原来的循环表达为:
while(已跑完的圈数 < 3) { 跑一圈……; }
那么,加上附加条件后,循环表达为:
while(已跑完的圈数 <3 && 我还跑得好好的) //&& 就是"并且",没忘吧? { 跑一圈…… }
第二种方法是在循环中使用条件分支,在指定的条件成立时,中途跳出循环,用于实现跳出的关键字为:break。
while(已跑的圈数 < 3 ) { 跑一圈……;
if(我身体感觉不妙) break; }
在循环中,每跑完一圈,都检查一下自已是否感觉不妙,如果是,则程序执行break,直接跳出while,而不管此时圈数是否到达3圈。
还记得“小女孩买裙子”的故事吗?那时候,我们将“父母不给买小红裙 && 我还没有哭累”作为循环继续的条件,如果使用break,则可以写成这样: while(父母不给买小红裙) { 我哭;
if(我哭累了) break; }
在循环中,“我”每哭一次,都想想是否累了,如果是,则程序执行break,直接跳出while,而不管此时爸妈是否已经买了我的裙。
通过这两个例子,你应该注意到了,如果要用break,则if的条件(也就是要执行break分支的条件),正好是把原来放在循环判断中的条件反正过来。比如,原来是判断“我还跑得好好的”,现在则是判断“我身体感觉不妙”;原来是判断“我还没有哭累”,现在是判断“我哭累了”。 一句话,原来是判断“是否继续循环”,现在是判断“是否跳出循环”……
再来看那个“可以多次统计”的统计程序。看看是否也能把它改成使用break来结束循环。 为了节省篇幅同时也是为了突出重点,我们将其中用于实现一次统计的代码,用一句伪代码来实现。(什么叫伪代码?我们用得很经常啊,就是那些用自然语言写的“代码”,这些代码当然无法在计算机上运行,它们只是要方便地表达实际代码要实现的功能)。
int main(int argc, char* argv[]) { 实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分
do { //提问是否继续统计: cout <<"是否开始新的统计?(Y/N)?"; cin >> c; } while( c == 'y' || c == 'Y'); }
改成用 break; int main(int argc, char* argv[]) { 实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分
do { //提问是否继续统计: cout <<"是否开始新的统计?(Y/N)?"; cin >> c;
//如果用户输出的不是字母Y,说明他不想继续统计了,我们需要中断循环。 if( c != 'y' && c != 'Y') break; } while (true); }
请首先 while(true)部分,其条件直接写上真(true),表明这是一个无条件的循环(即,循环将无条地一直持续下去),这岂不犯了程序界的武林大岂:成了一个“死循环”?其实,相信你已明白,在循环体内,有一个break的分支在呢,当判断用户输入的字母既不是小写的y,也不是大写的Y,break就起它能起的作用了。
三个例子,都是从循环判断的条件摘出一部分或全部(最后一个例子),然后循环体中,采用一个if判断,结束break来跳出循环。可能你会问:为什么要break呢?直接用原来的方法,在while处判断条件不是很好吗?
break的长处在于,它可以在循环体内的任意位置进行判断。 继续上一例。假设我们出于慎重,想在用户按入 N 时,再问他一句是否真的退出统计,则此时显示出了break的方便: int main(int argc, char* argv[]) { 实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分
do { //提问是否继续统计: cout <<"是否开始新的统计?(Y/N)?"; cin >> c;
//如果用户输出的不是字母Y,说明他不想继续统计了,我们需要中断循环。 if( c != 'y' && c != 'Y') { //出于慎重起见,我们要再问一句用户是否真的不统计了? cout << "您真的不想继续计算了?(Y:真的结束 / N:继续统计)"; cin >> c;
//这回,如果用户输入Y,表明他真的不统计了: if( c == 'Y' || c == 'y') break; } } while (true); }
在上面例子,由于用户的两次输入我们都采用变量 c (char 类型)接收。但如果第一次输入 字母‘Y’时,循环需继续,但如果用户是在第二次输入‘Y',则表示是真的不统计了,循环却必须结束;所以,此时while无法仅凭c的值来做出正确判断,但,采用break,正如上面代码,我们在合适的位置安排一个break,从而直观地实现了。
当然,这里仅为了讲学方便而举此例,如果你真的在程序中为了一个“是否继续统计”而问了用户两遍,可能会被用户骂做“神经质”。不过,如果是删除某些重要数据(直接删除,不可恢复的情况),多问一次就选得很重要了。(比如句神英语删除用户操作就会在最后多问一句“真的要说再见吗?我们会想你的……”)
再举一例,看我们前面关于跑步的例子:
while(已跑的圈数 < 3 ) { 跑一圈……;
if(我身体感觉不妙) break; }
这段代码有点问题,因为判断“我身体感觉不妙”是在跑完一圈之后……很可能我在某一圈刚开始跑时就觉得肚子剧痛,极可能是得阑尾炎啊!按照这段程序,我只有坚持跑完一圈后,才能break了…… 要完美解决这个问题,我们将在本章再后讲到,现在先采用一个“通融”的办法,我们允许你每跑100米就检查一次吧:
while(已跑完图数 < 3) { 跑第1个100米;
if(我身体感觉不妙) break;
跑第2个100米;
if(我身体感觉不妙) break;
跑第3个100米;
if(我身体感觉不妙) break;
跑第4个100米;
if(我身体感觉不妙) break; } 代码中,我们将1圈拆为4个100米,每跑完1/4,我们就检查一次是否身体不对。看明白这个例子,我想你对break的用途和用法,可以算是理解了。
11.1.2 break 的一个“高级用法”
本小节不是很适于没有多少实际编程经历的初学者,所以初学者可以跳过,以后再回头阅读。当然,所谓的“高级用法”的确是应该加对引号的,所谈的内容只是一个高手们常用小小技巧。 使用do...break...while简化多级条件判断的结构。
如果你写过不少代码,那么一定会不时遇到类似下的情况: 假设要找到文件A,复制该文件为B;然后打开B文件,然后往B文件内写入一些内容;最后在写入成功后,我们需要再进行一些相关操作。 在此过程,遇到以下情况时将放弃后续的操作,认为是操作失败: 1、如果A文件不存在; 2、如果B文件已经存在,并且询问用户是否覆盖时,用户回答“不”; 3、无法复制出B文件; 4、无法打开B文件; 5、无法写入B文件; 6、无法正常关闭B文件。
用伪代码写该段程序为:
if( A文件存在 ) { 执行A文件的相关操作; if( B文件不存在 || 用户允许覆盖原有B文件) { 复制A文件为B文件; if(复制文件成功) { 打开B文件; if(打开文件成功) { 写入文件; if(写入成功) { 关闭B文件; if(关闭成成功) { 执行其它必须在一切成功后进行的操作。 …… } } } } } }
可能有些操作和判断可以同时处理,但这个程序的繁琐仍然不可避免,而现实中程序的复杂性往往要远过于此例。从语法上看,这个例子没有任何错误,但它的一层套一层的条件判断却让人难以书写,阅读,调试,在复杂的情况就容易造成人为的错误(比如最马虎的,花括号匹配不对等……)。
同样一段代码“程序老鸟”是这样写的:
do { if(A文件不存在) break; 执行A文件的相关操作;
if(B文件存在 && 用户不允许覆盖) break;
复制A文件为B文件; if(复制不成功) break;
打开B文件; if(打开B文件不成功) break;
写入文件; if(写入文件不成功) break;
关闭B文件; if(关闭不成功) break;
执行其它必须在一切成功后进行的操作。 …… } while(false);
看,代码是不是“直”了很多?这里用了do..while,可是根本不是为了循环,而是为了使用它的break功能。每当有操作不成功,就直接用break跳出循环。所以循环条件总是一个“永假” false。 在一个程序中,这种结构相当的多,为了更加一步淡化while的原来的循环用途,我们非常值得在代码加入两个共用的宏: #define BEG_DOWHILE do { #define END_DOWHILE } while(false);
这里举的是do...while结构,在某些情况下,可以使用while...来实现类似功能。
11.1.3 break 在for循环中的一点注意
前面举的例子都是do...while或while,break在for循环也一个样。请看下面例题:
例一:从1开始累加,每次递增1,请问累加到哪个数,累加和超过2000?请输出该数,及当时的累加和。
分析:和求1~100的累加和类似,只是在发现累加和已经超过2000时,就输出当前累加的数,然后结束循环。
for(int i=1,sum=0;;i++) { sum += i; if(sum > 2000) { cout << i << "," << sum << endl; break; } }
输出结果为:
63,2016
关于这段例子,需要注意三点:1、循环条件初始的位置,我们同时声明两个变量;2、没有循环条件。为了解这两点注意,请看下面放大图:
最后一点注意是关于break和“条件因子变化”的注意。我们知道,for每执行一遍循环体后,都将执行一次“条件因子变化”语句(见上图③)。现在需要注意的是: 在for循环中,执行break后,“条件因子变化”语句同样被跳过,没有被执行循环就被中断。 (完整代码请见lz1.bpr)
至此,break 在 while,do...while,for中的用法我们都已见过。不过,你还记得吗,我们最早学到break是在哪里?在讲条件分支语句中switch里。如果你有点忘了那里的break是起什么作用,现在就去看看吧。
11.1.4 多层循环中的break
break 只能跳出当前层的循环,所以,如果有多层循环,则在内层的break跳出循环后,外层的循环还将继续。
前面说跑步的例子,一圈400米,我们每跑100检查一下是否肚子疼什么的,如果疼得利害就break,不跑了。这和现实不符,我们应该每跑一步就检查一次是否肚子疼最合理。 一圈得分成几步呢?显然不能再像上面分成四次检查那样写代码了。我们加一层循环,也就是把跑一圈的工作用一个循环来实现:
while(一圈未结束) { 跑一步; }
然后,我们在每跑完一步时加入一个判断:
while(一圈未完) { 跑一步;
if(我身体感觉不妙) break; }
把这跑一圈的代码加入外层循环:
while(已跑完图数 < 3) { while(一圈未完) { 跑一步;
if(我身体感觉不妙) break; } }
外层的while用于负责一圈一圈循环跑完三圈,内层的while用于负责一步一步地循环跑完一圈,同时负责每跑一步就检查是否身体不妙,若身体不舒服,就跳出循环,不跑了。看起来代码很完美,其实BUG已经产生:问题就在那个break。当“我身体感觉不妙”后,程序遇上break,跳出内层while,落入外层的while,外层的循环可没有被break,所以程序将继续外层的循环。假如你跑第一圈跑了一半时肚子疼,按照这段程序逻辑,那好这第一圈剩下的一半你可以不用跑了,但后面的两圈你还得继续。 解决的第一种方法是:
while(已跑完图数 < 3) { while(一圈未完) { 跑一步;
if(我身体感觉不妙) break; }
if(我身体感觉不妙) break; }
我们在外层也进行了一次判断,这样当然就可保证从内层跳出来以后,外层的循环也被跳出。但在内层已经做过一次“感觉”的情况下,外层还要重新“感觉”一次,这种代码让人不爽,所以我们可以加一个变量,用于记住现在的身体状态:
bool needBreak = false; //是否需要跳出循环
while(已跑完图数 < 3) { while(一圈未完) { 跑一步;
if(我身体感觉不妙) { needBreak = true; //做一标志,需要break; break; }
if(needBreak) break; }
虽然本人的课程并不是绕什么圈子,可是在这有关break的长篇累牍的文字中,想必各位现在头脑里只有一个词,只有一个念头:break。想 break?后面的课程就不要啦?不可能,我们还是continue吧。
11.2 continue
continue 汉意为继续。它的作用及用法和break类似。重要区别在于,当前循环遇到break,是直接结束循环,而若遇上continue,则是停步当前这一遍循环,然后直接尝试下一遍循环。我把“尝试”加粗以引起注意,为什么要注意原因后面再说,请先看下面关于break和continue的对比:
continue并不结束整个循环,而仅仅是中断的这一遍循环,然后跳到循环条件处,继续下一遍的循环。当然,如果跳到循环条件处,发现条件已不成立,那么循环也将结束,所以我们称为:尝试下一遍循环。
例二:求整数1~100的累加值,但要求跳过所有个位为3的数。 分析:在循环中加一个判断,如果是该数个位是3,就跳过该数不加。
如何判断一个1到100中,哪些整数的个位是3呢?还是 % ,将一个2位以内的正整数,除以10以后,余数是3,就说明这个数的个位为3。 比如: 23 ,除以10,商2,余数3。这里我们不需要商,所以用求余(也称为求模)运算:23 % 10 = 3。
int sum = 0;
for(int i = 1; i<=100;i++) { if( i % 10 == 3) continue;
sum += i; }
cout << sum << endl;
(完整代码请见lz2.bpr)
和break正相反: 在for循环中,执行continue后,“条件因子变化”语句没有被跳过,将被执行一次,然后再尝试循环的下一遍。 在上例中,当条件 i %10 ==3 成立时,continue 被执行,于是,程序首先执行 i++;然后执行 i <= 100 的判断。如果将该段程序改成while,正确答案为:
int sum = 0; int i = 1;
while(i <= 100) { if( i % 10 == 3) { i++; continue; }
sum += i; i++; }
cout << sum << endl;
请注意程序中的两句"i++;",缺一不可。
11.3 goto
臭名昭著的goto出场了。
goto的汉义为“转到”,在计算机语言里,它的完整名称为:“无条件跳转语句”。几乎所有高级语言都会劝你尽量不要使用它goto。因为它会破坏程序的模块性,严重降低一段程序的可读性。若是老外写的书,则比喻使用大量goto的代码:“像意大利面条”。嗯,其实北京的杂酱面也很缠绕……可惜没有走向世界。
goto的用法是,首先要在代码中某处加上一个位标(也称标号),然后在代码中的需处,加上goto,并写让要跳转到位标。比如你在第三行代码加一个位标:A : ,然后可以在第10行写上一个goto A,程序执行到该行时,就将跳到第三行。
加位标的方法是在一空行加上位标的名称,命名规则和变量一样,但最后要加上一冒号“:”。 例如:
int i = 1;
A :
cout << i << endl; i++;
if(i <= 10) goto A;
... ...
goto 虽然号称“无条件跳转”,事实上倒是有些条件限制。主要是三条。 1、goto只能在当前的同一程序段内跳转; 2、goto 可以从循环内跳转到循环外的代码,但不能从循环外的代码跳到循环内; 3、在有goto的跳转范围内,不能再使用C++允许的临时变量声明。
好了,其实笔者写程序近10年,惟一用到goto的地方就是:将一段简单的程序故意用goto写得面目全非,以期能让破解程序的人因为眼晕而放弃功击……一句老话:如果没有什么特殊理由,不要在程序里使用goto。
11.4 流程控制强化训练
这一节将提供一系列的有关流程控制的实例,程序中知识点全部不超过你学到本章时的水平。有些程序需要一些数学上的小小技巧。 所有实例是从建立一个新的控制台工程开始。所以一些由CB自动生成代码我将不写出。你应该知道如何将它们写成一个完整的控制台程序。如果实在有困难也不要紧,各个实例的完整我都已经提供下载。(但只有付费报名学员可以通过课程下载器下载,解密)。
最后,在例子中会出现不少常见的编程技巧,可能在前面的课程中没有直接讲到,我会对这些技巧进行解说。
11.4.1 求绝对值
例三:用户输入一整数,请用程序输出绝对值 分析: 1、本例演示了一个最简单的流程控制:if... 2、同时你可以学到如何求一个数的绝对值,很简单;另外,看一个数是否为负数,就是看它是否小于0,这也很简单。 3、另外,本例使用一个 while(true)来无限循环,你可以不断地输入,如果要中止程序,请按Ctrl+C,这是由操作系统提供的,DOS窗口下中止程序的热键。(因此,本例也无须在最后加 getchar();这行代码)
答案: #include <iostream.h> int main(int argc, char* argv[]) { int num;
while(true) { cout << "求绝对值的程序" << endl; cout << "要中止运行请按 Ctrl + C " << endl;
cout << "==============" << endl; cout << "请输入一个整数:"; cin >> num;
//正数和0的绝对值是本身,负数的绝对值为其相反数 if(num < 0) num = -num;
cout << "绝对值为:" << num << endl << endl; //输出两个换行,仅是为了美观 } }
11.4.2 判断用户输入字符的类型
例四:用户输入一字符,请判断该字符是:大写字母,小写字母,数字字符,其它字符。 分析: 1、本题主要演示多级 if..else... 2、在ASCII表中,题中所提的 前3类字符,其ASSCII值都各自连续(换句话说就是:所有的大写字母都是连续的,所有在小写字母也是连续的……)。基于这一点,你容易看明白代码中为判断字符类型的方法。 3、本解答也采用了循环,所以也不用加getchar()这行代码。关于循环中条件判断方法比较特殊,请见代码后的说明。
#include <iostream.h> #include <conio.h>
int main(int argc, char* argv[]) { char ch; cout << "请输入一个字符:" << endl;
while( (ch = getche()) != '\r' ) { cout << endl; //加一个换行,仅为了输出美观
if( ch >= 'A' && ch <= 'Z') cout << ch << "是一个大写字母。" << endl; else if ( ch >= 'a' && ch <= 'z') cout << ch << "是一个小写字母。" << endl; else if( ch >= '0' && ch <= '9') cout << ch << "是一个数字字符。" << endl; else cout << ch << "是一个其它的字符。" << endl; } }
这段代码中,我们用到了getche()库函数,它的声明包含在 conio.h 文件中,所以本例程除了"#include <iostream.h>"以外,还另需 "#include <conio.h>"。
getche() 和我们常用的 getchar()同样是接收用户从键盘输入的一个字符,但getchar()在用户输入字符后,用户还需要敲一下回车键才能完成输入;而getche()则在用户敲入一个字符后,立即完成。本例中,我们希望如果用户敲一个回车键,则程序自动结束(见下面解析),所以我们采用getche()函数。
现在来看while的循环条件:
while( (ch = getche()) != '\r' )
这行代码依次完成下面两件事: 首先是: ch = getche() ,它等待用户敲入一字符,然后将该字符存储在ch变量。 然后是判断条件: (……) != '\r' 。 程序判断 ch 是否不等于 '\r', '\r' 即回车(return)字符。也就是看用户输入的字符是否为回车键,如果不是,则循环继续,如果是,则循环结束。 记住,在C和C++里 一个赋值表达式: A = B, 本身也有值,值就是完成赋值后的A。在上例中,A是ch,B是 getche()。在C,C++里,几乎所有表达式本身都有值,比如:1+2 的值是3;而表达式 a = 3 的值为3。 理解这段代码,最好的方式就是在CB中运行它。至于我们所要练习的多级if...else在例中的表现,我不再多说,你需要自已看懂它。 最后解释一下 conio.h, 其中 con 即我们总说的控制台,io则和iostream中的io一样,指:input/output。
11.4.3 等腰三角形图形的输出
例五:请输出以下图形: * *** ***** ******* ********* 分析: 新手刚看这道词可能觉得无从下手,其实,如果把图形改成一个矩形:
********* ********* ********* ********* ********* 那么就很好解决了:输出5行,其中每行都输出9个* 。
for(int i=0;i<5;i++) { for(int j=0;j<9;j++) { cout << '*'; } }
对于三角形,程序仍然是这个结构:需要两层循环。同样是要输出5行,所以外层循环不变;不同的地方在于每一行输出的内容。其实三角形同样是输出一个矩形,只不过有些地方要打空格,有些地方要打*,以下我们用“-”表示空格,则三角形实为:
----*---- ---***--- --*****-- -*******- ********* 所以,问题的重点在于:在每一行中,哪些地方要输出空格,哪些地方要输出星号?如果我们行和列都从1开始编号,如图: 仔细观察我们发现,哪一列要打星,哪一列要打空格,主要和该列与第5列(红线所在列)的距离有关: 第 1 行: 只有第5列本身打星,第5列和第5列(自身)的距离是0 第 2 行: 除了第5列以外,增加第4、6列,4和6与5的距离都为1 第 3 行: 增加了3、7两列要打星,3,7两列和5的距离都为2 ……
行了,规律就是:在第n行内,凡是和第5列的距离小于n的列,都要打星,其余的列打空格。 下面代码中,row表示当前行,col表示当前列。
答案:
#include <iostream.h> int main(int argc, char* argv[]) { for(int row=1;row<=5;row++) { for(int col=1;col<=9;col++) { 以下是输出结果:
在本例中,为了保持大家日常生活的习惯,我对行,列的编号均从1开始,其实,C,C++程序员更习惯于编程从0开始,即原来的第1行现在称为第0行,第1列称为第0列,则相关代码如下(黑体部分为改动处):
for(int row=0;row<5;row++) { for(int col=0;col<9;col++) { 学会从0开始索引的思想方法,这也是大家所要注意的,否则在阅读别人代码时会比较困难。
11.4.4 输出正弦曲线图
例六:请在DOS窗口输出正弦曲线图 分析: 1、还记得初中代数学的正弦函数吧? y = sin (x); 当x从0到2π变化时,y的值在 -1 和 +1 之间变化。 我们现在的任务就是随着x(位置)的变化,在y的位置上打一个点即可。 2、C为我们提供了sin的库函数。只要我们给它x的值,它就能计算出相应的y值。sin(x)函数包含在头文件main.h里。 3、为了方便,我们将“竖”着输出曲线,即x的值由上而下增长,而y值则在左右“摇摆”。并且,如果y值为负数的话,那么将输出到屏幕的最左边外面,所以我们将y值统一加上一值,用于向右偏到合适的位置。至于要加多大的值,和第4点有关。 4、和前面输出“等腰三角形”类似。假如我们需要在屏幕的某一行最右边(行末)打出一个点,我们的方法是在前边连续地打满空格。正弦值在 -1到1之间,我们不可能打零点几个空格,所以,需要正弦值放大一定的倍数。
答案: int main(int argc, char* argv[]) { #define PI 3.14159
int scale = 30; //放大倍数 double X,Y;
for(float X = 0.0; X <= 2 * PI; X += 0.1) { // 乘上scale 是为了放大Y值,而加上scale则是为了向右边偏移 // 以保证所有的点都不会跑出屏幕左边。 Y = sin(X) * scale + scale;
//前面打空格 for(int dx = 0;dx<Y;dx++) cout << ' ';
cout << '.' << endl; }
getchar();
return 0; }
完整的代码请查代码文件。由于输出画面太长,所以这里不显示结果图。
11.4.5 标准体重计算程序
尽管类似输出“九九口诀表”、“等腰三角形”,“正弦曲线”这些题目对锻练大家的编程思维颇为有益,但可能很多人都不会喜欢这种题。 嗯,这很多人当中,就有我自已一个。所以,我们来点有趣的题目吧。 街上有一种电子称,你站上去一量身高体重,它就会告诉你的身材是否为标准体重。可是有一天我兴冲冲地往上一站,那机器竟怪里怪气地说:“本仪器不适于非洲儿童……”。害得我当众狼狈而逃! 回去后,我痛下血本,每天大鱼大肉,如此月余,自认为横了一点,很想再测测这回该是哪一洲的儿童。然而由于上次的经历已经对我的造成了极大的心灵伤害,以致于我上街看见那种电子称就腿软。只好自购小站秤一台,米尺一条,不过,如何计算是否标准体重呢?嗯,就是这节课的“标准体重计算程序”了。
计算标准(理想)体重的方法是从网上搜到的:
“最近军事科学院还推出一种计算中国人理想体重的方法: 北方人理想体重=〔身高cm—150〕x0.6十50(kg) 南方人理想体重=〔身高cm—150〕x0.6十48(kg)”
(原文请见:三九健康网)
考虑到女性一般要比男性轻,所以如果是女性,我们还需要将标准体重减去2公斤。
可见,要计算一个人的标准体重,必须知道是男人女人,是北方人还是南方人,及他的身高。 用户还必须输入他的现实体重,这样,在程序计算出标准体重之后,我们计算实际体重在标准体重百分之几的范围之内,作出不同判断。
代码请见例程文件,加有详细的注解。本题事实上没有什么复杂算法,所以比前面的题都要简单--尽管代码看上去长多了。 试用时请注意: 程序需要输入数字时,如果不小心输入字母并回车,将引起死循环,这是cin的问题所致,请按Ctrl + C 强行退出即可。
在课程的最后,测一下自已的体重与“理想体重”的差距,是个不错的选择……测好了?能告诉我程序对你的身材所作的评价吗? |
[到页首]