Как можно зациклить стек на си

Есть у меня стек такого вида:

typedef union {
    float f;
    int   i;
    struct{
    int16_t  lo;
    uint16_t hi;
    };
} uniondata;

typedef struct {
    int    *MCALC_TOP;
    uniondata  data[32];
    int     size;
} Mcalc;

extern Mcalc MCALC;

Со следующими методами:

void initStackMcalc(Mcalc *stack)
{
 stack->size = 0;
}


void pushMcalcF(Mcalc *stack, float value)
{
 stack->data[stack->size].f = value;
 stack->size ++;
}


float popMcalcF(Mcalc *stack)
{
 float val = 0.0;
 val = stack->data[stack->size].f;
 stack->size --;
 return(val);
}

Нужно его как-то зациклировать. Когда стек заполнен и вызывается метод 'pushMcalcF' нужно сдвинуть и записать последней с сохранением размера стека. Метод 'popMcalcF' должен брать с вершины стека если произошел сдвиг.


Ответы (1 шт):

Автор решения: zhilenkov

Я подумал сделать что-то типа такого. Может где ошибся. Проверьте.

#define McalcSize 32 // размер стека
#define McalcSizeMask (McalcSize - 1) // маска
typedef union {
    float f;
    int   i;
    struct{
    int16_t  lo;
    uint16_t hi;
    };
} uniondata;

typedef struct {
    int    *MCALC_TOP; // указатель на верхней элемент в стеке калькулятора
    uniondata  data[32];
    int     size;
} Mcalc;

extern Mcalc MCALC;

Методы:

void initStackMcalc(Mcalc *stack)
{
 for(uint8_t i = 0; i < McalcSize; i++){
     stack->data[i].i = 0;
 }
 stack->size = 0;
}


void pushMcalcF(Mcalc *stack, float value)
{
 stack->data[++stack->size].f = value;
 stack->size &= McalcSizeMask;
}


float popMcalcF(Mcalc *stack)
{
 float val = 0.0;
 if(stack->size != 0){
 val = stack->data[stack->size --].f;
 stack->size &= McalcSizeMask;
 }
 return(val);
}
→ Ссылка