📄 第11章 循环语句.htm
字号:
<P> 跑一步;
<P>
<P> if(我身体感觉不妙)
<P> <B>
break;</B>
<P> }
<P>}
<P>
<P>外层的while用于负责一圈一圈循环跑完三圈,内层的while用于负责一步一步地循环跑完一圈,同时负责每跑一步就检查是否身体不妙,若身体不舒服,就跳出循环,不跑了。看起来代码很完美,其实BUG已经产生:问题就在那个break。当“我身体感觉不妙”后,程序遇上break,跳出内层while,落入外层的while,外层的循环可没有被break,所以程序将继续外层的循环。假如你跑第一圈跑了一半时肚子疼,按照这段程序逻辑,那好这第一圈剩下的一半你可以不用跑了,但后面的两圈你还得继续。
<P>解决的第一种方法是:
<P>
<P>while(已跑完图数 < 3)
<P>{
<P> while(一圈未完)
<P> {
<P> 跑一步;
<P>
<P> if(我身体感觉不妙)
<P> <B>
break;</B>
<P> }
<P>
<P> if(我身体感觉不妙)
<P> <B> break;</B>
<P>}
<P>
<P>我们在外层也进行了一次判断,这样当然就可保证从内层跳出来以后,外层的循环也被跳出。但在内层已经做过一次“感觉”的情况下,外层还要重新“感觉”一次,这种代码让人不爽,所以我们可以加一个变量,用于记住现在的身体状态:
<P>
<P>bool needBreak = false; //是否需要跳出循环
<P>
<P>while(已跑完图数 < 3)
<P>{
<P> while(一圈未完)
<P> {
<P> 跑一步;
<P>
<P> if(我身体感觉不妙)
<P> {
<P> needBreak =
true; //做一标志,需要break;
<P> <B>
break;</B>
<P> }
<P>
<P> if(needBreak)
<P> <B> break;</B>
<P>}
<P>
<P>虽然本人的课程并不是绕什么圈子,可是在这有关break的长篇累牍的文字中,想必各位现在头脑里只有一个词,只有一个念头:break。想
break?后面的课程就不要啦?不可能,我们还是continue吧。
<P>
<H3><A name=11.2>11.2</A> continue</H3>
<P>
<P>continue
汉意为继续。它的作用及用法和break类似。重要区别在于,当前循环遇到break,是直接结束循环,而若遇上continue,则是停步当前这一遍循环,然后直接<B>尝试</B>下一遍循环。我把“尝试”加粗以引起注意,为什么要注意原因后面再说,请先看下面关于break和continue的对比:
<P>
<P><IMG height=345 src="第11章 循环语句.files/ls11.h3.gif" width=443 border=0>
<P>continue并不结束整个循环,而仅仅是中断的这一遍循环,然后跳到循环条件处,继续下一遍的循环。当然,如果跳到循环条件处,发现条件已不成立,那么循环也将结束,所以我们称为:<B>尝试</B>下一遍循环。
<P>
<P><B>例二:</B>求整数1~100的累加值,但要求跳过所有个位为3的数。
<P><B>分析:</B>在循环中加一个判断,如果是该数个位是3,就跳过该数不加。
<P>
<P>如何判断一个1到100中,哪些整数的个位是3呢?还是 % ,将一个2位以内的正整数,除以10以后,余数是3,就说明这个数的个位为3。
<P>比如: 23 ,除以10,商2,余数3。这里我们不需要商,所以用求余(也称为求模)运算:23 % 10 = 3。
<P>
<P>int sum = 0;
<P>
<P>for(int i = 1; i<=100;i++)
<P>{
<P> if( i % 10 == 3)
<P> continue;
<P>
<P> sum += i;
<P>}
<P>
<P>cout << sum << endl;
<P>
<P>(完整代码请见lz2.bpr)
<P>
<P>和break正相反:
<P><B>在for循环中,执行continue后,“条件因子变化”语句没有被跳过,将被执行一次,然后再尝试循环的下一遍。</B>
<P>在上例中,当条件 i %10 ==3 成立时,continue 被执行,于是,程序首先执行 i++;然后执行 i <= 100
的判断。如果将该段程序改成while,正确答案为:
<P>
<P>int sum = 0;
<P>int i = 1;
<P>
<P>while(i <= 100)
<P>{
<P> if( i % 10 == 3)
<P> {
<P> <FONT color=#000000><SPAN
style="BACKGROUND-COLOR: #ffff00"> i++;</SPAN></FONT>
<P> continue;
<P> }
<P>
<P> sum += i;
<P> <SPAN style="BACKGROUND-COLOR: #ffff00">i++;</SPAN>
<P>}
<P>
<P>cout << sum << endl;
<P>
<P>请注意程序中的两句"i++;",缺一不可。
<P>
<H3><A name=11.3>11.3</A> goto</H3>
<P>
<P>臭名昭著的goto出场了。
<P>
<P>goto的汉义为“转到”,在计算机语言里,它的完整名称为:“无条件跳转语句”。几乎所有高级语言都会劝你尽量不要使用它goto。因为它会破坏程序的模块性,严重降低一段程序的可读性。若是老外写的书,则比喻使用大量goto的代码:“像意大利面条”。嗯,其实北京的杂酱面也很缠绕……可惜没有走向世界。
<P>
<P>goto的用法是,首先要在代码中某处加上一个位标(也称标号),然后在代码中的需处,加上goto,并写让要跳转到位标。比如你在第三行代码加一个位标:A
: ,然后可以在第10行写上一个goto A,程序执行到该行时,就将跳到第三行。
<P>
<P>加位标的方法是在一空行加上位标的名称,命名规则和变量一样,但最后要加上一冒号“:”。
<P>例如:
<P>
<P>int i = 1;
<P>
<P><B>A :</B>
<P><B></B>
<P>cout << i << endl;
<P>i++;
<P>
<P>if(i <= 10)
<P><B> goto A;</B>
<P>
<P>... ...
<P>
<P>goto 虽然号称“无条件跳转”,事实上倒是有些条件限制。主要是三条。
<P>1、goto只能在当前的同一程序段内跳转;
<P>2、goto 可以从循环内跳转到循环外的代码,但不能从循环外的代码跳到循环内;
<P>3、在有goto的跳转范围内,不能再使用C++允许的临时变量声明。
<P>
<P>好了,其实笔者写程序近10年,惟一用到goto的地方就是:将一段简单的程序故意用goto写得面目全非,以期能让破解程序的人因为眼晕而放弃功击……一句老话:如果没有什么特殊理由,不要在程序里使用goto。
<P>
<H3><A name=11.4>11.4</A> 流程控制强化训练</H3>
<P>
<P>这一节将提供一系列的有关流程控制的实例,程序中知识点全部不超过你学到本章时的水平。有些程序需要一些数学上的小小技巧。
<P>所有实例是从建立一个新的控制台工程开始。所以一些由CB自动生成代码我将不写出。你应该知道如何将它们写成一个完整的控制台程序。如果实在有困难也不要紧,各个实例的完整我都已经提供下载。(但只有付费报名学员可以通过课程下载器下载,解密)。
<P>
<P>最后,在例子中会出现不少常见的编程技巧,可能在前面的课程中没有直接讲到,我会对这些技巧进行解说。
<P>
<H4><A name=11.4.1>11.4.1</A> 求绝对值</H4>
<P>
<P><B>例三:</B>用户输入一整数,请用程序输出绝对值
<P><B>分析:</B>
<P>1、本例演示了一个最简单的流程控制:if...
<P>2、同时你可以学到如何求一个数的绝对值,很简单;另外,看一个数是否为负数,就是看它是否小于0,这也很简单。
<P>3、另外,本例使用一个
while(true)来无限循环,你可以不断地输入,如果要中止程序,请按Ctrl+C,这是由操作系统提供的,DOS窗口下中止程序的热键。(因此,本例也无须在最后加
getchar();这行代码)
<P>
<P><B>答案:</B>
<P>#include <iostream.h><BR> </P>
<P><SPAN lang=EN-US>int main(int argc, char* argv[])</P></SPAN>
<P>{
<P> int num;
<P>
<P> while(true)
<P> {
<P> cout << "求绝对值的程序"
<< endl;
<P> cout << "要中止运行请按 Ctrl
+ C " << endl;
<P>
<P> cout <<
"==============" << endl;
<P> cout << "请输入一个整数:";
<P> cin >>
num;
<P>
<P> //正数和0的绝对值是本身,负数的绝对值为其相反数
<P> if(num < 0)
<P> num =
-num;
<P>
<P> cout << "绝对值为:"
<< num << endl << endl; //输出两个换行,仅是为了美观
<P> }
<P>}
<P>
<H4><A name=11.4.2>11.4.2</A> 判断用户输入字符的类型</H4>
<P>
<P><B>例四:</B>用户输入一字符,请判断该字符是:大写字母,小写字母,数字字符,其它字符。
<P><B>分析:</B>
<P>1、本题主要演示多级 if..else...
<P>2、在ASCII表中,题中所提的
前3类字符,其ASSCII值都各自连续(换句话说就是:所有的大写字母都是连续的,所有在小写字母也是连续的……)。基于这一点,你容易看明白代码中为判断字符类型的方法。
<P>3、本解答也采用了循环,所以也不用加getchar()这行代码。关于循环中条件判断方法比较特殊,请见代码后的说明。
<P>
<P>#include <iostream.h>
<P>#include <conio.h>
<P> <SPAN lang=EN-US>
<P>int main(int argc, char* argv[])</P></SPAN>
<P>{
<P> char ch;
<P> cout << "请输入一个字符:" << endl;
<P>
<P> while( (ch = getche()) != '\r' )
<P> {
<P> cout << endl;
//加一个换行,仅为了输出美观
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -