首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C:嵌套Ifs或Gotos

C:嵌套Ifs或Gotos
EN

Stack Overflow用户
提问于 2010-11-10 20:39:36
回答 11查看 5.2K关注 0票数 9

管理C程序资源的最佳方法是什么?是使用嵌套的if结构还是使用goto语句?

我知道有很多关于goto语句的禁忌。不过,我认为本地资源的清理是有道理的。我提供了两个样品。一个比较嵌套的if结构,另一个使用goto语句。我个人认为goto语句可以使代码更容易阅读。对于那些可能认为嵌套if提示结构更好的人来说,想象一下如果数据类型不是char*,比如句柄。我觉得嵌套的if结构将失去对一系列CreateFile函数或任何其他需要大量参数的函数的控制。

这个文章演示了本地goto语句为C代码创建RAII。代码很整洁,易于遵循。假设这是一系列嵌套的if语句。

我理解goto在许多其他语言中是禁忌的,因为它们存在其他控制机制,如try/等,但是在C语言中似乎是合适的。

代码语言:javascript
复制
#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;
}

我还想引用Linux关于Linux语句的话。

有时结构是不好的,并进入了道路,而使用一个"goto“就更清楚了。 例如,有不嵌套的条件是很常见的。 在这种情况下,您有两种可能性

  • 使用goto,并且要快乐,因为它不强制嵌套 这使得代码更具可读性,因为代码只是做算法应该做的事情。
  • 复制代码,并以嵌套形式重写代码,以便您可以 使用结构化跳转。 这通常会使代码更难读、更难维护、更大。

Pascal语言是后一个问题的一个主要例子。因为它没有“中断”语句,所以循环在(传统的) Pascal中常常看起来像完全的狗屎,因为你必须添加完全任意的逻辑才能说“我现在就完了”。

goto是否可用于资源管理?我应该使用嵌套的if语句还是有更好的方法?

更新: C语言中的Gotos示例

EN

回答 11

Stack Overflow用户

回答已采纳

发布于 2010-11-10 20:51:15

使用goto进行清理有一个优点,即它不太容易出错。必须释放在每个返回点上分配的每一个资源,可能会导致某一天在进行维护工作时缺少一些清理。

尽管如此,我将引用Knuth的“带有goto语句的结构化编程”:

我主张在某些情况下取消go to's,并在其他情况下引入它们。

Knuth在同一篇论文中引用了Dijkstra的话:

“请不要落入这样的陷阱,以为我对陈述非常固执。我有一种不舒服的感觉,认为别人在用它来做宗教,就好像编程的概念问题可以通过一个简单的编码规则来解决似的!”29。

票数 10
EN

Stack Overflow用户

发布于 2010-11-10 20:51:44

如果通过使用goto可以避免编写复杂的代码,那么就使用goto

您的示例也可以这样编写(没有goto):

代码语言:javascript
复制
void anotherExample()
{
    char *string1, *string2, *string3, *string4, *string5;
    string1 = string2 = string3 = string4 = string5 = 0;
    if ((string1 = (char*) calloc(STRING_MAX, sizeof(char)))
     && (string2 = (char*) calloc(STRING_MAX, sizeof(char)))
     && (string3 = (char*) calloc(STRING_MAX, sizeof(char)))
     && (string4 = (char*) calloc(STRING_MAX, sizeof(char)))
     && (string5 = (char*) calloc(STRING_MAX, sizeof(char))))
    {
       //important code here
    }

  free(string1);
  free(string2);
  free(string3);
  free(string4);
  free(string5);
}
票数 11
EN

Stack Overflow用户

发布于 2010-11-10 21:14:42

毫无疑问,Dijkstra是编程界的一位令人敬畏的人物。他的后藤认为有害论文被夸大了。是的,GoTo可能被不加区分地使用,而且可能有害,但许多人认为完全禁止GoTo是没有道理的。Knuth给Dijkstra提供了一个非常合理的反驳:用GO TOs进行结构化编程

阅读Knuth的文章,您会发现您的GoTo模式是GoTo的一个很好的用途。

顺便说一句,Dijkstra对于许多其他的事情也很适用。不如:

  • 面向对象的编程是一个非常糟糕的想法,它只能起源于加利福尼亚。

迪克斯特拉是一位伟大的数学家,为计算机科学做出了巨大贡献。然而,我不认为他必须处理,或感兴趣的,日复一日的东西,我们的节目99.99 %。

只在合理和结构上使用GoTo。很少用。但一定要用它们。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4148838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档