我已经用 C++ 编程几个月了,当我浏览论坛时,我注意到了一种趋势。似乎这些goto
陈述通常被认为是完全错误的使用,或者只应在非常特定的情况下使用。是什么goto
使它们从根本上错误的陈述?
问问题
517 次
2 回答
7
最大的原因是它使代码难以遵循。goto
并不是隐含的坏;用它编写难以理解的代码很容易。
例如,您更愿意阅读哪个?这个:
int factorial(int n) {
int result;
if(n==0 || n==1)
result = 1;
else
result = n*factorial(n-1);
return result;
}
或这个:
int factorial(int n) {
int result;
if(n > 1)
goto big;
result = 1;
goto end;
big:
result = n*factorial(n-1);
end:
return result;
}
这两种实现对机器来说是一样的,但第一种对我们的肉眼来说要清楚得多。不过,有时goto
会更清楚。例如,从 C(或 C++ 没有例外)考虑这个:
void process_big_file(FILE* foo) {
if(possible_failure_1(foo))
goto cleanup;
// Do some work
if(possible_failure_2(foo))
goto cleanup;
// Do some more work
cleanup:
fclose(foo);
}
在这里,使用goto
是有意义的,因为它可以让您将所有清理代码放在一个地方,并且goto
s 实际上创建了一个逻辑执行流。特别是,在阅读代码时,很明显您总是 (a) 到达清理代码,并且 (b) 总是到达相同的清理代码,这在这里很重要。在没有例外的情况下,我实际上认为goto
在尝试组织(例如)清理代码时这是正确的事情。
于 2013-04-28T18:28:35.793 回答
0
主要原因是这goto
使得对代码的推理非常困难,如果不是不可能的话。(注意,同样的事情也适用于“隐藏”的 goto,比如使用 abreak
从循环中间退出。)一般来说,如果您希望能够推断代码的正确性,您希望在每个块中输入顶部,并将其留在底部。如果无法推断代码的正确性,您就无法确定它是否正确。
于 2013-04-28T19:03:00.113 回答