4、环形队列的实现(C语言)



一、实现原理如下图所示

 

环形队列实现需注意以下四点(本质上是和“3、一个简单队列的实现”一样的):
(1)往队列中写数据
memcpy(&g_tQue[g_iWritePos],pNode,sizeof(T_QUEUE));
g_iWritePos = (g_iWritePos + 1) % QUEUE_SIZE_MAX;

(2)从队列中读出数据
memcpy(pNode,&g_tQue[g_iReadPos],sizeof(T_QUEUE));
g_iReadPos = (g_iReadPos + 1) % QUEUE_SIZE_MAX;
(3)队列放满数据
((g_iWritePos + 1) % QUEUE_SIZE_MAX) == g_iReadPos),下一个要写的位置等于要读的位置,
则队列放满,实际上队列满的时候,里边存放的QUEUE_SIZE_MAX - 1个数据,这样做是为了和空
队列加以区分管

(4)队列为空(没有数据)
g_iWritePos == g_iReadPos,当前要写的位置等于当前要写的位置,则队列为空
二、代码实现如下

 (1)简单实现

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 #define QUEUE_SIZE_MAX        10            
 6 #define MY_BUF_SIZE           128
 7 
 8 typedef struct{
 9     int type;
10     int reserve;
11     int buf[MY_BUF_SIZE];
12 }T_QUEUE;
13 
14 static T_QUEUE g_tQue[QUEUE_SIZE_MAX];
15 
16 static int g_iReadPos = 0;
17 static int g_iWritePos = 0;;
18 
19 static int isFull(void)
20 {
21     return (((g_iWritePos + 1) % QUEUE_SIZE_MAX) == g_iReadPos);
22 }
23 
24 static int isEmpty(void)
25 {
26     return (g_iWritePos == g_iReadPos);
27 }
28 
29 static int PutData(T_QUEUE *pNode)
30 {
31     if (isFull())
32     {
33         printf("queque is overflow!\r\n");
34         return -1;
35     }
36     else
37     {
38         memcpy(&g_tQue[g_iWritePos],pNode,sizeof(T_QUEUE));    
39         g_iWritePos = (g_iWritePos + 1) % QUEUE_SIZE_MAX;
40         return 0;
41     }
42 }
43 
44 static int GetData(T_QUEUE *pNode)
45 {
46     if (isEmpty())
47     {
48         printf("queque is empty!\r\n");
49         return -1;
50     }
51     else
52     {
53         memcpy(pNode,&g_tQue[g_iReadPos],sizeof(T_QUEUE));
54         g_iReadPos = (g_iReadPos + 1) % QUEUE_SIZE_MAX;
55     }
56     
57 }

 (2)通用型

<1>创建ring_queue.c文件

 1 // 初始化队列
 2 int ring_queue_init(int* piWritePos, int* piReadPos)
 3 {
 4     *piWritePos = 0;
 5     *piReadPos = 0;
 6     return 0;
 7 }
 8 
 9 // 队列是否已满
10 int isFull(int* piWritePos, int* piReadPos, int iQueSizeMax)
11 {    
12     return (((*piWritePos + 1) % iQueSizeMax) == *piReadPos);
13 }
14 
15 // 队列是否为空
16 int isEmpty(int* piWritePos, int* piReadPos)
17 {
18     return (*piWritePos == *piWritePos);
19 }
20 
21 // 队列中放入数据
22 int PutData(int* piWritePos, int* piReadPos, void *tQue, void *pNode, int iQueSizeMax, int NodeSize)
23 {
24     
25     if (isFull(piWritePos,piReadPos,iQueSizeMax))
26     {
27         printf("queque is overflow!\r\n");
28         return -1;
29     }
30     else
31     {
32         memcpy(tQue + (*piWritePos) * NodeSize,pNode,NodeSize);    
33         *piWritePos = (*piWritePos + 1) % iQueSizeMax;
34         return 0;
35     }
36 }
37 
38 // 从队列中取数据
39 int GetData(int* piWritePos, int* piReadPos, void *tQue, void *pNode, int iQueSizeMax, int NodeSize)
40 {
41     if (isEmpty(piWritePos,piReadPos))
42     {
43         printf("queque is empty!\r\n");
44         return -1;
45     }
46     else
47     {
48         memcpy(pNode,tQue + (*piReadPos) * NodeSize,NodeSize);
49         *piReadPos = (*piReadPos + 1) % iQueSizeMax;
50         return 0;
51     }
52     
53 }

<2>创建example1.c文件

  1 #define DATA_ARRAY_MAX     (5)
  2 #define MAX_DATA_SIZE     (64)    
  3 #define MSG_BUF_SIZE         (64)
  4 typedef struct
  5 {
  6     unsigned long hid;
  7     unsigned long cid;
  8     unsigned char type;
  9     unsigned char len;    
 10     unsigned char chksum;
 11     unsigned char seq;
 12     unsigned char userData[MAX_DATA_SIZE];
 13 }DATA_T;
 14 
 15 typedef struct
 16 {
 17     unsigned int version;
 18     unsigned int channel;
 19     unsigned int reserve;
 20 }DATA_INFO_T;
 21 
 22 
 23 typedef struct{
 24     int type;
 25     int data;
 26     int arBuf[MSG_BUF_SIZE];
 27 }ITEM_MSG_T;
 28 
 29 typedef enum
 30 {
 31     RECV_PORT1_DATA,
 32     RECV_PORT2_DATA,
 33     RECV_PORT3_DATA,
 34 }MSG_TYPE_E;
 35 typedef enum
 36 {
 37     GET_BD_INFO_REQ,
 38     GET_BD_INFO_RES,
 39 }DATA_TYPE_E;
 40 
 41 int g_iQin = 0;
 42 int g_iQout = 0;
 43 
 44 static unsigned char tx_buf[sizeof(DATA_T)];
 45 
 46 static DATA_T g_tArray[DATA_ARRAY_MAX];
 47 /*****************************************************************
 48   * @brief    初始化队列
 49   *
 50   * @param    no
 51   *
 52   *@retval    no
 53   *
 54   *****************************************************************/
 55 void Example1_init(void)
 56 {
 57     ring_queue_init(&g_iQin, &g_iQout);
 58 }
 59 
 60 /*****************************************************************
 61   * @brief    把数据放入队列
 62   *
 63   * @param    pData        指向要放入队列的数据
 64   *
 65   * @param    len            数据长度
 66   *
 67   *@retval    len            放入队列的数据长度
 68   *
 69   *****************************************************************/
 70 int SendData(void *pData,int len)
 71 {
 72     PutData(&g_iQin, &g_iQout, g_tArray,pData,sizeof(g_tArray),len);
 73     return len;
 74 }
 75 
 76 int RecieveData(void)
 77 {
 78     GetData(&g_iQin, &g_iQout, g_tArray, tx_buf,sizeof(g_tArray),sizeof(DATA_T));
 79     return 0;
 80 }
 81 
 82 unsigned char MakeCheckSum(DATA_T *pData)
 83 {
 84     unsigned char ucCheckSum = 0;
 85     unsigned char ucTmp;
 86     unsigned char *pWork = (unsigned char *)pData;
 87 
 88     for(ucTmp=0;ucTmp<pData->len;ucTmp++){
 89         ucCheckSum += pWork[ucTmp];
 90     }
 91 
 92     ucCheckSum = ~ucCheckSum;
 93     ucCheckSum++;
 94     
 95     return ucCheckSum;
 96 }
 97 static int MkSlaveWithData(DATA_T *pReq, DATA_T *pRes,unsigned char type ,unsigned char*pdata, int datalen)
 98 {
 99     pRes->hid = pReq->hid;
100     pRes->cid = pReq->cid;
101     pRes->type = type;
102     pRes->len = sizeof(DATA_T) - MAX_DATA_SIZE + datalen;
103     pRes->chksum = 0;
104     pRes->seq = pReq->seq;
105     memcpy(pRes->userData, pdata, datalen);
106 
107     pRes->checksum = MakeCheckSum(pRes);
108 
109     return pRes->len;
110 
111 }
112 
113 int DataProcess(ITEM_MSG_T * pMsg)
114 {
115     DATA_T tmp_data;
116     DATA_T res_data;
117     DATA_INFO_T info;
118 
119     memcpy(&tmp_data,pMsg->arBuf,sizeof(DATA_T));
120     if (pMsg->type == RECV_PORT1_DATA)
121     {
122         if (tmp_data.type == GET_BD_INFO_REQ)
123         {
124             memset(&info,0,sizeof(DATA_INFO_T));
125             info.version = 100;
126             info.channel =  96;
127             MkSlaveWithData(tmp_data,res_data,GET_BD_INFO_RES,(unsigned char*) &info,sizeof(DATA_INFO_T));
128             SendData(&res_data, sizeof(DATA_T));            // 发送到环形队列
129         }
130     }    
131 }

 

<3>创建example2.c文件

  1 #define MAX_MSG_DATA_LEN                 (128)
  2 
  3 typedef struct MSG_QUEUE_ITEM_T                // 队列项数据结构定义
  4 {
  5     int len;
  6     unsigned char data[MAX_MSG_DATA_LEN];            //队列项的大小128
  7 }MSG_QUEUE_ITEM_T;
  8 
  9 #define MSG_QUE_SIZE_MAX                 (6)            //4
 10 
 11 typedef struct ID_TBL_ITEM_T                        // 列表项数据结构定义
 12 {
 13     int used;
 14     unsigned long id;
 15     int head;
 16     int tail;
 17     MSG_QUEUE_ITEM_T queue[MSG_QUE_SIZE_MAX];    //列表项中定义一个队列,大小为6
 18 }ID_TBL_ITEM_T;
 19 
 20 #define ID_TBL_SIZE                         (2)         // 列表大小为2
 21 ID_TBL_ITEM_T g_IdTbl[ID_TBL_SIZE];                    // 定义一个列表
 22 
 23 
 24 int id_tbl_init(void)
 25 {
 26     int i;
 27     for (i=0; i<ID_TBL_SIZE; i++)
 28     {
 29         g_IdTbl[i].used = 0;
 30     }
 31     return 0;
 32 }
 33 
 34 #if 0
 35 int add_id_to_tbl(unsigned long id)
 36 {
 37     int i;
 38     for (i=0; i<ID_TBL_SIZE; i++)
 39     {
 40         if (g_IdTbl[i].used == 1)
 41         {
 42             if ((g_IdTbl[i].id == id)
 43             {
 44                 return 0;
 45             }
 46         }
 47     }
 48 
 49     for (i=0; i<ID_TBL_SIZE; i++)
 50     {
 51         if (g_IdTbl[i].used == 0)
 52         {
 53             g_IdTbl[i].used = 1;
 54             g_IdTbl[i].id = id;
 55             g_IdTbl[i].head = 0;
 56             g_IdTbl[i].tail = 0;
 57             
 58             return 1;
 59         }
 60     }
 61 
 62     return 0;
 63 }
 64 #endif
 65 
 66 int add_id_to_tbl(unsigned long id)
 67 {
 68     int i;
 69     for (i=0; i<ID_TBL_SIZE; i++)
 70     {
 71         if (g_IdTbl[i].used == 1)
 72         {
 73             if ((g_IdTbl[i].id == id)
 74             {
 75                 return 0;
 76             }
 77         }
 78         else
 79         {
 80             g_IdTbl[i].used = 1;
 81             g_IdTbl[i].id = id;
 82             g_IdTbl[i].head = 0;
 83             g_IdTbl[i].tail = 0;            
 84             return 1;
 85         }
 86     }
 87     if (i >= ID_TBL_SIZE)
 88     {
 89         printf("id tbl overflow!!!\r\n");
 90     }
 91     return 0;
 92 }
 93 
 94 int del_id_from_tbl(unsigned long id)
 95 {
 96     int i;
 97     for (i=0; i<ID_TBL_SIZE; i++)
 98     {
 99         if (g_IdTbl[i].used == 1)
100         {
101             if ((g_IdTbl[i].id == id)
102             {
103                 g_IdTbl[i].used = 0;
104                 return 1;
105             }
106         }
107     }
108     printf("don't find id!!!\r\n");
109     return 0;
110 }
111 
112 int get_tbl_index(unsigned long id)
113 {
114     int i;
115     for (i=0; i<ID_TBL_SIZE; i++)
116     {
117         if (g_IdTbl[i].used == 1)
118         {
119             if ((g_IdTbl[i].id == id)
120             {
121                 return i;
122             }
123         }
124     }
125     printf("don't find index!!!\r\n");
126     return ID_TBL_SIZE;
127 }
128 
129 int put_send_data_to_queue(unsigned long id , unsigned char *data, int len)
130 {
131     int indx;
132     ID_TBL_ITEM_T * pListItem;
133     MSG_QUEUE_ITEM_T QueItem;
134     indx = get_tbl_index(id );
135     if (indx == ID_TBL_SIZE)
136     {
137         return 0;
138     }
139     memset(&QueItem,0,sizeof(MSG_QUEUE_ITEM_T));
140     QueItem.len = len;
141     memcpy(QueItem.data,data,len);
142 
143     pListItem =& g_IdTbl[indx];
144 
145     return  PutData(&pListItem->head, &pListItem->tail ,pListItem->queue, &QueItem ,MSG_QUE_SIZE_MAX ,sizeof(MSG_QUEUE_ITEM_T))
146 
147 }
148 
149 int get_send_data_from_queue(int idx, MSG_QUEUE_ITEM_T* pQueItem)
150 {
151     ID_TBL_ITEM_T * pListItem;
152 
153     pListItem = g_IdTbl[idx];
154     return GetData(&pListItem->head, &pListItem->tail ,pListItem->queue, void *pQueItem,MSG_QUE_SIZE_MAX,sizeof(MSG_QUEUE_ITEM_T));
155 
156 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM