搜索
bottom↓
回复: 39
打印 上一主题 下一主题

一个不错的队列代码,发给大家看看

  [复制链接]

出0入0汤圆

跳转到指定楼层
1
发表于 2013-5-15 21:50:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 cyj_0220 于 2013-5-16 09:15 编辑

从书上抄下来的,觉得不错,发给大家看看

  1. /*******************************************************************************
  2. **File Name   : queue.c
  3. **MCU Chip    :
  4. **FOSC        :
  5. **CCLK        :
  6. **Description :
  7. **Author      :
  8. **Version     :
  9. *******************************************************************************/
  10. #include "queue.h"




  11. /*==============================================================================
  12. **                                                                            **
  13. **                          FUNCTION PROTOTYPES                               **
  14. **                                                                            **
  15. ==============================================================================*/
  16. __STATIC_INLINE void CopyToNode(Node_Type *pq,ITEM item);
  17. __STATIC_INLINE void CopyToItem(ITEM *pitem,Node_Type *pq);
  18. void  QueueInit(Queue_Type *pq);
  19. BOOL  QueueIsFull(const Queue_Type *pq);
  20. BOOL  QueueIsEmpty(const Queue_Type *pq);
  21. UINT8 QueueItemCnt(const Queue_Type *pq);
  22. BOOL  EnQueue(Queue_Type *pq,ITEM item);
  23. BOOL  DeQueue(Queue_Type *pq,ITEM *pitem);
  24. void  EmptyTheQueue(Queue_Type *pq);



  25. /*==============================================================================
  26. **                                                                            **
  27. **                        GLOBAL VARIABLES                                    **
  28. **                                                                            **
  29. ==============================================================================*/




  30. /*==============================================================================
  31. **                                                                            **
  32. **                      LOCAL GLOBAL VARIABLES                                **
  33. **                                                                            **
  34. ==============================================================================*/








  35. /******************************************************************************
  36. **Function Name     : QueueInit
  37. **Input Parameters  : none
  38. **Output Parameters : none
  39. **Returned Value    : none
  40. **Descrition        : initialize queue
  41. ******************************************************************************/
  42. void QueueInit(Queue_Type *pq)
  43. {
  44.     pq->pfront    = NULL;
  45.     pq->prear     = NULL;
  46.     pq->ucItemCnt = 0;
  47. }
  48. /******************************************************************************
  49. **Function Name     : QueueIsFull
  50. **Input Parameters  : the queue base pointer
  51. **Output Parameters : none
  52. **Returned Value    : 1->full
  53. **                    0->not full
  54. **Descrition        : initialize queue
  55. ******************************************************************************/
  56. BOOL QueueIsFull(const Queue_Type *pq)
  57. {
  58.     return (QUEUE_SIZE == pq->ucItemCnt);
  59. }
  60. /******************************************************************************
  61. **Function Name     : QueueIsEmpty
  62. **Input Parameters  : the queue base pointer
  63. **Output Parameters : none
  64. **Returned Value    : 1 -> empty
  65. **                    0 -> not empty
  66. **Descrition        : initialize queue
  67. ******************************************************************************/
  68. BOOL QueueIsEmpty(const Queue_Type *pq)
  69. {
  70.     return (0 == pq->ucItemCnt);
  71. }
  72. /******************************************************************************
  73. **Function Name     : QueueGetItemCnt
  74. **Input Parameters  : the queue base pointer
  75. **Output Parameters : none
  76. **Returned Value    : 1 -> empty
  77. **                    0 -> not empty
  78. **Descrition        : initialize queue
  79. ******************************************************************************/
  80. UINT8 QueueItemCnt(const Queue_Type *pq)
  81. {
  82.     return (pq->ucItemCnt);
  83. }
  84. /******************************************************************************
  85. **Function Name     : CopyToNode
  86. **Input Parameters  : Queue_Type *pq -> the queue base pointer
  87. **                    ITEM item      -> the value of item
  88. **Output Parameters : none
  89. **Returned Value    : none
  90. **Descrition        : initialize queue
  91. ******************************************************************************/
  92. __STATIC_INLINE void CopyToNode(Node_Type *pq,ITEM item)
  93. {
  94.     pq->item = item;
  95. }
  96. /******************************************************************************
  97. **Function Name     : EnQueue
  98. **Input Parameters  : Queue_Type *pq -> the queue base pointer
  99. **                    ITEM item      -> the value of item
  100. **Output Parameters : none
  101. **Returned Value    : 1 -> enqueue successful
  102. **                    0 -> enqueue failure
  103. **Descrition        : initialize queue
  104. ******************************************************************************/
  105. BOOL EnQueue(Queue_Type *pq,ITEM item)
  106. {
  107.     Node_Type *pnew;
  108.    
  109.     if(QueueIsFull(pq))
  110.     {
  111.         return FALSE;
  112.     }
  113.     pnew = (Node_Type *)malloc(sizeof(Node_Type));       //obtain a memory space
  114.     if(pnew == NULL)                  //obtain a memory space fail ?                                                                  
  115.     {
  116.         return FALSE;
  117.     }
  118.     CopyToNode(pnew,item);           //copy to node
  119.     pnew->pnext = NULL;               //restore pointer
  120.     if(QueueIsEmpty(pq))
  121.     {
  122.         pq->pfront = pnew;            //the new node is the first one
  123.     }
  124.     else
  125.     {
  126.         pq->prear->pnext = pnew;      //add to the tail
  127.     }
  128.     pq->prear = pnew;                 //the new node is the last one
  129.     pq->ucItemCnt++;                  //increase the item counter
  130.     return TRUE;
  131. }
  132. /******************************************************************************
  133. **Function Name     : CopyToNode
  134. **Input Parameters  : Queue_Type *pq -> the queue base pointer
  135. **                    ITEM item      -> the value of item
  136. **Output Parameters : none
  137. **Returned Value    : none
  138. **Descrition        : initialize queue
  139. ******************************************************************************/
  140. __STATIC_INLINE void CopyToItem(ITEM *pitem,Node_Type *pq)
  141. {
  142.     *pitem = pq->item;
  143. }
  144. /******************************************************************************
  145. **Function Name     : DeQueue
  146. **Input Parameters  : Queue_Type *pq -> the queue base pointer
  147. **                    ITEM item      -> the value of item
  148. **Output Parameters : none
  149. **Returned Value    : 1 -> dequeue successful
  150. **                    0 -> dequeue failure
  151. **Descrition        : initialize queue
  152. ******************************************************************************/
  153. BOOL DeQueue(Queue_Type *pq,ITEM *pitem)
  154. {
  155.     Node_Type *pt;
  156.    
  157.     if(QueueIsEmpty(pq))              //the queue is empty ?
  158.     {
  159.         return FALSE;                 
  160.     }
  161.     CopyToItem(pitem,pq->pfront);     //copy the node to item
  162.     pt = pq->pfront;                  //get the basic point of the first node
  163.     pq->pfront = pq->pfront->pnext;   //now the next node is the first node
  164.     free(pt);                         //free the space
  165.     pq->ucItemCnt--;            
  166.     if(0 == pq->ucItemCnt)            //the queue is empty?
  167.     {
  168.         pq->prear = NULL;
  169.     }
  170.     return TRUE;
  171. }
  172. /******************************************************************************
  173. **Function Name     : EmptyTheQueue
  174. **Input Parameters  : Queue_Type *pq -> the queue base pointer
  175. **                    ITEM item      -> the value of item
  176. **Output Parameters : none
  177. **Returned Value    : 1 -> dequeue successful
  178. **                    0 -> dequeue failure
  179. **Descrition        : initialize queue
  180. ******************************************************************************/
  181. void EmptyTheQueue(Queue_Type *pq)
  182. {
  183.     ITEM dummy;
  184.     while(!(QueueIsEmpty(pq)))
  185.     {
  186.         DeQueue(pq,&dummy);
  187.     }
  188. }

  189. #ifndef _queue_h
  190. #define _queue_h

  191. #include "type.h"
  192. #include "string.h"
  193. #include "stdlib.h"
  194. /*==============================================================================
  195. **                                                                            **
  196. **                          IO DEFINITION                                     **
  197. **                                                                            **
  198. ==============================================================================*/





  199. /*==============================================================================
  200. **                                                                            **
  201. **                          CONSTANT DEFINITION                               **
  202. **                                                                            **
  203. ==============================================================================*/
  204. #define QUEUE_SIZE 10


  205. /*==============================================================================
  206. **                                                                            **
  207. **                          TYPEDEF DEFINITION                                **
  208. **                                                                            **
  209. ==============================================================================*/
  210. typedef unsigned char ITEM ;
  211. typedef struct node{
  212.     ITEM        item;
  213.     struct node *pnext;
  214. }Node_Type;

  215. typedef struct queue{
  216.     Node_Type *pfront;     //指向队列首的指针
  217.     Node_Type *prear;      //指向队列尾的指针
  218.     UINT8     ucItemCnt;     //队列中项目的个数
  219. }Queue_Type;

  220.    






  221. /*==============================================================================
  222. **                                                                            **
  223. **                          FUNCTION PROTOTYPES                               **
  224. **                                                                            **
  225. ==============================================================================*/
  226. void  QueueInit(Queue_Type *pq);
  227. BOOL  QueueIsFull(const Queue_Type *pq);
  228. BOOL  QueueIsEmpty(const Queue_Type *pq);
  229. UINT8 QueueItemCnt(const Queue_Type *pq);
  230. BOOL  EnQueue(Queue_Type *pq,ITEM item);
  231. BOOL  DeQueue(Queue_Type *pq,ITEM *pitem);
  232. void  EmptyTheQueue(Queue_Type *pq);
  233.             
  234. #endif
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入25汤圆

2
发表于 2013-5-16 09:25:15 | 只看该作者
MASK,收藏了,慢慢看

出0入0汤圆

3
发表于 2013-5-16 10:03:00 | 只看该作者
有时间再静下心来看看

出0入0汤圆

4
发表于 2013-5-24 18:10:08 | 只看该作者
静下心,以后看。

出0入0汤圆

5
发表于 2013-5-26 08:47:31 | 只看该作者
beautiful!!!!

出0入0汤圆

6
发表于 2013-7-31 17:42:10 | 只看该作者
mark!!!!

出0入0汤圆

7
发表于 2013-8-2 17:29:59 | 只看该作者
MARK.

            

出0入0汤圆

8
发表于 2013-8-12 14:54:22 来自手机 | 只看该作者
mark……
顶一个…

出0入0汤圆

9
发表于 2013-8-30 19:57:10 | 只看该作者
mark..........

出0入0汤圆

10
发表于 2013-8-31 14:11:13 | 只看该作者
这两本书有讲,代码用这种任务时调用,效率挺高的

出0入0汤圆

11
发表于 2013-9-21 13:21:40 | 只看该作者
mark!!!

出0入0汤圆

12
发表于 2013-11-14 14:56:58 | 只看该作者
好样的...........

出0入0汤圆

13
发表于 2013-11-14 15:25:06 | 只看该作者
学习~~~~

出0入0汤圆

14
发表于 2013-11-14 15:28:41 | 只看该作者
代码风格不错,学习了

出0入0汤圆

15
发表于 2014-2-25 06:22:51 来自手机 | 只看该作者
mask, 谢谢分享

出0入0汤圆

16
发表于 2014-2-25 06:53:21 来自手机 | 只看该作者
代码看着不错,谢谢了

出0入0汤圆

17
发表于 2014-2-25 07:37:51 | 只看该作者
Linux下的KFIFO. 限制是缓存区大小必须为2的整数次幂.
在Linux内核中, 程序会将用户输入的缓存区自动圆整到2的整数次幂.

  1. /**
  2.   ******************************************************************************
  3.   * @file    kfifo.c
  4.   * @author  DevLabs
  5.   * @version V0.1
  6.   * @date    2013-12-30 20:44
  7.   * @brief
  8.   ******************************************************************************
  9.   * @attention
  10.   *
  11.   * <br />Copyright 2013
  12.   * <br />http://www.DevLabs.cn
  13.   *
  14.   * <h2><center>&copy; COPYRIGHT 2013 DevLabs </center></h2>
  15.   ******************************************************************************
  16.   */

  17. /* Includes ------------------------------------------------------------------*/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdint.h>

  21. /* Private typedef -----------------------------------------------------------*/
  22. typedef struct
  23. {
  24.     uint8_t *buffer;        //!< 缓存区指针
  25.     uint32_t size;          //!< 缓存区大小
  26.     uint32_t in;            //!< 写偏移(in % size)
  27.     uint32_t out;           //!< 读偏移(out % size)
  28. } KFIFO;

  29. /* Private define ------------------------------------------------------------*/
  30. #ifndef     BOOL
  31.     #define     BOOL    unsigned int
  32. #endif

  33. #ifndef     FALSE
  34.     #define     FALSE   (0)
  35. #endif

  36. #ifndef     TRUE
  37.     #define     TRUE    (!FALSE)
  38. #endif

  39. #define     FIFO_BUF_SIZE   32

  40. /* Private macro -------------------------------------------------------------*/
  41. #define     MIN(a, b)   ((a) < (b) ? (a) : (b))
  42. #define     MAX(a, b)   ((a) < (b) ? (b) : (a))

  43. /* Private variables ---------------------------------------------------------*/
  44. /* Private function prototypes -----------------------------------------------*/
  45. /* Private functions ---------------------------------------------------------*/

  46. /**
  47. * @brief  判断一个数是否为2的整数次幂
  48. *
  49. * @param  n 要判断的数
  50. *
  51. * @retval TRUE
  52. * @retval FALSE
  53. */
  54. BOOL is_power_of_2(unsigned long n)
  55. {
  56.     return (n != 0 && ((n & (n - 1)) == 0));
  57. }

  58. /**
  59. * @brief  fifo初始化
  60. *
  61. * @param  fifo 要初始化的fifo
  62. * @param  buffer fifo的缓冲区
  63. * @param  size  fifo缓冲大小
  64. *
  65. * @retval TRUE 初始化成功
  66. * @retval FALSE 初始化失败
  67. */
  68. BOOL kfifo_init(KFIFO *fifo, uint8_t *buffer, uint32_t size)
  69. {
  70.     if (!is_power_of_2(size))
  71.     {
  72.         printf("file: %s, line: %d size must be power of 2!", __FILE__, __LINE__);

  73.         return FALSE;
  74.     }

  75.     fifo->buffer = buffer;
  76.     fifo->size = size;
  77.     fifo->in = fifo->out = 0;

  78.     return TRUE;
  79. }


  80. /**
  81. * @brief  向FIFO写入数据
  82. *
  83. * @param  fifo 待写入的FIFO
  84. * @param  buffer 待写入的数据
  85. * @param  len 待写入的数据长度
  86. *
  87. * @return 实际写入的数据
  88. */
  89. uint16_t kfifo_put(KFIFO *fifo, uint8_t *buffer, uint32_t len)
  90. {
  91.     uint32_t l;

  92.     len = MIN(len, fifo->size - (fifo->in - fifo->out));
  93.     l = MIN(len, fifo->size - (fifo->in & (fifo->size - 1)));

  94.     memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
  95.     memcpy(fifo->buffer, buffer + l, len - l);

  96.     fifo->in += len;

  97.     return len;
  98. }



  99. /**
  100. * @brief  从FIFO取出数据
  101. *
  102. * @param  fifo 要取出数据的FIFO
  103. * @param  buffer 存储取出数据的缓存
  104. * @param  len 要取出数据的长度
  105. *
  106. * @return 实际取出的数据长度
  107. */
  108. uint16_t kfifo_get(KFIFO *fifo, uint8_t *buffer, uint32_t len)
  109. {
  110.     uint32_t l;

  111.     len = MIN(len, fifo->in - fifo->out);
  112.     l = MIN(len, fifo->size - (fifo->out & (fifo->size - 1)));

  113.     memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
  114.     memcpy(buffer + l, fifo->buffer, len - l);

  115.     fifo->out += len;

  116.     return len;
  117. }


  118. /**
  119. * @brief  打印缓冲区
  120. *
  121. * @param  buf 缓冲区指针
  122. * @param  len 要打印的数据长度
  123. */
  124. void put_buf(const uint8_t *buf, uint32_t len)
  125. {
  126.     while (len != 0)
  127.     {
  128.         putchar(*buf);
  129.         len--;
  130.         buf++;
  131.     }
  132.     printf("\n");

  133.     return;
  134. }


  135. int main(void)
  136. {
  137.     KFIFO kfifo;
  138.     uint32_t i;
  139.     uint8_t fifo_buf[FIFO_BUF_SIZE];
  140.     uint8_t get_buf[FIFO_BUF_SIZE];
  141.     uint8_t *str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  142.     uint8_t *str2 = "abcdefghijklmhopqrstuvwxyz";

  143.     for (i = 0; i < FIFO_BUF_SIZE; i++)
  144.     {
  145.         fifo_buf[i] = '*';
  146.     }

  147.     for (i = 0; i < FIFO_BUF_SIZE; i++)
  148.     {
  149.         get_buf[i] = '#';
  150.     }

  151.     // FIFO初始化
  152.     kfifo_init(&kfifo, fifo_buf, FIFO_BUF_SIZE);
  153.     // 向FIFO写入26个数据
  154.     kfifo_put(&kfifo, str1, strlen(str1));

  155.     printf("fifo_buf: ");
  156.     put_buf((const uint8_t *)&fifo_buf, FIFO_BUF_SIZE);

  157.     // 取出10个数据
  158.     kfifo_get(&kfifo, get_buf, 10);

  159.     printf(" get_buf: ");
  160.     put_buf((const uint8_t *)&get_buf, FIFO_BUF_SIZE);

  161.     // 这次写入会使FIFO回绕
  162.     kfifo_put(&kfifo, str2, strlen(str2));

  163.     printf("fifo_buf: ");
  164.     put_buf((const uint8_t *)&fifo_buf, FIFO_BUF_SIZE);

  165.     return 0;
  166. }


  167. /******************* (C) COPYRIGHT 2013 DevLabs **********END OF FILE**********/

复制代码

出0入0汤圆

18
发表于 2014-2-25 08:44:51 | 只看该作者
这种代码风格,看着很舒服!

出0入0汤圆

19
发表于 2014-2-25 08:49:01 | 只看该作者
MARK  以后也许会用上。

出0入0汤圆

20
发表于 2014-2-25 09:08:52 | 只看该作者
标记一下,需要学习

出0入0汤圆

21
发表于 2014-2-25 09:51:13 | 只看该作者
mark一下,日后再看!

出0入0汤圆

22
发表于 2014-2-25 10:26:34 | 只看该作者
收藏,看着很清晰

出0入0汤圆

23
发表于 2016-4-1 10:25:20 | 只看该作者
DevLabs 发表于 2014-2-25 07:37
Linux下的KFIFO. 限制是缓存区大小必须为2的整数次幂.
在Linux内核中, 程序会将用户输入的缓存区自动圆整到 ...

还是Linux的代码 看着舒服

出0入0汤圆

24
发表于 2016-4-1 10:26:46 | 只看该作者
感谢分享

出0入0汤圆

25
发表于 2016-4-1 10:29:34 | 只看该作者
mask 一下,有空再来细品

出0入10汤圆

26
发表于 2016-4-22 14:02:28 | 只看该作者
收藏,静心细看

出0入0汤圆

27
发表于 2016-4-22 14:05:45 | 只看该作者
楼主厉害!

出0入0汤圆

28
发表于 2016-4-22 15:38:27 | 只看该作者
看风格有点像傻孩子的啊?是不?

出0入0汤圆

29
发表于 2016-4-22 15:45:50 | 只看该作者
Kfifo 的代码简单明了。我想用c++实现,KFIFO 这结构体里边的buffer 对应不同的类型,比如char   int  struct 等等。请高人指导下!

出0入0汤圆

30
发表于 2016-4-22 17:57:56 | 只看该作者
第一种就是普通的双向链表吧,Kfifo是效率比较高的FIFO实现,这种实现方法还有用于ringbuff的,特点就是判断首尾指针是否碰到非常快捷。而且这种方式用在两个线程一个读一个写的环境中,可以不用加任何锁或者同步。

出0入0汤圆

31
发表于 2016-7-6 20:52:17 | 只看该作者
mark                        

出0入0汤圆

32
发表于 2016-7-12 08:53:19 | 只看该作者
收藏了,学习下

出0入0汤圆

33
发表于 2016-11-3 17:32:42 | 只看该作者
MASK,收藏了,慢慢看

出0入0汤圆

34
发表于 2016-12-1 13:58:46 | 只看该作者
粗略看了一下,没看懂。先MARK一下,有空慢慢看。

出0入0汤圆

35
发表于 2016-12-1 17:04:43 | 只看该作者
先MARK一下,有空慢慢看

出0入0汤圆

36
发表于 2016-12-2 17:34:08 | 只看该作者
MARK,谢谢分享

出0入0汤圆

37
发表于 2017-7-21 07:32:03 | 只看该作者
最近有用 收藏慢慢看

出0入0汤圆

38
发表于 2018-5-26 16:59:04 | 只看该作者
mark 谢谢楼主分享!

出0入0汤圆

39
发表于 2018-5-27 14:39:25 | 只看该作者
MASK,收藏了,慢慢看

出0入0汤圆

40
发表于 2023-1-8 15:59:23 | 只看该作者
mark, 最近有用
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 01:49

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表