Переход между случаями в операторах C switch

У меня есть следующий код для определения моих состояний FSM:

enum states
{
    START,              // Send request to remote IP or wait for a request (WAIT_CONN_REQ)
    WAIT_RESP,          // Chat request sent to remote IP. Waiting for a response from the target machine
    SEND_CONN_RESP,     // Chat request received from remote IP. ACCEPT or REJECT
    ACCEPTED            // Both parties agreed to exchange datagrams. Begin application data (MESSAGES) exchange
};
typedef enum states states;
states state;

Мой мыслительный процесс был следующим: моя программа чата будет иметь четыре вышеупомянутых состояния. Какой лучший способ сделать это аккуратно? Конечно, с помощью оператора switch. Так как я могу это сделать? Вот так: (код упрощен и заменен на printf функции"

int main(int argc, char *argv[])
{
    state = START;
    switch (state)
    {
        case START:
            printf("Simple Chat Client - START state\n");
            if (argv[1] != NULL)
            {
                SEND_CONN_REQ();
                } else {
                WAIT_CONN_REQ();
            }
            break;
        case WAIT_RESP:
            printf("WAIT_RESP STATE!");
            break;
        case SEND_CONN_RESP:
            printf("SEND_CONN_RESP state!");
            break;
        case ACCEPTED:
            printf("ACCEPTED state!");
            break;
    }
}

Но это не делает то, что я хочу. Я хочу, чтобы он перешел к другому случаю, когда условие выполнено. Вот так:

    if (argv[1] != NULL)
                    {
                        SEND_CONN_REQ();
                        goto case WAIT_RESP;          
                        } else {
                        WAIT_CONN_REQ();
                    }
                    break;
                case WAIT_RESP:
                    printf("WAIT_RESP STATE!");
                    break;

Моя логика говорит мне, что способ сделать это будет изменить state переменная, предполагая, что все switch будет выполнен снова с новой переменной. Но происходит то, что я должен использовать break и выйти switchили не используйте его и позвольте программе выполнить следующее case,

Поэтому я посмотрел на другие варианты, как do заявления и continue, Но везде я смотрю, используя case кажется, что путь с FSM.

Буду признателен за любую помощь о том, как сделать это правильно. Это switch Скажите даже лучший путь?

2 ответа

Решение

Обычный способ кодирования конечного автомата - использование цикла и переключателя:

state = START;
while (state != STOP)
{
    switch (state)
    {
        case START:
            printf("Simple Chat Client - START state\n");
            if (argv[1] != NULL)
            {
                SEND_CONN_REQ();
            } else {
                WAIT_CONN_REQ();
            }
            break;
        case WAIT_RESP:
            printf("WAIT_RESP STATE!");
            break;
        case SEND_CONN_RESP:
            printf("SEND_CONN_RESP state!");
            break;
        case ACCEPTED:
            printf("ACCEPTED state!");
            break;
    }
}

Каждое действие может при желании установить новое состояние, чтобы следующая итерация выполняла соответствующие действия. Не забудьте вывести переводы строк в конце printf() заявления, если вы хотите увидеть результат своевременно. Это может не иметь значения в Windows; это происходит на других платформах.

Если вы всегда захотите выполнить состояние прямо под тем местом, где вы находитесь, вы можете удалить break заявление. Я бы положил комментарий в это место, как /* fall through */ так что ясно, что оно намеренно отсутствует для людей, которые следуют за ним, а также для вашего забывчивого будущего. Мне лично не нравится этот метод.

Почему бы не изменить state переменная, а затем просто выполнить goto это прямо над оператором switch? Как это может быть:

switchStart:
    switch (state)
    {
        case START:
            printf("Simple Chat Client - START state\n");
            if (argv[1] != NULL)
            {
                SEND_CONN_REQ();
                state = STATE_HERE; // change your state
                goto switchStart; // jump to the top of the switch
                } else {
                WAIT_CONN_REQ();
            }
            break;
        case WAIT_RESP:
            printf("WAIT_RESP STATE!");
            break;
        case SEND_CONN_RESP:
            printf("SEND_CONN_RESP state!");
            break;
        case ACCEPTED:
            printf("ACCEPTED state!");
            break;
    }
Другие вопросы по тегам