C: вложенные ifs или Gotos

Как лучше всего управлять ресурсами для программы C . Должен ли я использовать вложенную структуру if или мне следует использовать операторы goto?

Я знаю, что существует множество табу относительно операторов goto . Однако я считаю это оправданным для очистки местных ресурсов. Я предоставил два образца. Один сравнивает вложенную структуру if, а другой использует операторы goto. Я лично считаю, что операторы goto облегчают чтение кода. Для тех, кто может утверждать, что вложено, если подсказывает лучшую структуру, представьте, если бы тип данных был чем-то другим, кроме char *, например дескриптором Windows. Мне кажется, что структура вложенного if выйдет из-под контроля с серией функций CreateFile или любой другой функцией, которая принимает большое количество параметров.

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и как ручка Windows. Мне кажется, что структура вложенного if выйдет из-под контроля с серией функций CreateFile или любой другой функцией, которая принимает большое количество параметров.

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и как ручка Windows. Мне кажется, что структура вложенного if выйдет из-под контроля с серией функций CreateFile или любой другой функцией, которая принимает большое количество параметров.

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и Мне кажется, что структура вложенного if выйдет из-под контроля с серией функций CreateFile или любой другой функцией, которая принимает большое количество параметров.

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и Мне кажется, что структура вложенного if выйдет из-под контроля с серией функций CreateFile или любой другой функцией, которая принимает большое количество параметров.

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и

Эта статья демонстрирует, что локальные операторы goto создают RAII для кода C. Код аккуратный, за ним легко следить. Представьте, что это серия вложенных операторов if .

Я понимаю, что goto является табу на многих других языках, потому что существуют другие механизмы управления, такие как try / catch и т. Д., Однако в C это кажется подходящим.

#include 

#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;
}

Я также хотел бы процитировать Линуса Торвальдса в операторах goto внутри ядра ядра Linux.

И иногда структура плохая , и встает на пути, и используя "goto" просто намного яснее.

Например, довольно часто иметь условные выражения, КОТОРЫЕ НЕ ВСПОМОГАТЕЛЬНЫ.

В этом случае у вас есть два возможности

  • используйте goto и будьте счастливы, так как он не требует вложенности

    Это делает код более читаемым, поскольку код просто делает то, что алгоритм говорит, что он должен работать.

  • продублируйте код и перепишите его во вложенной форме, чтобы вы могли
    используйте структурированные переходы.

    Это часто делает код намного МЕНЬШЕ читаемый, сложный в обслуживании и больше.

Язык Паскаль является ярким примером последней проблемы. Потому что это не имеет "перерыва", циклы в (традиционном) Паскале заканчиваются часто выглядит полным дерьмом, потому что вы должны добавить совершенно произвольный логика, чтобы сказать: «Я закончил».

Подходит ли goto для управления ресурсами? Следует ли мне использовать вложенные операторы if или есть лучший способ?

Обновление: Примеры хороших Gotos в C

9
задан Community 23 May 2017 в 11:45
поделиться