C:嵌套If语句或GOTOS [英] C: Nested Ifs or Gotos

查看:127
本文介绍了C:嵌套If语句或GOTOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是管理资源的 C 程序的最佳途径。我应该使用嵌套,如果结构或我应该使用goto语句?

What is the best way to manage resources for a C program. Should I use a nested if structure or should I use goto statements?

我知道有一个关于转到语句很多的禁忌的。但是,我认为这是对当地资源的清理有道理的。我已经提供了两个样本。一个比较嵌套if结构,另一个则使用goto语句。我个人觉得在goto语句使code更容易阅读。对于那些谁可能会认为,在嵌套if 提示符更好的结构,想象一下,如果数据类型是其他东西比一个char *,就像一个Windows句柄​​。我觉得嵌套if 的结构将变得不可收拾了一系列的的CreateFile 的功能或任何其他函数,它的参数,数量大。

I am aware there is a lot of taboo about goto statements. However, I think it is justified for local resource clean up. I have supplied two samples. One compares a nested if structure and another uses goto statements. I personally find the goto statements make the code easier to read. For those who might argue that the nested if prompt better structure, imagine if the datatype was something other than a char*, like a Windows handle. I feel that the nested if structure would get out of hand with a series of CreateFile functions or any other function that takes large quantities of parameters.

文章表明,当地的goto语句建立了C code RAII 。在code是一个整齐易于遵循。试想一下,作为一个系列的嵌套if 语句。

This article demonstrates that local goto statements create RAII for C code. The code is neat an easy to follow. Imagine that as a series of nested if statements.

据我所知,转到在许多其他语言忌讳,因为他们的存在,像try / catch语句等,但在C似乎是适当的其他控制机制。

I understand that goto is taboo in many other languages because their exists other control mechanisms like try/catch etc, however, in C it seems appropriate.

#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公司在Linux 内核中的转到语句

有时结构的的,并
  进入的方式,并使用转到
  只是更清晰。

And sometimes structure is bad, and gets into the way, and using a "goto" is just much clearer.

例如,它是很常见的
  有不NEST条件语句。

For example, it is quite common to have conditionals THAT DO NOT NEST.

在这种情况下,你有两个
  可能性

In which case you have two possibilities


      
  • 使用goto语句,快乐的,因为它不强制嵌套

  • use goto, and be happy, since it doesn't enforce nesting

这使得code的更多的可读性,
  自code少了点什么
  算法说,它应该做的。

This makes the code more readable, since the code just does what the algorithm says it should do.

复制code和重写它的嵌套形式,这样就可以结果
  使用结构化的跳跃。

duplicate the code, and rewrite it in a nesting form so that you can
use the structured jumps.

这往往使得code少得多
  可读性强,难以维护,
  大。

This often makes the code much LESS readable, harder to maintain, and bigger.

Pascal语言是一个很好的例子
  后者的问题。因为它
  没有一个破发的声明,
  在(传统)帕斯卡循环结束
  经常看起来像狗屎总额,因为
  你必须添加任意完全
  逻辑地说:我现在做的。​​

The Pascal language is a prime example of the latter problem. Because it doesn't have a "break" statement, loops in (traditional) Pascal end up often looking like total shit, because you have to add totally arbitrary logic to say "I'm done now".

时的转到作为资源管理是否可以接受?我应该使用嵌套if 陈述或者有更好的办法?

Is goto acceptable for resource management? Should I use nested if statements or is there a better way?

更新:良好的goto的 例子在C

推荐答案

使用转到清理的优点是,它不太容易出错。其释放的每一个折返点分配的每个资源都可以导致有人做维护工作时,有一天丢失了一些清理工作。

Cleanup using goto has the advantage that it's less error-prone. Having to free each and every resource allocated on each and every return point can lead to someone someday missing some cleanup when doing maintenance work.

这是说,我还要举Knuth的结构化编程使用goto语句

That said, I'll quote Knuth's "Structured Programming with goto Statements":

我认为消除,在某些情况下的,而他们在别人的介绍。

I argue for the elimination of go to's in certain cases, and for their introduction in others.

和Knuth的在同一文件的Dijkstra的话:

and Knuth's quote of Dijkstra in that same paper:

请不要掉入相信,我非常专横有关[转到声明。我有其他人正在一个宗教出它的不舒服的感觉,的陷阱,如果编程的概念问题可能由单一的把戏来解决,通过编码规则的一种简单形式! [29]

"Please don't fall into the trap of believing that I am terribly dogmatical about [the go to statement]. I have the uncomfortable feeling that others are making a religion out of it, as if the conceptual problems of programming could be solved by a single trick, by a simple form of coding discipline!" [29].

这篇关于C:嵌套If语句或GOTOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆