循环队列 C语言

    本文地址:http://tongxinmao.com/Article/Detail/id/153

    #ifndef __fifo_h__

    #define __fifo_h__


    #include <stdint.h>

     


    typedef uint8_t ELETYPE;

    typedef volatile  struct queue   

    {  

        

        uint16_t front;    //指向队列第一个元素  

        uint16_t rear;    //指向队列最后一个元素的下一个元素  

        uint16_t  size; //循环队列的最大存储空间  

    ELETYPE *pBase;  

    }QUEUE,*PQUEUE; 


     QUEUE    extern printerQueue;

      QUEUE   extern piQueue;

      

    void CreateQueue(PQUEUE   Q,ELETYPE* buf,uint16_t maxsize);   

    uint8_t FullQueue(QUEUE    Q);  

    uint8_t EmptyQueue(QUEUE   Q);  

    uint16_t SizeQueue(QUEUE);


    uint8_t Enqueue(PQUEUE   Q, ELETYPE val);  

    uint8_t Dequeue(PQUEUE   Q, ELETYPE *val);  

     

    #endif






    #include "fifo.h"

    #include <stdio.h>



    #define RBSIZE 3000u



    static ELETYPE printerFifoBuf[RBSIZE];

    static ELETYPE piFifoBuf[RBSIZE];




    QUEUE     printerQueue;

    QUEUE     piQueue;


    void appFifoInit(void)

    {

    //fifo_init(&printerFifo,printerFifoBuf,RBSIZE);

    //fifo_init(&piFifo,piFifoBuf,RBSIZE);

    CreateQueue(&printerQueue,printerFifoBuf,RBSIZE);

    CreateQueue(&piQueue,piFifoBuf,RBSIZE);

    }




    /*********************************************** 

    Function: Create a empty stack; 

    ************************************************/  

    void CreateQueue(PQUEUE    Q,ELETYPE* buf,uint16_t maxsize)  

    {  

      

        Q->pBase=buf;   

        Q->rear=0;         //初始化参数  

        Q->front=0;  

     

        Q->size=maxsize;  

    }  

     

    uint8_t FullQueue(QUEUE   Q )

    {


    return (Q.rear)%Q.size==Q.front?1:0;

    }

       

    uint8_t EmptyQueue(QUEUE   Q)  

    {  

    return Q.rear==Q.front?1:0;

    }  

    uint8_t Enqueue(PQUEUE   Q, ELETYPE e)  

    {  

    //牺牲一个单元来区分队空和队满,入队时少用一个队列单元,这是一种较为普遍的 做法,约定以“队头指针在队尾指针的下一位置作为队满的标志”,

        if((Q->rear+1)%Q->size == Q->front) return 0; //队满

        Q->pBase[Q->rear]=e;

        Q->rear= (Q->rear+1)%Q->size; //队尾指针加 1 取模

        return 1;

        

    }  

      

    uint8_t Dequeue(PQUEUE   Q, ELETYPE *e)  

    {  

         if(Q->rear == Q->front) return 0;  //队空,报错

        *e=Q->pBase[Q->front];

        Q->front= (Q->front+1)%Q->size;  //队头指针加 1 取模

        return 1;

    }  


    uint16_t SizeQueue(QUEUE Q)

    {

    return (Q.rear-Q.front+Q.size)%Q.size;

    }




    //////////////////////////////////////////////////////////////////////////////

    如果使用单独变量记录队列长度,记住改写此变量一定要加临界保护!

    上一篇:USB逻辑分析仪68013 描述符
    下一篇:USB键盘描述符