假设有这样一个问题:计算2 的10 次方.我们首先想到的可能是
#include
int main() {
// 第一个解决方案
cout << "2 raised to the power of 10: ";
cout << 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2;
cout << endl;
return 0;
}
这样确实能够解决问题,但是可能需要检查两到三遍以确保正好有10个常数2参与乘法.
接着我们被要求算出2的17次方和2的23次方.每次都要修改程序确实很麻烦,但更糟糕的是,这样做经常会出错.修改后的程序常常会多乘或少乘了一个2.最后我们又被要求生成2的从0到15次方的数值的表.使用文字常量需要与32行类似下面的格式
cout << "2 raised to the power of X\t";
cout << 2 * ... * 2;
这里X随每对语句递增1.
虽然这种蛮力型的方案也能解决问题,但是它总让人感到不快而且有些危机感.
在下例中用来取代这种蛮力型的方案包括两部分内容:使用有名字的对象来读写每步的计算;引入一个控制流结构以便在某个条件为真时可以重复执行一系列语句.
下面是一种技术先进的计算2 的10 次幂的程序:
#include
int main()
{
// int 类型的对象
int value = 2;
int pow = 10;
cout << value << " raised to the power of "
<< pow << ": \t";
int res = 1; // 保存结果
// 循环控制语句: 反复计算res
// 直至cnt 大于pow
for ( int cnt=1; cnt <= pow; ++cnt)
res = res * value;
cout << res << endl;
}
value,pow,res以及cnt是变量.它们允许对数值进行存储修改和查询.for循环使计算过程重复执行pow次.虽然这种层次的通用化能使程序更加灵活,但是这样的程序仍然是不可重用的.
我们必须进一步通用化:把计算指数值的那部分程序代码抽取出来,定义成一个独立的函数以使其他函数能够凋用它.例如:
int pow( int val, int exp )
{
for ( int res = 1; exp > u; --exp )
res = res * val;
return res;
}
现在每个需要计算指数值的程序,都可以使用pow()的实例,而不是重新实现它
我们可以用如下的代码来生成2的幂的表:
#include
extern int pow(int, int);
int main()
{
int val = 2;
int exp = 15;
cout << "The Powers of 2\n";
for ( int cnt=0; cnt <= exp; ++cnt )
cout << cnt << ": "
<< pow(val, cnt) << endl;
return 0;
}
实际上,这个pow()的实现既不够健壮也不够通用.例如,如果指数是负数该怎么办,如果是1 000 000 呢,对于负数指数,我们的程序总是返回1.对于一个非常大的指数,变量int res又小得不能够容纳这个结果.因此,对于一个大的指数将返回一个任意的不正确的值(在这种情况下,最好的解决方案是将返回值的类型修改为double类型)从通用的角度来说,我们的程序应该能够处理整数和浮点数类型的底数和指数,甚至其他的类型.正如你所看到的,为一个未知的用户组写一个健壮的通用函数,比实现一个特定的算法来解决眼前的问题要复杂得多.