回避复杂—《狂人C》习题解答(第3章题7)

题目: 5个小孩围成一圈分糖果。最初第一个小孩有66块糖果,第二个有35块,第三个有24块,第四个有7块,第五个有34块。第一个小孩把自己的一半分给第二个小孩,然后第二个小孩把自己现有的一半分给第三个小孩……最后第五个小孩把自己现有的一半分给第一个小孩。编程模拟这个过程,输出最后每个小孩的糖果数。(每个孩子的糖果数始终为整数) 由于在计算过程中需要记住每个小孩的糖果数目,所以使用变量存储。这些变量都有初值,因此可在定义这些变量时直接给这些变量赋初值。 #include #include #define PORTION 2 int main( void ) { int num_1 = 66 , num_2 = 35 , num_3 = 24 , num_4 = 7 , num_5 = 34 ; system("PAUSE"); return 0; } 然后逐步模拟分配的过程。首先是“第一个小孩把自己的一半分给第二个小孩” #include #include #define PORTION 2 int main( void ) { int num_1 = 66 , num_2 = 35 , num_3 = 24 , num_4 = 7 , num_5 = 34 ; //第一个小孩把自己的一半分给第二个小孩 num_2 += num_1 / PORTION ; num_1 /= PORTION ; system("PAUSE"); return 0; } 如果写出这样的代码,逻辑上是有问题的。因为第二条语句本应该写成“num_1 -= num_1 / PORTION ;”(num_1 - num_1 / 2 => num_1 ),尽管其结果与“num_1 /= PORTION;”( num_1 / 2 => num_1 )相同,但“num_1 /= PORTION”实际上是编程者代替程序对“num_1 -= num_1 / PORTION”(num_1 - num_1 / 2 => num_1 )进行了进一步的演算和简化得到的。一般情况下,编程者应该把计算交给程序而不应该越俎代庖。如果题目改成了“第一个小孩把自己的三分之一分给第二个小孩”就会发现“num_1 -= num_1 / PORTION”(num_1 - num_1 / 3 => num_1 )依然正确,而“num_1 /= PORTION”( num_1 / 3 => num_1 )则是错误的。 但是 num_2 += num_1 / PORTION ; num_1 -= num_1 / PORTION ; 对次序有严格的要求,必须先执行第一句,再执行第二句。这就要求编程者在编程时付出更多的思考和谨慎,这也意味着出错的可能性更大些。如果一个写法比另一个写法更不容易出错,在两者都正确的前提下,显然第一种写法更好。学习编程只学习把代码写正确是远远不够的,更高的境界是学习写简单轻松的代码,不容易出错的代码。一定要学会回避复杂。把代码写得复杂以至于没有明显的错误固然不太容易,但编程更高的境界是,把代码写得非常简单以至于明显没有错误。 在本题目中,这种简单轻松和不易出错体应现在:摆脱或减少对次序的强依赖,避免复杂的表达式。这可以通过增加一个临时变量实现。 { int num_to_send ; num_to_send = num_1 / PORTION ; num_1 -= num_to_send ; num_2 += num_to_send ; } 这个写法后面两条语句不存在对次序的依赖,避免了“num_2 += num_1 / PORTION”这样的复杂的表达式,更直接、更简洁,因而是更好的写法。 临时变量,有时也叫中间变量,通常用于存储计算过程中的中间计算结果。恰当地使用中间变量可以达到简化表达式,提高可读性的效果。 下面是该问题解答的完整代码。 #include #include #define PORTION 2 int main( void ) { int num_1 = 66 , num_2 = 35 , num_3 = 24 , num_4 = 7 , num_5 = 34 ; //第一个小孩把自己的一半分给第二个小孩 { int num_to_send ; num_to_send = num_1 / PORTION ; num_1 -= num_to_send ; num_2 += num_to_send ; } //第二个小孩把自己现有的一半分给第三个小孩 { int num_to_send ; num_to_send = num_2 / PORTION ; num_2 -= num_to_send ; num_3 += num_to_send ; } //第三个小孩把自己现有的一半分给第四个小孩 { int num_to_send ; num_to_send = num_3 / PORTION ; num_3 -= num_to_send ; num_4 += num_to_send ; } //第四个小孩把自己现有的一半分给第五个小孩 { int num_to_send ; num_to_send = num_4 / PORTION ; num_4 -= num_to_send ; num_5 += num_to_send ; } //第五个小孩把自己现有的一半分给第一个小孩 { int num_to_send ; num_to_send = num_5 / PORTION ; num_5 -= num_to_send ; num_1 += num_to_send ; } printf("最后每个小孩的糖果数分别为" "%d,%d,%d,%d,%d\n" , num_1,num_2,num_3,num_4,num_5 ) ; system("PAUSE"); return 0; } 推荐阅读: IT编程研究

猜你喜欢

转载自muxang.iteye.com/blog/1205419
今日推荐