2.15 for 结构使用举例
下面的例子显示for结构中改变控制变量的方法。在每个例子中.我们都编写相应的for结构首部。注意循环中递减控制变量的关系运算符的改变。
1、将控制变量从1变到100,增量为1。
for(int i=l; i<=100; i++)
2、将控制变量从100变到1,增量为-1。
for(int i=100; i>=1; i--)
常见编程错误2.17
循环向下计数时如果循环条件中不使用正确的关系运算符(如在向下计算到1的循环中使用i<=1)通常是个逻辑错误,会在程序运行时产生错误结果。
3、控制变量的变化范围为7到77。
for(int i= 7; i <= 77; i+= 7)
4、控制变量的变化范围为20到2。
for(int i=20; i>=2; i-=2)
5、按所示数列改变控制变量值:2、‘、8、11、14、17、20。
for(int j=2; j<=20; j+=3)
6、按所示数列改变控制变量值:99、88、77、66、55、44、33、22、ll、O。
for(int j=99; j>=O; j-=11)
下面两个例子提供for结构的简单应用。图2.20所示的程序用for结构求2到100的所有整数的总和。
注意图2.20中for结构体可以用下列逗号运算符合并成for首部的右边部分:
for(int number = 2; // initialization number <= 100; // continuation condition sum += number, number += 2) // total and increment
初始化 sum=0 也可以合并到 for 的初始化部分。
// Fig. 2.20: figO2_20.cpp // Summation with for #include int main(){ int sum = O; for (int number = 2; number <= 100; number += 2 ) sum += number; cout << "Sum is "<< sum << endl; return O; }
输出结果:
sum is 2550
图2.20 用 for 语句求和
编程技巧2.23
尽管for前面的语句和for结构体的语句通常可以合并到for的首部中,但最好不要这么做,因为这样会使程序更难阅读。
编程技巧1.24
尽可能将控制结构首部的长度限制为一行。
下列用for结构计算复利。考虑下列问题:
一个人在银行存款1000.00美元,每利率为5%。假设所有利息留在账号中,则计算10年间每年年末的金额并打印出来。用下列公式求出金额:
a=P(1+r)n
其中:
- P是原存款(本金)
- r是年利率
- n是年数
- a是年未本息
这个问题要用一个循环对10年的存款进行计算。解答如图2.21,for结构执行循环体10次,将控制变量从1变到10,增量为1。C++中没有指数运算符,因此要用标准库函数pow。函数pow(x,y)计算x的y次方值。函数pow取两个类型为double的参数并返回double值。类型double与float相似,但double类型的变量能存放比float精度更大的数值。C++把常量(如图2.21中的1000.0和.05)当作double类型处理。
// Fig. 2.21: fig02_21.cpp // Calculating compound interest #include #include #include int main(){ double amount, // amount on deposit principal = 1000.0, // starting principal rate = .05; // interest rate cout << "Year" << setw( 21 ) << "Amount on deposit" << endl; for ( int year = 1; year <= 10; year++ ) { amount = principal * pow ( 1.0 + rate, year ); cout << setw( 4 ) << year << setiosflags( ios::fixed I ios::showpoint ) << setw( 21 ) << setprecision( 2 ) << amount << endl; } }
输出结果:
Year Amount on deposic 1 1050.00 2 1102.50 3 1157.62 4 1215.51 5 1276.28 6 1340.10 7 1407.10 8 1477.46 9 1551.33 10 1628.89
图 2.21 用for结构计算复利
这个程序必须包括math.h才能编译。函数pow要求两个double参数,注意year是个整数。math.h文件中的信息告诉编译器将year值转换为临时double类型之后再调用函数。这些信息放在pow的函数原型(function prototype)中。第3章将介绍函数原型并总结pow函数和其他数学库函数。
常见编程错误1.18
程序中使用数学库函数而不包括math.h头文件是个语法错误。
程序中将变量amount、principal和rate声明为double类型,这是为了简单起见,因为我们要涉及存款数额的小数部分,要采用数值中允许小数的类型。但是,这可能造成麻烦,下面简单介绍用float和double表示数值时可能出现的问题(假设打印时用setprecision(2)):机器中存放的两个float类型的值可能是14.234(打印14.23)和18.673(打印18.67)。这两个值相加时,内部和为32.907,打印32.91。结果输出如下:
14.23 + 18.67 ---------- 32.91
但这个加式的和应为32.90。
编程技巧2.25
不要用float和double表示一些货币值。浮点数是不精确的,可能导致错误,产生不准确的货币值。练习中将介绍用整数值进行货币计算。注意:c++类库可以用于正确地进行货币计算。
输出语句:
cout<<setw(4)<<year <<setiosflags(10s::fixed los::showpoint) << setw(21) << setpreclsion(2) << amount<<endl;
用参数化流操纵算于setw、setiosflags和setprecision指定的格式打印变量year和amount的值。调用selw(4)指定下一个值的输出域宽(field width)为4,即至少用4个字符位置打印这个值。如果输出的值宽度少于4个字符位,则该值默认在输出域中右对齐(ishljustl^ed),如果输出的值宽度大于4个字符,则该值将输出域宽扩大到能放下这个值为止。调用setiosflag(ios::left)可以指定输出的值为左对齐(1eft justified)。
上述输出中的其余格式表示变量amount打印成带小数点的定点值(用setiosflags(ios::fixed | ios::showpoint)指定),在输出域的21个字符位中右对齐(用setw(21)指定),小数点后面为两位(用setprecision(2)指定)。我们将在第11章介绍C++强大的输入/输出格式功能。
注意计算1.o+rate作为pow函数的参数,包含在for语句体中。事实上,这个计算产生的结果在每次循环时相同,因此是重复计算(是一种浪费)。
性能提示2.5
避免把不改变数值的表达式放在循环中。但即使把不改变数值的表达式放在循环中,如今的许多复杂优化编译器也全自动地把这种表达式放到循环之外,产生优化机器语言代码。
性能提示2.6
许多编译器中有优化特性,可以改进所写的代码,但最好一开始就编写优化的代码。
为了增加趣味性,本章练习中提供了一个peter Minuit问题,演示了复利计算的精彩之处。