我知道这是故意写得很糟糕的考试,但我希望你意识到它有多糟糕,为什么它不应该这样做.解构它可能有助于澄清它实际上在做什么.
首先,它有太多的副作用,以及太多与循环控制无关的动作.将for循环转换为while会有所帮助,所以如下:
for (++a[i]; !i, p = a[i]; s += a[i++]) {
...
}
变成这样:
++a[i];
while (!i, p = a[i]) {
...
s += a[i++];
}
,
操作符执行两个操作,但只返回第二个操作的结果.如果您希望第一个操作的副作用影响第二个操作,它可能是有用的,但!i
没有副作用,所以可以丢弃.循环现在是:
++a[i];
while (p = a[i]) {
...
s += a[i++];
}
测试表达式是一个任务,乍一看可能会令人困惑,所以不是一个好主意.条件表达式不应该出现在条件表达式中.它可以被移出,并替换为分配的变量p
,但是p
在两个地方被更新,一个是在循环之前,另一个是在循环结束之前.
++a[i];
p = a[i]; // Update p here first.
while (p) {
...
s += a[i++];
p = a[i]; // Update p before looping again.
}
这应该会让循环清晰.在里面,p
是在=
符号两侧的表达式中,虽然这是允许的,它意味着一个变量用于两个东西,当发生这种情况时,你需要转换你的 idea —如果你错过了它,你会认为变量的错误含义.每次意义改变时添加一个新变量:
short a[4] = {66, 066, 0x66};
int i = 0, s = 0, p = 15;
++a[i];
p = a[i];
while (p) {
int m = a[i] >> 2 | p;
a[i] &= m;
s += a[i++];
p = a[i];
}
应该很清楚,p
可以在任何地方被a[i]
取代,但我会保持原样.这应该清楚地说明代码现在做什么,以及为什么.如果需要,可以将while循环转换回for循环:
for (p = a[i];p;p = a[i]) {
它看起来并不太有用,但这就是它最终的用途,所以我会把它作为while循环.