C语言循环数组做FIFO队列

C语言循环数组做FIFO队列
在做通信时,FIFO队列queue是非常好用的,先完成接收通信把接收的数据存在队列里;然后再进行先进先出逐项处理。
C语言用循环数组,通过读位置和写位置循环来实现FIFO队列功能。即数组队列。

1 以1个字节为单位的数组队列的数据结构
使用数组队列,为了方便判断队列空和队列满,使用不完全填满队列,即保留一个元素始终不用
下面是两个例子
[cpp]  view plain copy
  1. char usart1_rev_buf[USART1_BUFFER_MAX_SIZE] = {0};     //usart receive buffer.  
  2. unsigned short usart1_r = 0;                           //usart receive buffer read position.  
  3. unsigned short usart1_w = 0;                           //usart receive buffer write position.  
  4.   
  5. char sendBufForUsart[SEND_BUF_MAX_SIZE] = {0};         //usart send buffer.  
  6. unsigned short sendWrite = 0;                          //usart send buffer write position.  
  7. unsigned short sendRead = 0;                           //usart send buffer read position.  
记住:
sendRead 是下一个将要读取的位置,现在还未读取。
     相当于队列头front,可执行delete操作。
sendWrite 是下一个将要写入的位置,现在还未写入。
     相当于队列尾rear,可执行insert操作。
保留不用的元素位置是(( sendRead+SEND_BUF_MAX_SIZE-1)%SEND_BUF_MAX_SIZE)。
判断队列空?         sendRead == sendWrite
判断队列满?        (sendWrite+1)%SEND_BUF_MAX_SIZE == sendRead


写操作
WrData为待写入的字节内容,WrBuf为待写入的内容buf,WrLen为待写的长度。
写一个字节
[cpp]  view plain copy
  1. if ((usart1_w+1)%USART1_BUFFER_MAX_SIZE != usart1_r)  
  2. {  
  3.      usart1_rev_buf[usart1_w] = WrData;  
  4.      usart1_w = (usart1_w+1) % USART1_BUFFER_MAX_SIZE;  
  5. }    
写多个字节
[cpp]  view plain copy
  1. unsigned short emptyLen;  
  2. unsigned short tmpAddr;  
  3. unsigned short tmpLen;  
  4.   
  5. emptyLen = (sendRead+SEND_BUF_MAX_SIZE-(sendWrite+1)) % SEND_BUF_MAX_SIZE;  
  6. if (emptyLen >= WrLen)  
  7. {  
  8.      tmpAddr = (sendWrite+WrLen) % SEND_BUF_MAX_SIZE;  
  9.      if (tmpAddr <= sendWrite)            //If Circular array have inverse to begin.  
  10.      {  
  11.           tmpLen =WrLen - tmpAddr;  
  12.           memcpy(&sendBufForUsart[sendWrite], WrBuf, tmpLen);   //bug place  
  13.           memcpy(&sendBufForUsart[0], WrBuf+tmpLen, tmpAddr);      
  14.      }  
  15.      else  
  16.      {  
  17.           memcpy(&sendBufForUsart[sendWrite], WrBuf, WrLen);  
  18.      }  
  19.   
  20.        
  21.      sendWrite = tmpAddr;  
  22. }  
读操作
RdBuf为存储读取内容的buf,RdLen为待读的长度。
读一个字节
[cpp]  view plain copy
  1. if (usart1_r != usart1_w)    //Have new data in usart receive buffer.  
  2. {  
  3.      *RdBuf = usart1_rev_buf[usart1_r];  
  4.      usart1_r = (usart1_r+1) % USART1_BUFFER_MAX_SIZE;     //Read out one byte.  
  5. }  
读多个字节
[cpp]  view plain copy
  1.      unsigned short validLen;  
  2.      unsigned short tmpAddr;  
  3.      unsigned short tmpLen;  
  4.   
  5.      validLen = (sendWrite+SEND_BUF_MAX_SIZE-sendRead) % SEND_BUF_MAX_SIZE;  
  6.      if (validLen >= RdLen)  
  7.      {  
  8.          tmpAddr = (sendRead+RdLen) % SEND_BUF_MAX_SIZE;  
  9.          if (tmpAddr <= sendRead) //If Circular array have inverse to begin.  
  10.          {  
  11.            tmpLen =RdLen - tmpAddr;  
  12.            memcpy(RdBuf, &sendBufForUsart[sendRead], tmpLen);  
  13.            memcpy(RdBuf+tmpLen, &sendBufForUsart[0], tmpAddr);       
  14.          }  
  15.          else  
  16.          {  
  17.            memcpy(RdBuf, &sendBufForUsart[sendRead], RdLen);  
  18.          }  
  19.          sendRead = tmpAddr;  
  20. }  


10.2 以固定N_LEN个字节为单位的队列的数据结构。使用二维数组队列。
要求每次写队列和每次读队列,长度都固定是 N_LEN。

下面是一个例子,每次读写固定长度为 CMD_LENGTH, 我使用二维数组实现。根据应用不同,也可选结构体数组。
[cpp]  view plain copy
  1. char sendBufForUsart[SEND_BUF_MAX_NUM][CMD_LENGTH] = {0};  
  2. unsigned short sendWrite = 0;  
  3. unsigned short sendRead = 0;  

写CMD_LENGTH长度
[cpp]  view plain copy
  1. if ((sendWrite+1)%SEND_BUF_MAX_NUM != sendRead)    //Have new data.  
  2. {  
  3.     memcpy(&sendBufForUsart[sendWrite][0], WrBuf, CMD_LENGTH);  
  4.     sendWrite = (sendWrite+1) % SEND_BUF_MAX_NUM;    //Read out one byte.  
  5. }  
读CMD_LENGTH长度
[cpp]  view plain copy
  1. if (sendRead != sendWrite)  
  2. {  
  3.     memcpy(RdBuf, &sendBufForUsart[sendRead][0], CMD_LENGTH);  
  4.     sendRead = (sendRead + 1) % SEND_BUF_MAX_NUM;  
  5. }  

用结构可以更明了的说明循环队列的使用
[cpp]  view plain copy
  1. *typedef struct{   
  2.  *    valuetype data[MAXSIZE];    [>数据的存储区<]   
  3.  *    int font, rear;     [>队首队尾<]   
  4.  *    int num;    [>队列中元素的个数<]   
  5.  *}Circular_Queue;    

以上是根据本人经验的一些认识。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值