C++程序设计课本翻译programming - in - C++-紧缩版(10)

2019-08-01 23:13

让我们再一次追踪程序,假如,我们不能打开输入文件,当从open函数返回时,流infile是处在失败状态,在if语句中,表达式!infile的值是true ,而且,then从句被执行,程序打印出一个错误信息给用户,然后中止程序,返回一个退出状态1值告知操作系统是一个不正常的程序中止。 (我们选择值1为退出状态纯粹是任意的,编程者有时使用不同的值来标记不同的程序中断原因,但是大多人只使用值1)。 无论何时你打开一个数据文件作为输入,在继续之前一定要测试流状态,如果你忘了测试,计算机不能打开文件,你的程序平静地继续执行并且忽视任何有关文件的输入操作。

第六章 循环

目标:

? 能够构造符合语法的、正确的while循环 ? 能够用while 语句构造计数控制循环 ? 能够用while语句构造事件控制循环 ? 能够使用文件结束条件控制数据输入 ? 能够使用标志控制一个while语句的执行 ? 能够用while语句构造一个计数循环 ? 能够用while语句构造一个求和循环 ? 能够为所给的问题选择正确的循环类型 ? 能够构造嵌套while循环

? 能够选择数据设置,测试一个综合地循环程序 循环:引起一条语句或成组的语句重复执行的控制结构。

只要一个条件或条件设置被满足,循环就一遍又一遍地执行同样的语句(简单的或复合的语句)。 在这章中,我们讨论不同种类的循环和如何用while语句构造循环。我们也讨论嵌套循环(包含另一个循环的循环) 6.1 while语句

while 语句,像If语句一样要测试一个条件,这里是while语句的语法模板。

这是一个例子:

while ( inputval != 25 ) cin >> inputval ;

while语句是一个循环控制结构,通过循环每次都执行的语句被称为循环体。在上面例子中,循环体是输入语句,读入一个值到变量inputval中。这个while 语句是说,只要输入值不是等于25,重复执行循环体,当inputval变量的值等于25,while 语句循环完成(因此,循环停止)。然而,这个循环的效果是销毁和忽略所有输入流中的值,直到数据25被读到为止。

正像If语句中的条件一样,在while语句中条件可以是任何简单数据类型的表达式。几乎条件总是一个逻辑(布尔)表达式,如果不是,它的值强制为布尔类型(回想一下,零值是强制为false,并且任何非零值被强制为true),while语句的表述是:“如果表达式的值是true,执行循环体,然后回过来再测试表达式。如果表达式的值是false,跳过循环体。”只要被测试的表达式是true,就一遍又一遍的执行循环体。当表达式是false,程序跳过循环体并继续执行紧跟着循环后面的语句,当然,如果表达式开始就是false,循环体甚至一次也不执行。图6-1显示了while语句的控制流程,这里statement1是循环体和statement2是紧跟着循环后面的语句

一个循环体可以是复合语句(块),这允许我们重复执行任何语句组。大多数情况下,我们常使用以下形式的while循环: while(表达式) { ? }

在这个结构中,如果表达式是true,在块中的全部系列语句被执行,然后表达式再次被检测,如果它仍是true,块语句再次被执行,循环一直继续到表达式成为false为止。

6.2 循环执行阶段

循环体执行的几个阶段:

? 循环进入:控制流程达到在循环体内第一条语句的位置。 ? 重复:独立贯穿执行循环体一趟。

? 循环测试:求表达式的值决定是开始一个新重复还是立即跳过循环体语句接着循环语句后面的语句继续执行的地方。

? 循环退出:循环体的重复结束并且控制转向循环后面的第一条语句的地方。

? 中止条件:引起循环结束条件。就while循环来说,结束条件是while表达式成为false。

注意循环退出仅出现在一种地方:当循环测试被执行时,即使结束条件也许在循环执行过程中被满足,但在计算机再次检查while表达式之前,当前重复仍被执行。 6.3 使用while语句构成循环

在解决问题中,你将会遇到两个主要循环类型:计数控制循环,这种循环重复执行指定的次数;事件控制循环,重复执行循环体直到循环内某件事情发生为止。 计数控制循环

计数控制循环在循环测试中,使用一个我们称之为“循环控制变量”。在我们进入计数控制循环之前,我们必须初始化(设置初始值)循环控制变量,那后对它进行测试,再把循环控制变量作为每次重复的循环的部分,我们必须对循环控制变量加1。这是一个例子: loopCout =1 ; //初始化 while (loopCout <= 10) //测试 {

? //重复活动

loopCout ++ ; //循环控制变量加1 }

这里,loopCout是循环控制变量,在循环进入之前,它被设置为1。while语句测试表达式 loopCout <= 10

只要表达式是true,执行循环体,在复合语句内部的点表示要重复的一系列语句。循环体中的最后一条语句将loopCount的值增加,以这种方法使用的变量被称为计数器,在我们的例子中,每次循环重复执行loopCout就增加一次――我们使用loopCout来计数重复执行次数。计数控制循环中的循环控制变量总是一个计数器。

当设计循环时,编程者的职责是看看被测试的条件在while语句开始之前被正确设置(初始化)。编程者也必须确定在循环内条件会改变以便它最终会变成false ;否则,循环就决不会退出。

一个循环决不退出被称是为无休止循环,因为,在理论上循环执行是永远的。在上面的代码中,省略循环底部的loopCout值的增加,会导致无休止循环。由于loopCout变量永远是1,while表达式始终是true。如果你的程序持续运行比你期望的时间要长的多,可能你已经产生了一个无休止循环。你也许不得不发出一个操作系统命令来终止程序。 事件控制循环

有几种形式的事件控制循环:标记控制,文件结束控制和特征控制。在这些循环中,循环中止条件取决于循环体被执行时的某些事件的出现。

标记控制循环:循环常被用来读入和处理长数据表,一个新的数据块被读入和处理时,每次循环体都被执行。通常一个被称为一个标记或尾部值的特殊数据,被用来标记程序不再有数据要被处理。只要读入的数据值不是标记值,循环就继续做下去。换句话说,读标记值是控制循环处理的事件。

一个标记值必须是某些决不会出现在正常输入到程序中的值。例如,如果一个程序读日历数据,我们可以使用2月31日作为一个标记值。

cin >> month >> day ; //得到一个数据——初始读值 while (!(month = =2 && day = =31) {

? // 对它(2月31日)进行处理 cin >> month >>day ; // 得到下一个数据 }

这个代码段在进入循环之前首先读入两个数据(我们把这称为初始读值),如果不是标记值,它得到处理。在循环的末尾下一个数据被读入,并且我们返回到循环的开始。如果新读入的数据不是标记值,它像第一个那样得到处理;当标记值被读到,while表达式成为false并且循环退出(不处理标记值)。 常常问题指挥着标记的值。例如,如果问题不允许有数据值0,那么标记值应设置为0,当你处理字符数据时,一次输入一行,新行字符('/n')常被作为标记。这里是一个读入和打印一个输入行所有字符的代码段(inChar 是 char 类型):

cin.get (inChar) ; // 得到第一个字符 while ( inChar != '/n' ) {

cout << inChar ; // 回显它的值 cin.get (inChar) ; //得到下一个字符 }

注意,对于这样特殊的工作,我们必须使用get函数,不要使用运算符“》”来输入一个字符,记住“》”运算符会跳过空白字符(空白字符包括空格和新行字符)在输入流中寻找下一个数据值。在这个例中,我们想要输入每个字符,甚至是空格和特殊地新行字符 。

在我们继续之前,我们提及一个不仅与循环设计有关而且与C++语言的使用有关的讨论。在第5章中,我们谈到了在If条件中,用赋值运算符(=)取代关系运算符(= =)的常见错误。当你写while语句时,相同的错误也会发生。看下例中,当我们使用错误运算符时会发生什么(每对输入数据中的第二个数据被作为标记值。除最后一对数据外,每对输入数据它都等于1,最后一对数据等于0,意味着不再有数据输入)。 cin >> dataValue >>sentinel ; while ( sentinel = 1) // 错误操作符 { ?

cin >> dataValue >> sentinel ; }

这个错误产生一个无休止的循环,while表达式现在是一个赋值表达式,不是一个关系表达式。表达式

的值是1(由于它是非零值,在循环测试中解释为1)并且它的负影响是存储值1到标记中,取代刚刚被输入到变量中的值。由于while表达式始终是true,循环决不会终止。

文件结束控制循环:在一个程序从一个输入文件读入最后数据段后,计算机是在文件的结尾(简称为EOF),在这个时刻,输入流状态是正确的。但是如果我们再多输入即使是多一个数据的值,输入流转向失败状态。我们可以利用这个有利的事实。为了写一个输入不知数据项数目的循环,我们可以使用输入流的失败状态作为一个标记的形式。

在第5章中,我们描述了如何测试一个I/O流的状态,在一个逻辑表达式中,我们使用流名就好像使用一个布尔变量一样。 if (inFile) ?

在这样的一个测试中,如果最近的I/O操作是成功的,结果为true,如果失败结果为false。在while语句中,测试流的状态用相同的方法。假如我们有一个包含整数值的数据文件,如果在我们的程序中,inDate是文件流的名字, 这里是一个读入和回显文件中所有数据值的循环: inData >> intVal ; // 得到第一个值 while (inData) // 当输入成功 {

cout << intVal << endl ; // 回显输入值 inData >> intVal ; // 得到下一个值 }

让我们跟踪这个代码,假设在文件中有三个值:10,20和30,初始读到输入值是10,由于输入成功,while条件为true,因此计算机执行循环体,首先循环体打印出值10,然后输入第2个数据值20,循环反回到循环测试位置,由于输入成功,表达式inData是true,循环体再次被执行,打印值20并从文件中读入值30,循环返回到测试位置,表达式是true,即使读入的数是在文件的结尾,流状态仍然是OK——因为前面的输入操作是成功的,循环体执行第3次,打印值30,并执行输入语句,这次输入语句读失败,因为我们试图读文件结尾以外的数据,输入流inData进入失败状态,循环返回到循环测试位置,表达式的值是false,程序退出循环。

当我们写像上面一样的EOF-控制循环时,我们希望文件的结尾是流失败的结果,但是记住任何输入错误都会引起流失败。例如,上面循环中断是由于输入数据中无效字符的输入引起的。这个事实再一次强调了回打印的重要性,它帮助我们证实在遇到EOF之前,所有读入的数据都是正确的。

特征控制循环:一个特征值是用来控制一个程序逻辑流的布尔变量。我们在while循环之前设置一个值为true布尔变量,然后,当我们想要停止执行循环,我们重新设置它为false,即,我们可以使用布尔变量来记录控制过程的事件是否会出现。例如,下列代码段读入数据并求它们的和值,直到输入值是负数为止: sum = 0 ;

nonnegative = true ; // 初始特征值 while ( nonnegative ) {

cin >> number ;

if ( number < 0 ) // 测试输入值

nonNegative = false ; // 如果事件出现,设置特征值为false else

sum = sum + number ; }

注意,我们可以用特征值编写标志控制循环,事实上,这个代码使用一个负值作为标志。

循环子任务

我们已经看到了使用循环来影响程序中控制流程的方法。但是循环自身不做什么事情,为了循环完成某些事情,循环体必须有序执行一项工作,在这部分,我们看三项工作——计数、求和、记录前面的值——经常在循环中使用。

计数:循环中一项通常的工作是记录执行循环的次数。例如,下列程序段读入并计数输入的字符直到出现一个句号为止。(inChar 具有char类型;count具有int 类型),这个例子中的循环有一个计数变量,由于变量不被作为一个循环控制变量,所以循环不是一个计数控制循环。 count = 0 ; //初始化计数器

cin.get ( inchar ) ; //读第一个字符 while (inchar != '.') {

count ++ ; //计数器增值

cin.get (inchar ) ; //得到下一个字符 }

在循环结束后,count包含数据比读入的字符数少,即它计数字符数目直至标记值(句号),但不包含句号标记值。注意如果句号是第一个字符,不进入循环体并且count包含一个0值作为它应有的值。由于循环是标记控制,这里我们要使用一个初始读数。

在这个例子中的计数器变量被称为重复计数器,因为它的值等于通过循环的重复次数。

按照我们的定义,计数控制循环的循环控制变量是一个重复计数器,可是,像你看到那样,不是所有重复计数器都是循环控制变量。

求和:另一个通常的循环工作是求一组数据值的和。注意在下列的例子中,不管如何控制循环,同样的方法写求和操作。

sum = 0 ; // 对sum初始化 count =1 ;

while (count <=10 ) {

cin >>number ; // 输入一个值

sum = sum + number ; // 增加值到sum中 count + + ; }

在循环开始之前,我们对sum初始化值为0,以便第1次执行循环体,语句 sum = sum + number ;

增加当前sum (0) 的值到number上形成新的sum值,在全部代码段执行完后,sum包含了10个读入值的总和,count包含11,并且number包含的是最后读入的值。

记录以前的值:有时我们想要记住变量以前的值。假如我们要在一个包含C++程序的文件中,写一个计数不等号的程序。我们可以简单地做这样:计数在输入数据中,一个感叹号(!)后面紧跟者出现一个等号(=)的次数。这样做的一种方法是,一次从输入文件中读一个字符,记录两个最近的值,当前值和前一个值。每次重复循环,读新的当前值并且旧的当前值成为前一个值。当读到EOF时,循环结束。这里是一个以这种方法编写的计数不等号的循环。 count = 0 ; // 初始化counter

inFile.get (prerChar ) ; // 初始化前一个值 inFile.get (currChar ) ; // 初始化当前值 while (inFile) // 当输入成功 {


C++程序设计课本翻译programming - in - C++-紧缩版(10).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:住房公积金 - 专办员试题与答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: