好文档 - 专业文书写作范文服务资料分享网站

信息学奥赛培训教程C++版

天下 分享 时间: 加入收藏 我要投稿 点赞

Determine the class avcraqe for the quiz

上层伪代码只是一个语句,表示程序的总体功能。这样.上层等于是程序的完整表达式。但上层通常无法提供编写C++程序所需的足够细节。因此要开始完善过程。我们将上层伪代码分解为一系列的小任务,按其需要完成的顺序列出。这个结果就是下列第一步完善(first,refinement):

Initialize variables

Input,sum,and count the quiz grades Calculate and print the class average

这里只用了顺序结构,所有步骤按顺序逐步执行。

要进行下一步完善(即第二步完善,second refinement),我们要指定特定变量,要取得数字的动态和以及计算机处理的数值个数,用一个变量接收每个输入的成绩值,一个变量保存计算平均值。下列伪代码语句:

Initialize variables

可以细化成:

Initialize total to zero Initialize counter to zero

注意,只有total和counter变量要先初始化再使用,average和grade变量(分别计算平均值和用户输入)不需要初始化.因为它们的值会在计算或输入时重定义。

下列伪代码语句:

Input, sum, and count the quiz grades

需要用重复结构(即循环)连续输入每个成绩。由于我们事先不知道要处理多少个成绩,因此使用标记控制重复。用户一次一项地输入合法成绩。输入最后一个合法成绩后,用户输人标记值。程序在每个成绩输入之后测试其是否为标记值.如果用户输入标记值,则顺序循环终止。上述伪代码语句的第二步完善如下:

Input the first grade (possibly the sentinel)

While the user has not as yet entered the sentinel Add this grade into the running total Add one to the grade counter

Input the next grade (possibly the sentinel)

注意,在这个伪代码中,我们没有在while结构体中使用花括号,只是在while下面将这些语句缩排表示它们属于while。伪代码只是非正式的程序开发辅助工具。

下列伪代码语句可以完善如下: If the counter is not equal to zero

Set the average to the total divided by the counter Print the average else

Print \

注意我们这里要测试除数为0的可能性,这是个致命逻辑错误,如果没有发现,则会使程序失败(通常称为爆炸或崩溃)。以上显示了全班平均成绩问题第二步完善的完整伪代码语句。伪代码中增加了一些空行,使伪代码更易读。空行将程序分成不同阶段。

图6.8所示的伪代码算法解决更一般的全班平均成绩问题,这个算法只进行了第二步完善,还

需要进一步完善。

-81-

Initialize total to zero Initialize counter to zero

Input the first grade (possibly the sentinel)

While the user has not as yet entered the sentinel Add this grade into the running total Add one to the grade counter

Input the next grade (possibly the sentinel)

if the counter is not rqual to zero

Set the average to the total divided by the counter Print the average else

Print \

图6.8 用标记符控制重复解决全班平均成绩问题的伪代码算法

图6.9显示了C++程序和示例执行结果。尽管只输入整数成绩,但结果仍然可能产生带小数点的平均成绩,即实数。int类型无法表示实数,程序中引入float数据类型处理带小数点的数(也称为浮点数,floatingpoint number),并引入特殊的强制类型转换运算符(cast operator)处理平均值计算。这些特性将在程序之后详细介绍。

1 // Fig. 2.9: fig02_09.cpp

2 // Class average program with sentinel-controlled repetition. 3 #include 4 #include 5

6 int main() 7 {

8 int total, // sum of grades

9 gradeCounter, // number of grades entered 10 grade; // one grade

11 float average; // number with decimal point for average 12

13 // initialization phase 14 total = 0;

15 gradeCounter = 0; 16

17 // processing phase

18 cout << \ 19 cin >> grade; 2O

21 while ( grade !=-1 ) { 22 total = total + grade;

-82-

23 gradeCounter = gradeCounter + 1; 24 cout << \ 25 cin >> grade; 26 } 27

28 // termination phase

29 if ( gradeCounter != 0 } {

30 average - static_cast< float >( total ) / gradeCounter; 31 cout << \ 32 << setiosflags( ios::fixed | ios::showpoint ) 33 << average << endl; 34 } 35 else

36 cout << \ 37

38 return 0; // indicate program ended successfully 39 }

输出结果:

Enter grade, -1 to end: 75 Enter grade, -1 to end: 94 Enter grade, -1 to end: 97 Enter grade,-1 to end: 88 Enter grade, -1 to end: 70 Enter grade, -1 to end: 64 Enter grade, -1 to end: 83 Enter grade, -1 to end: 89 Enter grade, -1 to end: -1 Class average is 82.50

图6.9 用标记符控制重复解决全班平均成绩问题的C++程序和示例执行结果

注意图6.9中while循环中的复合语句。如果没有花括号,则循环体中的最后三条语句会放到循环以外,使计算机错误地理解如下代码:

while ( grade ! = -1 ) total - total + grade;

gradeCounter = gradeCounter + 1; cout << \ cin >> grade;

如果用户输入的第一个成绩不是-l,则会造成无限循环。 注意下列语句: cin >> grade;

-83-

前面用一个输出语句提示用户输入。

平均值并不一定总是整数值,而常常是包含小数的值,如7.2或-93.5。这些值称为浮点数,用数据类型float表示。变量average声明为数据类型float,以获得计算机结果中的小数。但total/gradeCounter的计算结果是整数,因为total和gradeCounter都是整数变量。两个整数相除是整除(integer division),小数部分丢失(即截尾,truncated)。由于先要进行计算,因此小数部分在将结果赋给average之前已经丢失。要用整数值进行浮点数计算,就要先生成用于计算的临时浮点数值。

C++提供了一元强制类型转换运算符(unary cast operator)。下列语句: average = static cast< float >(total) / gradeCounter;

包括一元强制类型转换运算符static_cast(),生成用于计算的临时浮点数值(total)。这样使用强制类型转换运算符称为显式类型转换(explicit conversion)。total中存放的值还是整数,而计算时则用浮点数值(total的临时float版本)除以整数gradcCounter。

c++编译器只能对操作数的数据类型一致的表达式求值。要保证操作数的数据类型一致,编译器对所选择的操作数进行提升(promotion)操作(也称为隐式类型转换,implicit conversion)。例如,在包含数据类型float和int的表达式中,int操作数提升为float。本例中,gradeCounter提升为float之后进行计算,将浮点数除法得到的结果赋给average。本章稍后将介绍所有标准数据类型及其提升顺序。任何数据类型都可用强制类型转换运算符,static_cast运算符由关键字statlc cast加尖括号(<>)中的数据类型名组成。强制类型转换运算符是个一元运算符(unary perator),即只有一个操作数的运算符。第1章曾介绍过二元算术运算符。C++也支持一元正(+)、负(-)运算符,程序员可以编写-7、+5之类的表达式。强制类型转换运算符从右向左结合,其优先级高于正(+)、负(-)运算符等其他一元运算符,该优先级高于运算符*、/和%,但低于括号的优先级。优先级表中用static_cast()表示强制类型转换运算符。

图6.9中格式化功能将在第2章详细介绍,这里先做一简要介绍。下列输出语句中调用 setpreclslon(2):

cout<<\ << Setiosflaqs(iOS::fixed |iOS::showpoint) <

表示float变量average打印小数点右边的位数为两位精度(precision),例如92.37,这称为参数化流操纵算子(parameterized stream manipulator)。使用这些调用的程序要包含下列预处理指令:

#include

注意endl是非参数化流操纵算子(nonparameterized stream manipulator),不需要iomanip.h头文件。如果不指定精度,则浮点数值通常输出六位精度(即默认精度,default precision),但稍后也会介绍一个例外。

上述语句中的流操纵算子setiosflags(ios::fixed | ios::showpoInt)设置两个输出格式选项ios::fixed和ios::showpoint。垂直条(1)分隔setiosflags调用中的多个选项(垂直条将在第16章详细介绍)。选项ios::fixed使浮点数值以浮点格式(而不是科学计数法,见第2章)输出。即使数值为整数,ios::showpoInt选项也会强制打印小数点和尾部O,如88.OO。如果不用ios::showpoint选项,则C++将该整数显示为88,不打印小数点和尾部0。程序中使用上述格式时,将打印的值取整,表示小数点位数,但内存中的值保持不变。例如,数值87.945和67.543分别输出为87.95和67.54。

尽管浮点数算不总是100%精确,但其用途很广。例如,我们说正常体温98.6(华氏温度)时,并不需要精确地表示,如果温度计上显示98.6度.实际上可能是98.5999473210643度。这里显示98.6对大多数应用已经足够了。

-84-

另一种得到浮点数的方法是通过除法。10除以3得到3.333333??,是无限循环小敷。计算机只分配固定空间保存这种值,因此只能保存浮点值的近似值。

6.9 构造算法与自上而下逐步完善:实例研究3(嵌套控制结构)

下面介绍另一个问题。这里还是用伪代码和自上而下逐步完善的方法构造算法,然后编写相应的C++程序。我们介绍过按顺序堆叠的控制结构,就像小孩堆积木一样。这里显示C++中控制结构的另一种方法,称为嵌套控制结构。

考虑下列问题:

学校开了一门课,让学生参加房地产经纪人证书考试。去年,几个学生读完这门课并参加了证 书考试。学校想知道学生考试情况,请编写一个程序来总结这个结果。已经得到了10个学生 的名单,每个姓名后面写1时表示考试通过,写2时表示没有通过。

程序应分析考试结果,如下所示: 1.输入每个考试成绩(即l或2),每次程序请求另一个考试成绩时,在屏幕上显示消息“Enter result\。

2.计算每种类型的考试成绩数。

3.显示总成绩,表示及格人数和不及格人数。

6.如果超过8个学生及格,则打印消息“Raise tuition”。

认真分析上述问题后,我们做出下列结论:

1.程序要处理10个考试成绩,用计数器控制循环。

2.每个考试成绩为数字l或2,每次程序读取考试成绩时,程序要确定成绩是否为数字1或2。

我们的算法中测试1,如果不是l,则我们假设其为2(本章末尾的练习会考虑这个假设的结果)。

3.使用两个计数器,分别计算及格人数和不及格人数。

4.程序处理所有结果之后,要确定是否有超过8个学生及格。

下面进行自上而下逐步完善的过程。首先是上层的伪代码表示: Analyze exam results and decide if tuition should be raised 我们再次强调,顶层是程序的完整表达,但通常要先进行几次完善之后才能将伪代码自然演变成C++程序。我们的第一步完善为:

Initialize variables

lnput the ten quiz qrades and COU~t passes and failures

Print a sugary Of the cxam results and decide if tuition should be raised

这里虽然有整个程序的完整表达式,但还需要进一步完善。我们要提供特定变量。要用两个计数器分别计算,用一个计数器控制循环过程,用一个变量保存用户输入。伪代码语句:

Initialize variables 可以细分如下:

Initialize passes to zero lnitialize failules to zero Inltiallze student counter to One

注意.这里只初始化计数器和总和。伪代码语句:

-85-

7147t1zw3j3ef8l93ts6
领取福利

微信扫码领取福利

微信扫码分享