编辑代码

#include <stdio.h>
#include <string.h>
//#include <stdint.h>

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

/**
  * @brief  缓存区操作信息结构体定义
  */
typedef struct{
    uint8_t  state;         /*!< 控制状态 */
    
    uint8_t  end;           /*!< 循环队列尾哨兵 */
    
    uint8_t  head;          /*!< 循环队列首哨兵 */
    
    uint8_t  num;           /*!< 循环队列中能存储的最多组数 */
} QueueCtrl_t;

#define QUEUE_ENABLE_COVER      (0X80)
#define QUEUE_EXIT_DATA         (0X01)
#define QUEUE_DATA_FULL         (0X02)
#define QUEUE_DATA_LOCK         (0X04)

/**
  * @brief      队列控制初始化
  * 
  * @param[in,out]  ctrl - 队列控制句柄
  * @param[in]  num - 队列数目大小
  * @param[in]  cover - 0,不覆盖; 1,队列满了覆盖顶端数据
  */
#define QUEUE_INIT(ctrl, maxNum, cover)  ({\
    ctrl.end    = 0;\
    ctrl.head   = 0;\
    ctrl.num    = (maxNum);\
    ctrl.state  = 0x00;\
    ctrl.state  |= ((cover) ? QUEUE_ENABLE_COVER : 0);\
})

/**
  * @brief      在队列末尾加入新的数据
  * 
  * @param[in,out]  dstLists - 队列缓存区
  * @param[in]      src - 新的数据
  * @param[in,out]  ctrl - 队列控制句柄
  * @retval     返回的值含义如下
  *             @arg 0: 写入成功
  *             @arg -1: 写入失败
  */
#define QUEUE_PUSH_DATA(dstLists, src, ctrl)  ({ \
    int ret = 0;\
\
    if (QUEUE_DATA_LOCK != ((ctrl.state) & QUEUE_DATA_LOCK))  \
    {\
        dstLists[(ctrl.end)++] = src;\
        (ctrl.state) |= QUEUE_EXIT_DATA;  \
\
        if ((ctrl.end) >= (ctrl.num))\
        {\
            (ctrl.end) = 0;\
        }\
\
        if (((ctrl.state) & QUEUE_DATA_FULL) == QUEUE_DATA_FULL)\
        {\
            (ctrl.head) = (ctrl.end);\
        }\
        else if ((ctrl.end) == (ctrl.head))\
        {\
            (ctrl.state) |= QUEUE_DATA_FULL;\
\
            if ((ctrl.state & QUEUE_ENABLE_COVER) != QUEUE_ENABLE_COVER)     \
            {\
                (ctrl.state) |= QUEUE_DATA_LOCK;\
            }\
        }\
\
        ret = 0;\
    }\
    else\
    {\
        ret = -1;\
    }\
\
    ret;\
})

/**
  * @brief      在队列顶端读取数据
  * 
  * @param[in,out]  dstLists - 队列缓存区
  * @param[out]     dst - 读取的数据
  * @param[in,out]  ctrl - 队列控制句柄
  * @retval     返回的值含义如下
  *             @arg 0: 读取成功
  *             @arg -1: 读取失败
  */
#define QUEUE_POP_DATA(dstLists, dst, ctrl)  ({\
\
    int ret = -1;\
\
    if (((ctrl.state) & QUEUE_EXIT_DATA) == QUEUE_EXIT_DATA)\
    {\
        dst = dstLists[ctrl.head++];\
\
        if ((ctrl.head) >= (ctrl.num))\
        {\
            ctrl.head = 0;\
        }\
\
        if ((ctrl.head) == (ctrl.end))\
        {\
            if (((ctrl.state) & QUEUE_DATA_FULL) != QUEUE_DATA_FULL)\
            {\
                (ctrl.state) &= ~QUEUE_EXIT_DATA;\
            }\
        }\
\
        ret = 0;\
    }\
\
    (ctrl.state) &= ~QUEUE_DATA_LOCK;\
    (ctrl.state) &= ~QUEUE_DATA_FULL;\
\
    ret;\
})

typedef struct{
    char  szDesc[20];
    uint8_t value;
    
} TestInfo1_t;

typedef struct{
    char  szDesc[20];
    float value;
    
} TestInfo2_t;


TestInfo1_t g_TestInfo1QueueBuff[10];
QueueCtrl_t g_TestInfo1QueueCtrl;

TestInfo2_t g_TestInfo2QueueBuff[5];
QueueCtrl_t g_TestInfo2QueueCtrl;

char g_stringQueueBuff[20];
QueueCtrl_t g_TestString2QueueCtrl;

int main(int argc, char **argv) {
    int i;
    TestInfo1_t testInfo1;
    TestInfo2_t testInfo2;
    
    QUEUE_INIT(g_TestInfo1QueueCtrl, 10, 1);    // 允许覆盖写入
    QUEUE_INIT(g_TestInfo2QueueCtrl, 5, 0);     // 禁止覆盖写入
    QUEUE_INIT(g_TestString2QueueCtrl, 20, 0);     // 禁止覆盖写入
    
    printf("\n存入队列1:");
    
    for (i = 0; i < 12; i++)
    {
        sprintf(testInfo1.szDesc, "测试数据-%d", i + 1);
        testInfo1.value = i + 1;
        
        if (0 == QUEUE_PUSH_DATA(g_TestInfo1QueueBuff, testInfo1, g_TestInfo1QueueCtrl))
        {
            printf("%d.成功 ", i + 1);
        }
        else
        {
            printf("%d.失败 ", i + 1);
        }
    }

    printf("\n存入队列2:");
    
    for (i = 0; i < 7; i++)
    {
        sprintf(testInfo2.szDesc, "测试数据-%d", i + 1);
        testInfo2.value = 2.56 * (i + 1) * 2.56;
        if (0 == QUEUE_PUSH_DATA(g_TestInfo2QueueBuff, testInfo2, g_TestInfo2QueueCtrl))
        {
            printf("%d.成功 ", i + 1);
        }
        else
        {
            printf("%d.失败 ", i + 1);
        }
    }

    printf("\n存入字符队列3:");
    
    for (i = 0; i < 22; i++)
    {
        if (0 == QUEUE_PUSH_DATA(g_stringQueueBuff, 'a' + i, g_TestString2QueueCtrl))
        {
            printf("%d.成功 ", i + 1);
        }
        else
        {
            printf("%d.失败 ", i + 1);
        }
    }
    
    printf("\n\n读取队列1:");
    
    while (QUEUE_POP_DATA(g_TestInfo1QueueBuff, testInfo1, g_TestInfo1QueueCtrl) == 0)
    {
        printf(" %s(%d) ", testInfo1.szDesc, testInfo1.value);
    }

    printf("\n读取队列2:");
    
    while (QUEUE_POP_DATA(g_TestInfo2QueueBuff, testInfo2, g_TestInfo2QueueCtrl) == 0)
    {
        printf(" %s(%f) ", testInfo2.szDesc, testInfo2.value);
    }

    printf("\n读取字符队列3:");
    char schar;
    while (QUEUE_POP_DATA(g_stringQueueBuff, schar, g_TestString2QueueCtrl) == 0)
    {
        printf("%c", schar);
    }
    
    return 0;
}