Последнее предложение в операторе C switch (возможно, с использованием goto) - PullRequest
1 голос
/ 04 августа 2011

Я мог бы использовать что-то вроде предложения finally Java в переключателе C. В большинстве моих дел есть общий набор функций, которые я хотел бы поместить в одно дело. Я думал о реализации этого с помощью операторов goto, хорошо зная возможность обфускации кода gotos, помещая общий регистр внизу оператора switch все еще кажется «более чистым» способом сделать это, чем разделение общей функциональности на отдельные функции.

Во всяком случае, я пытался сделать что-то вроде этого:

switch( x ) {
case 0:
    printf("Case 0\n");
    goto case 2;
    break;
case 1:
    printf("Case 1\n");
    goto case 2;
    break;
case 2:
    printf("Case 2\n");
    break;
default:
    // do nothing
    break;
}

Однако, при использовании gcc, эта ошибка завершается ошибкой

error: expected identifier or ‘*’ before ‘case’

Есть предложения, как это сделать? Или, возможно, лучший подход?

Ответы [ 5 ]

4 голосов
/ 04 августа 2011

«Лучшая практика» - это, конечно, делегировать общий код функции.Но в некоторых ситуациях, когда это слишком сложное или просто невозможное / нежелательное, вы можете сделать следующее:

switch( x ) 
{
case 0:
    printf("Case 0\n");
    goto shared_material;

case 1:
    printf("Case 1\n");
    goto shared_material; // Unnecessary, but keep it for clarity.

case 2:
shared_material:
    printf("Case 2\n");
    break;

default:
    // Write a meaningful error message somewhere
    return -1;
}

Я не нахожу это слишком нечитаемым, и у меня нет проблем с этим при условии, что весь оператор помещается на одном экране (в противном случае он квалифицируется как код спагетти ).Однако вам, возможно, придется защищать его в обзорах кода, что является одной из основных причин, по которой я бы отказался от таких конструкций и переосмыслил код.

2 голосов
/ 04 августа 2011

Почему бы не поставить общий код после переключателя?

Я чувствую, что должен обновить этот ответ, перефразируя принятый ответ одним, который, по моему мнению, имеет лучший дизайн:

switch( x )
{
    case 0:
        printf("Case 0\n");
        break;

    case 1:
        printf("Case 1\n");
        break;

    case 2:
        break;

    default:
        return -1; 
}

printf("Common code for cases 0, 1 and 2\n");

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

1 голос
/ 04 августа 2011

следующих работ:

switch( x ) {
case 0:
    printf("Case 0\n");
    if(0)
case 1:{
    printf("Case 1\n");
    }
case 2:
    printf("Case 2\n");
    break;
default:
    // do nothing
    break;
}
1 голос
/ 04 августа 2011

Я бы предпочел пойти на такой подход:

void sharedFunction() {
    printf("Case 2\n");
}

switch( x ) {
case 0:
    printf("Case 0\n");
    sharedFunction();
    break;
case 1:
    printf("Case 1\n");
    sharedFunction();
    break;
case 2:
    sharedFunction();
    break;
default:
    // do nothing
    break;
}
1 голос
/ 04 августа 2011

Вы можете использовать флаг do2, установить его при необходимости и проверить его после переключателя.

если он сложнее со многими иерархическими зависимостями, тогда создайте конечный автомат с переходами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...