kh9*_*h99 15 c optimization loops switch-statement
我找到了一些具有这种结构的C代码:
switch (n) {
do {
case 1:
// do some things
if (some condition)
goto go_on;
case 2:
// do some things
if (some condition)
goto go_on;
case 3:
// do some things
if (some condition)
goto go_on;
} while (1);
do {
case 4:
// do some things
if (some condition)
goto go_on;
case 5:
// do some things
if (some condition)
goto go_on;
} while (1);
}
go_on:
Run Code Online (Sandbox Code Playgroud)
我在C中编程多年(多年前)并且会认为这将是语法错误.我认为它与优化循环有关,但我想知道是否有人可以解释它的作用.while(1)到达时会发生什么,它是否有效地返回到交换机?特别是为什么有两个人在那里做什么呢?
顺便说一句,我不希望开始使用的讨论goto,或者如果这是糟糕的设计.我没有写这个,我假设作者这样做了,因为它使循环运行尽可能快.
可以更好地显示程序流的等效代码.
类似于Duff的设备,允许在某个中间位置进入循环.@ tangrs
将军对这些日子不以为然1)编译器通常在优化方面做得更好2)正如OP发现的那样,很容易模糊代码的含义.谨慎使用.
在OP的代码中,在任一while条件之后,程序流程都不会返回到switch语句.在switch和case只影响初步进入while循环.
if (n == '1') goto case1;
if (n == '2') goto case2;
...
if (n == '5') goto case5;
goto go_on;
do {
case1:
// do some things
if (some condition) goto go_on;
case2:
// do some things
if (some condition) goto go_on;
case3:
// do some things
if (some condition) goto go_on;
} while (1);
do {
case4:
// do some things
if (some condition) goto go_on;
case5:
// do some things
if (some condition) goto go_on;
} while (1);
go_on:
Run Code Online (Sandbox Code Playgroud)
[编辑]
有2个while循环可以容纳原始编码器的流程,以跳入中间点,成为2个循环中的1个.
候选人重写如下.有权访问整体代码,当然可以获得更清晰的解决方案.
int n2 = n; // Only evaluate n once as in the switch statement.
if (n2 >= 1) {
if (n2 <= 3) {
while (1) {
if (n2 <= 1) {
// do some things
if (some condition) { break; }
}
if (n2 <= 2) {
// do some things
if (some condition) { break; }
}
// do some things
if (some condition) { break; }
n2 = 1;
}
else if (n2 <= 5) {
while (1) {
if (n2 <= 4) {
// do some things
if (some condition) { break; }
}
// do some things
if (some condition) { break; }
n2 = 4;
}
}
}
Run Code Online (Sandbox Code Playgroud)
让我为你重写这段代码,也许这会让它变得更加明显.以下代码或多或少等同于您发布的代码:
if (n == 1) goto ONE;
if (n == 2) goto TWO;
if (n == 3) goto THREE;
if (n == 4) goto FOUR;
if (n == 5) goto FIVE;
goto SKIP_ALL;
while (true) {
ONE:
// do some things
if (some condition) goto go_on;
TWO:
// do some things
if (some condition) goto go_on;
THREE:
// do some things
if (some condition) goto go_on;
}
while (true) {
FOUR:
// do some things
if (some condition) goto go_on;
FIVE:
// do some things
if (some condition) goto go_on;
}
SKIP_ALL:
go_on:
Run Code Online (Sandbox Code Playgroud)
环路在交换机内,它们不会导致交换机更频繁地发生.该开关基本上决定程序流程跳转到哪个循环,以及该循环中的哪个指令开始.一旦它跳到那里,循环继续正常.另请注意,开关通常比所有这些if语句更快.
不,goto一般来说都不错.A switch只是一个goto而且开关也不错.实际上,在CPU或VM中执行的函数/方法中的几乎每个代码分支都是简单的goto(有时是有条件的,有时不是).只是goto是最原始的,低级别的分支方式,并且告诉读者很少有意图.每当有一个更高级别,一个使你的意图更明显,最好使用那个.使用goto只是糟糕的设计,如果你可以轻松地编写相同类型的代码而不使用goto,它也不会更糟.在一些(尽管非常罕见)的情况下,goto几乎是不可避免的,或者任何避免它的尝试都会产生丑陋,难以理解,非常复杂的代码或者导致非常差的性能.
"goto被认为有害"的文章来自一个时代,有些人正在使用goto来处理所有事情:if/else代码分支,for循环,switch,断开循环/开关,避免递归等等.如果你过度使用goto,如果你做跳转到另一个标签的标签,人们会失去概述.像这样的代码是不可读的,并且非常难以调试.这是编写汇编代码的方式,但这不应该是我们编写C代码的方式.