Re: [问题]请教一下for与while为什么答案不一样?

楼主: poyenc (发箍)   2020-09-16 22:35:35
安安, 其实这题不需要真的执行啦! 只要善用简单的静态分析 (static
analysis) 技巧就可以知道问题在哪边. 首先是 for 循环的基本定义, 我们可
以用判断程式码品质时常用的方法: 资料视觉化 (data visualization) 来为
程式码片段做着色. for 循环里的程式码依照责任可以分成四个区块:
for ( (1) ; (2) ; (3) ) {
(4)
}
虽然通常每个区块做的事情都不同, 但求值顺序却是固定的, 如果我们想知道
循环的商业逻辑, 我们会直接看 (4) , 想知道问题的范围/大小就看 (2) , 依
此类推. while 循环也有这四个区块存在, 只是写得比较分散一点:
(1)
while ( (2) ) {
(4)
(3)
}
从上面可以看到, while 循环的 (4) 和 (3) 同样都写在循环的本体内, 在阅
读上和 for 相比多了区分两区块的步骤, 而且 (1) 容易和前面的程式码混在
一起, 可读性较差. 因为两种循环是可以互转的, 在发现有这个问题时, 就可
以尝试将循环改写, 改写前先将程式码着色 (从 for 循环出发):
int i=0,a;
for(a=0;i<n;a++) {
if(a%3==2 && a%5==3 && a%7==2)
i++;
}
如果转成 while 循环的话会变成这个样子:
int i=0,a=0;
while (i<n) {
if(a%3==2 && a%5==3 && a%7==2)
i++;
a++;
}
有没有发现这个 while 循环和你写的不太一样? 这个就是问题所在: 它们的结
构是不一样的. 程式码结构不同, 导致了求值顺序甚至是语意的改变, 所以你
跑出来的结果才会有差. 为了验证这件事情, 我们可以用简易的方法来比较程
式码结构: 将已经着色的程式码区块依照求值顺序排成有多种颜色的线段, 然
后比较两线段的颜色差异. 假设循环迭代 3 次, 你的 for 循环和 while 循环
画成线段后会长成下面的样子:
(for-loop)
(while-loop)
————————————————————————→
time
如上图所示, 排出来的线段颜色相同, 才表示这两份程式码做的事情是等价的;
你的例子因为 a++ 和 if 语句 顺序对调的缘故, 已经产生出不同的程式.
作者: Lipraxde (Lipraxde)   2020-09-16 23:10:00
其实就原 po 不熟悉 for 语法而已...
作者: kobe8112 (小B)   2020-09-16 23:45:00
这一篇文章值 392 Ptt币 你赢了XDDD
作者: james732 (好人超)   2020-09-17 01:00:00
也太精美了 XD
作者: ckvir (ckvir)   2020-09-17 01:21:00
我觉得不需要把简单问题复杂化 你这样写更难看的懂
作者: kaneson (Lance)   2020-09-17 06:57:00
我是觉得(3),(4)反过来就讲完了,不过我喜欢楼主的(1)~(4)的说明方式
作者: derekjj (忘记帐号的男子)   2020-09-17 09:42:00
这个要给推,太神了
作者: v86861062 (数字人:3)   2020-09-17 10:31:00
赞哦
作者: jack82822005 (小郭郭)   2020-09-17 10:35:00
这篇文章赚喔XD
作者: GankTw (GankTw)   2020-09-17 12:21:00
推,分析的真好
作者: MOONRAKER (㊣牛鹤鳗毛人)   2020-09-17 12:42:00
作者: Kashir (Kashir)   2020-09-17 15:52:00
谢谢版大的精准分析!受益良多
作者: VSei (Chaos)   2020-09-17 17:13:00
分析透彻易懂,大推
作者: ggBird (ggBird)   2020-09-17 21:35:00
作者: FY4   2020-09-18 00:12:00
作者: annheilong (方格子)   2020-09-18 10:29:00
谢谢大大教我如何赚 P 币XDDDD
作者: michael0728n (蒜˙远古)   2020-09-18 14:17:00
这招酷喔推推
作者: VictorTom (鬼翼&娃娃鱼)   2020-09-20 17:24:00
推精美:)
作者: eopXD (eopXD)   2020-09-22 17:24:00
推推
作者: stock999 (史托克柰褦錼)   2020-09-27 14:18:00
哪一种比较好呢??
作者: TuChinJui (Jerry)   2020-10-01 11:29:00
太强了,P币大师4ni?

Links booklink

Contact Us: admin [ a t ] ucptt.com