管理资源的最佳方式是什么C程序。我应该使用嵌套的 if 结构还是应该使用 goto 语句?
我知道有很多taboo about goto声明。不过,我认为本地资源清理是合理的。我提供了两个样品。一种比较嵌套的 if 结构,另一种使用 goto 语句。我个人发现 goto 语句使代码更易于阅读。对于那些可能认为嵌套如果提示更好的结构,想象一下数据类型是否不是 char*,比如 Windows 句柄。我觉得嵌套如果结构会因一系列的失控创建文件 http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx函数或任何其他需要大量参数的函数。
This article http://vilimpoc.org/research/raii-in-c/演示本地 goto 语句为 C 代码创建 RAII。代码简洁且易于理解。想象一下,作为一系列嵌套如果声明。
我明白那个goto在许多其他语言中这是禁忌,因为它们存在其他控制机制,例如 try/catch 等,但是在 C 中似乎是合适的。
#include <stdlib.h>
#define STRING_MAX 10
void gotoExample()
{
char *string1, *string2, *string3, *string4, *string5;
if ( !(string1 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string1;
if ( !(string2 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string2;
if ( !(string3 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string3;
if ( !(string4 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string4;
if ( !(string5 = (char*) calloc(STRING_MAX, sizeof(char))) )
goto gotoExample_string5;
//important code goes here
gotoExample_string5:
free(string4);
gotoExample_string4:
free(string3);
gotoExample_string3:
free(string2);
gotoExample_string2:
free(string1);
gotoExample_string1:
}
void nestedIfExample()
{
char *string1, *string2, *string3, *string4, *string5;
if (string1 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string2 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string3 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string4 = (char*) calloc(STRING_MAX, sizeof(char)))
{
if (string5 = (char*) calloc(STRING_MAX, sizeof(char)))
{
//important code here
free(string5);
}
free(string4);
}
free(string3);
}
free(string2);
}
free(string1);
}
}
int main(int argc, char* argv[])
{
nestedIfExample();
gotoExample();
return 0;
}
我还想引用 Linus Torvalds 的话gotoLinux 内部的语句Kernel http://kerneltrap.org/node/553/2131.
有时结构是bad, 和
妨碍,并使用“goto”
更清楚了。
例如,这是很常见的
有不嵌套的条件。
在这种情况下你有两个
可能性
-
使用 goto,并且很高兴,因为它不强制嵌套
这使得代码more可读,
因为代码只是做了什么
算法说它应该做。
-
复制代码,并以嵌套形式重写,以便您可以
使用结构化跳转。
这通常会使代码变得更少
可读,难以维护,并且
大。
Pascal 语言就是一个典型的例子
的后一个问题。因为它
没有“break”声明,
(传统)Pascal 中的循环最终结束
通常看起来完全是一坨狗屎,因为
你必须添加完全任意的
逻辑上说“我现在完成了”。
Is goto资源管理可以接受吗?我应该使用嵌套如果声明或者有更好的方法吗?
Update: C 语言中良好 Goto 的示例 https://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c