c 中状态机的问题

Issues with state machine in c

我的状态机(函数 automate())遇到了一些问题。似乎枚举总是保持相同的值,而不是根据函数中的不同条件更改它。 我的输出总是 "DECREMENT_PARA_1" 谁能告诉我为什么变量 etat_courant 没有在每次迭代时将值保存在内存中?提前致谢 !这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>


//PARAMETRES
enum Etat {INIT, DECREMENT_PARA_1, INCREMENT_PARA_1, ETAT_INVARIANT_1, DECREMENT_PARA_2, ETAT_INVARIANT_2, INCREMENT_PARA_2, RADAR_SATURE};

//Prototypes
void automate(int tddv_estime, int tab_para_automate[][2], enum Etat *etat_courant, int* para_1_courant, int* para_2_courant);
void fct_test(int scenario[]);

int main()
{
    int scenario[15] = {21, 21, 20, 12, 12, 20, 22, 22, 22, 22, 22, 22, 22, 22, 500};
    fct_test(scenario);
    return 0;
}

/*-----------------------------------------------------------------------
Fonction fct_test
-------------------------------------------------------------------------*/
void fct_test(int scenario[])
{
    int increment = 1;
    int tddv_estime;
    int para_1_courant = 10;
    int para_2_courant = 4;
    int para_1_min = 5;
    int para_1_max = 10;

    int para_2_min = 1;
    int para_2_max = 4;

    int tab_para_automate[2][2] = {{0}};
    int tab_para_application[1][3] = {{0}};

    tab_para_automate[0][0] = para_1_min;
    tab_para_automate[0][1] = para_1_max;
    tab_para_automate[1][0] = para_2_min;
    tab_para_automate[1][1] = para_2_max;

    tab_para_application[0][0] = para_1_courant;
    tab_para_application[0][1] = para_2_courant;
    tab_para_application[0][2] = increment;

    int i;
    enum Etat etat_courant = INIT;

    for (i=0 ; i<15 ; i++)
   {
        tddv_estime = scenario[i];
        printf("%d\n",scenario[i]);
        automate(tddv_estime, tab_para_automate, &etat_courant, &para_1_courant, &para_2_courant);
   }
   //}
}

/*-----------------------------------------------------------------------
Fonction automate
-------------------------------------------------------------------------*/

void automate(int tddv_estime, int tab_para_automate[][2], enum Etat *etat_courant, int* para_1_courant, int* para_2_courant)
{
    int evenement;


    int tddv_worst = 20;

    if (tddv_estime < tddv_worst)
        evenement = 1; //Etat initial

    if (tddv_estime > tddv_worst)
        evenement = 2; //Decrement para1

    if (tddv_estime < tddv_worst &&  *para_1_courant<= tab_para_automate[0][1])
        evenement = 3; //Increment para1

    if (tddv_estime == tddv_worst)
        evenement = 4; //Etat Invariant 1

    if (tddv_estime > tddv_worst && *para_1_courant <=  tab_para_automate[0][0])
        evenement = 5; //Decrement para_2

    if (tddv_estime < tddv_worst &&  *para_2_courant <= tab_para_automate[1][1])
        evenement = 6; //Increment para2

    if (tddv_estime == tddv_worst)
        evenement = 7; //Etat Invariant 2

    if (tddv_estime > tddv_worst && *para_1_courant<=  tab_para_automate[0][0] && *para_2_courant<=  tab_para_automate[1][0])
        evenement = 8; //Etat radar sature


    switch (*etat_courant) {
        case INIT:
            switch(evenement)
            {
                case 1:
                    *etat_courant = INIT;
                    printf("ETAT_INITIAL\n");
                    break;
                case 2:
                    *etat_courant = DECREMENT_PARA_1;
                    printf("DECREMENT_PARA_1\n");
                    break;
            }
            break;

        case DECREMENT_PARA_1:
            switch(evenement)
            {
                case 5:
                    *etat_courant = DECREMENT_PARA_2;
                    printf("DECREMENT_PARA_2\n");
                    break;
                case 4:
                    *etat_courant = ETAT_INVARIANT_1;
                    printf("ETAT_INVARIANT_1\n");
                    break;
                case 3:
                    *etat_courant = INCREMENT_PARA_1;
                    printf("INCREMENT_PARA_1\n");
                    break;
                case 2:
                    *etat_courant = DECREMENT_PARA_1;
                    printf("DECREMENT_PARA_1\n");
                    break;
            }
            break;
        case INCREMENT_PARA_1:
            switch(evenement)
            {
                case 4:
                    *etat_courant = ETAT_INVARIANT_1;
                    printf("ETAT_INVARIANT_1\n");
                    break;
                case 3:
                    *etat_courant = INCREMENT_PARA_1;
                    printf("INCREMENT_PARA_1\n");
                    break;
                case 2:
                    *etat_courant = DECREMENT_PARA_1;
                    printf("DECREMENT_PARA_1\n");
                    break;
            }
            break;

        case ETAT_INVARIANT_1:
            switch(evenement)
            {
                case 2:
                    *etat_courant = DECREMENT_PARA_1;
                    printf("DECREMENT_PARA_1\n");
                    break;
                case 4:
                    *etat_courant = ETAT_INVARIANT_1;
                    printf("ETAT_INVARIANT_1\n");
                    break;
                case 3:
                    *etat_courant = INCREMENT_PARA_1;
                    printf("INCREMENT_PARA_1\n");
                    break;
            }
            break;

        case DECREMENT_PARA_2:
            switch(evenement)
            {
                case 5:
                    *etat_courant = DECREMENT_PARA_2;
                    printf("DECREMENT_PARA_2\n");
                    break;
                case 7:
                    *etat_courant = ETAT_INVARIANT_2;
                    printf("ETAT_INVARIANT_2\n");
                    break;
                case 6:
                    *etat_courant = INCREMENT_PARA_2;
                    printf("INCREMENT_PARA_2\n");
                    break;
                case 8:
                    *etat_courant = RADAR_SATURE;
                    printf("RADAR_SATURE\n");
                    break;
            }
            break;
        case ETAT_INVARIANT_2:
            switch(evenement)
            {
                case 5:
                    *etat_courant = DECREMENT_PARA_2;
                    printf("DECREMENT_PARA_2\n");
                    break;
                case 7:
                    *etat_courant = ETAT_INVARIANT_2;
                    printf("ETAT_INVARIANT_2\n");
                    break;
                case 6:
                    *etat_courant = INCREMENT_PARA_2;
                    printf("INCREMENT_PARA_2\n");
                    break;
                }
                break;

        case INCREMENT_PARA_2:
            switch(evenement)
            {
                case 5:
                    *etat_courant = DECREMENT_PARA_2;
                    printf("DECREMENT_PARA_2\n");
                    break;
                case 7:
                    *etat_courant = ETAT_INVARIANT_2;
                    printf("ETAT_INVARIANT_2\n");
                    break;
                case 6:
                    *etat_courant = INCREMENT_PARA_2;
                    printf("INCREMENT_PARA_2\n");
                    break;
                case 3:
                    *etat_courant = INCREMENT_PARA_1;
                    printf("INCREMENT_PARA_1\n");
                    break;
            }
            break;
            default :
                exit(1);
                break;

    }

}

Can anyone tell me why the variable etat_courant doesn't keep the value in memory for each iteration please ?

它实际上是将值保存在内存中:它不能这样做,etat_courant 将一直保存在内存中,直到 fct_test(...) returns。输出总是 DECREMENT_PARA_1 的原因纯粹是由于 automate() 函数中的逻辑。

例如,您在 automate() 函数中进行了冗余比较 - 它覆盖了先前对 evenement 的赋值。

if (tddv_estime == tddv_worst)
    evenement = 4; //Etat Invariant 1

// ...

if (tddv_estime == tddv_worst)
    evenement = 7; //Etat Invariant 2

如果 - 这只是假设(这是否是正确的做法取决于您要实现的目标)- 您删除第二个比较,输出将至少变化一次。

顺便说一句...将数组的大小传递给 fct_test(...) 函数更安全 - 如

int main(void) {
    int scenario[] = {21, 21, 20, 12, 12, 20, 22, 22,
                    22, 22, 22, 22, 22, 22, 500};
    fct_test(scenario, sizeof(scenario)/sizeof(scenario[0]));
    return 0;
}

void fct_test(int *scenario, size_t array_len) {
    // Etc. (ommitted for brevity )
    for (i = 0; i < array_len; i++) {
         tddv_estime = scenario[i];
         // etc.
    }
}

(请注意,我在您的 main() 中添加了一个 return 0 - 您遗漏了。)