题目:计算 ,直到最后一项小于 。
注意题目要求:计算到最后一项小于 。也就是这一项是要参与到计算中的,计算完这一项才能触发循环停止条件。
这种先运算后判断的情况很对do-while循环的胃口。
do就是做嘛,while就是判断嘛,所以这种循环结构就是为“先干后看”而生的。
do-while循环的格式为“do{循环体}while(条件);”,注意while循环条件后面有一个分号。
很据所给式子可得出规律:
①奇数项符号为正,偶数项符号为负;
②第n项的分母为2n-1。
#include<stdio.h>
int main(){int n=1;double m, sum=0;do {m = 1.0/(2*n-1);if(n%2 != 0) sum += m;else sum -= m;n++;} while(m>=1e-6);printf("%f\n", sum);return 0;
}
当然了,用for或while循环也是完全可以的,只需要在循环体结束时加入一条循环终止判断语句:if()break;
以for循环为例:
#include<stdio.h>
int main() {double sum = 0;for(int n = 1; ; n++) {double m = 1.0 / (2*n-1);if(n % 2 != 0) sum += m;else sum -= m;if(m < 1e-6) break; //循环终止判断}printf("%f\n", sum);return 0;
}
可见,使用do-while的好处就是不用单独再加一条循环终止判断语句。
对于本题,最后再给出我家孩子的代码,权做反面案例。
#include <cstdio>
using namespace std;
int main () {double cnt=0,h=3;int i=1;while(h>1e-6){h=1.0/i;if(h<1e-6) break;cnt+=h;i+=2;h=1.0/i;cnt-=h;i+=2;}printf("%f",cnt);
}
这段代码的问题如下:
①未理解题目要求“直到最后一项小于 ”的含义,就像前面说的,它的意思很明确,计算的式子的最后一项要小于 ,也就是第一次小于 时参与计算,再后面的就不计算了。所以必须要先运算后判断,而我家娃娃的代码恰恰忽略了这点,掉入本题最大的陷阱。
②为了使程序刚开始能顺利执行while循环,增加了一个与本题无关的变量h。当然这是个小问题。
③不是以单项为单位总结每一项式子的规律,建立起每项的值与第n项的关系,而是以两项为一组,符号一正一负,前后项分母差2。这样做不但会造成代码重复,更重要的是,这种写法容易出错。因为最后一项可能是这一组中的前一项,也可能是后一项,需要在每一项后都加入判断,这个判断非常容易遗漏。
④错误理解C语言中科学记数法的表示,认为10e-6才是 。
如果用孩子思路,正确的代码如下:
#include <cstdio>
using namespace std;
int main () {double cnt=0,h;int i=1;while(1){h=1.0/i;cnt+=h;if(h<1e-6) break;i+=2;h=1.0/i;cnt-=h;if(h<1e-6) break;i+=2;}printf("%f",cnt);
}