练习

  1. 1)写出通过递推方式求200之内的完全平方数的程序;2)写出只使用加法的求完全平方数的程序;3)写出求1000之内的完全立方数的程序,请参考书中实例的写法和上面的两种写法,分别写出相应的求立方数的版本。


  2. 试验正文中乌龟旅行的实例,看看在你所用的C系统上得到什么样的结果。从数学教科书中找出有关调和级数的理论结论,并将它与我们的试验做一个比较。


  3. 写一个程序,计算并输出Fibonacci序列中一系列的相邻项之比。确定一个范围,观察输出的结果,能够得到什么结论(这个比的序列可能有极限吗?极限是什么)。查阅有关资料,了解有关的理论结果。


  4. 写函数计算 1! + 2! + ... + k!。用主函数试验函数对一系列k值计算出的结果。你写出的函数对110计算结果都正确吗?如果出现错误,弄清楚是什么原因。这个程序能对k = 30得到正确结果吗?(另外,你能只用一重循环完成函数的定义吗?)


  5. 写函数计算:,公式中有n层嵌套。利用这个函数打印 x = 1.02.0、…、20.0n = 10时的函数值表。


  6. 实现书中讨论的验证哥德巴赫猜想的程序,用不同的n 6n 的范围试验该程序。去掉程序中的打印输出语句,增加计时功能,对不同的n运行程序,考察程序的运行时间,画出一条曲线,说明运行时间与n的关系。


  7. 设法(从文献中)找到其他更有效的素数判断方法并实现对应函数。在一个数值比较大的整数区间试验书上给出的函数和你写的其他函数,利用它们打印出这一区间中的所有素数。你所试验的几种方法在工作效率上有明显差异吗?(为程序计时)
  8. 定义函数:void prt_factors(int),它对正整数实参输出其所有的因子。


  9. 定义函数:void prt_pfactors(int),它对正整数实际参数,输出其所有的素因子(多重因子重复输出);对于负参数,首先输出-1,然后输出所有因子。


  10. 已知 ,利用该公式编程序求 的近似值,看用这个和式的前多少项求出的近似值与3.14159165的误差小于 ,令程序输出三项数据:计算得到的和,由这个和求出的 的近似值,求得该和所用得项数。把 改为 并重新试验,用计时方式总结出误差减小与执行时间之间的关系。


  11. 修改书中计算sin值的函数,使之能输出计算中循环执行的次数。用不同的数值(一个比一个大)试验这一函数,观察出现的情况。你看到出现溢出的情况了吗?(为试验方便,你应该写一个适用的驱动程序)


  12. 已知x < 1),写函数 double asinh(double) 计算 的近似值。


  13. 考虑不用函数(例如isprime)直接写出对6200的偶数验证哥德巴赫猜想的程序(利用循环、条件、break语句等,不使用goto语句)。将这样写出的程序与用定义函数的方式写出的程序比较。例如考察两个函数的行数、字节数,其中各种控制结构的嵌套深度,控制结构使用的个数等。


  14. 辗转相减求最大公约数的递归定义是(其中):

    利用这个定义,用递归和循环方式各写出一个求最大公约数的函数。

  15. 对一些n值试验河内塔程序,给它们计时。据此估计你所用的计算机搬完64个金盘需要多长时间。如果僧侣们1秒钟搬金盘1次,搬完64个金盘需要多少时间?将这一时间与科学家对宇宙的估计寿命做个比较,据此评价僧侣们的说法。


  16. 一个三位的十进制整数,如果它的三个数位数字的立方和等于这个数的数值,那么它就被称为一个“水仙花数”。定义函数判断一个整数是水仙花数,并利用这个函数打印出所有的水仙花数。


  17. 对一个整数,如果其所有因子(包括因子1在内)之和正好等于这个数,那么就称它为“完全数”。因子之和小于自身的数称为“亏数”;因子之和大于自身的数称为“盈数”。写一个函数,当其参数是亏数时返回负值,是完全数时返回0,是盈数时返回正值。利用这个函数求出1000以内的所有完全数(实际上只有1628496)。为这个程序计时:从100开始每隔100做一次计算,写一个循环,输出各次计算花的时间。再从1000开始,每隔1000做一次计算直到10000为止,输出对程序执行计时的值。利用所定义的函数对一段区间的整数做一个分类,输出其中各个数所属的类。


  18. 写程序由标准输入得到一系列三个一组的数,把每组数作为三角形的三边长,计算三角形的面积。注意在程序里检查输入数据,对不能构成三角形的情况给出错误信息。仔细分析自己的程序,能否检查出所有不合理数据。用不同数据运行试验。


  19. 写一个程序,它读入一系列整数,最后输出其中最大的两个数。


  20. 写一个程序,它输出所读入的一系列整数的平均值。假定给它的第一个数并不是数据,而是用于说明数据的项数。


  21. 假设程序由输入得到的一系列正实数是一条折线在x等于012,…的对应值(数据的数目事先并未确定),请求出这一折线与x轴之间区域的面积。


  22. 能够组成直角三角形三个边的最小一组整数是345。写程序求出在一定范围里所有可以组成直角三角形三个边的整数组,输出三个一组的整数。设法避免重复的组。


  23. 改造本章正文中讨论的计算器程序:
    1. 增加计算一行后的处理,使出现在正确表达式之后的任意字符序列都不会影响下一表达式的计算(抛弃正确表达式之后的字符)。
    2. 修改程序,使之在数值、加号之间出现任意个空格时都能正确计算。
    3. 修改程序,使之不仅能处理加法,还能处理其他算术运算符(提示:记录运算符,用if或者switch判断、计算和输出)。

  24. 仿照本章中的单词统计程序,写一个统计C程序里标识符个数的程序。程序里可以利用标准库提供的字符分类函数:

    int isalpha(int c)

    c是字母的编码时,返回非0值;

    int isdigit(int c)

    c是数字的编码时,返回非0值。

    使用这两个函数时,应在程序文件前部写 #include <ctype.h>

  25. 定义下面的计算规则:遇到1就终止;如果遇到1之外的奇数,求出它乘31的值作为下一个数;如果遇到偶数,求出它除以2的值作为下一个数。问题是:对每个正整数,反复使用这套规则,最终是否都能得到1。也就是问,按照这个规则定义的递推序列是否对每个正整数都终止(这个著名问题至今也没有结论)。请按上面的规则定义一个函数,它返回对参数计算直到终止所经历的计算步数。对一系列参数试验这个函数。注意:序列中的数可能变得很大,请设法检查溢出,遇到溢出时打印信息。


  26. 考察目前银行对各种期限的储蓄利率。写一个函数,它能够计算出对给定的时间(例如8年,10.5年等,以半年为基本单位)如何分段将能够得到最大的收益。


  27. 为本章正文中的某些程序实例写出好用的测试驱动程序。为你所做的某些练习写出好用的测试驱动程序,并借助于它们仔细检查你所定义的函数。