C语言

it2024-11-14  3

循环队列

头文件queue.h源文件queue.c函数调用方法 Note:

  本代码用C语言编写,已经用于实际的项目中,在队列的申请过程中,也进行错误判断,可通过错误判断函数中枚举类型的值来判断,队列哪个过程出现错误。此外对于使用c++的朋友,本人建议将该数据结构封装成一个类来使用,将其操作函数变成成员函数,变量改为私有变量。(并发操作过程中,应给队列加锁,如在结构体或类中定义锁机制)


头文件queue.h

#ifndef _QUEUE_H #define _QUEUE_H typedef unsigned char Q_U8Data; typedef unsigned short Q_U16Data; typedef unsigned int Q_U32Data; typedef struct _tQueueInfo { Q_U8Data *pDataBuf; Q_U16Data MaxQueueSize; Q_U32Data Front; Q_U32Data Rear; Q_U32Data QueueLength; }QueueInfo, *pQueueInfo; void Queue_Init(pQueueInfo pQInfo,Q_U16Data MaxSize); void Queue_ClearData(pQueueInfo pQInfo); Q_U32Data Queue_GetLength(pQueueInfo pQInfo); void Queue_AddData(Q_U8Data *pSrcBuf, pQueueInfo pQInfo, Q_U16Data DataCnt); void Queue_AddOneData(Q_U8Data SrcData, pQueueInfo pQInfo); void Queue_GetData(Q_U8Data *pBuf, pQueueInfo pQInfo, Q_U32Data DataCnt); void Queue_GetOneData(Q_U8Data *DestData, pQueueInfo pQInfo); void Queue_DummyRead(pQueueInfo pQInfo,Q_U16Data DataCnt); #endif

源文件queue.c

#include "queue.h" #include "malloc.h" #include "delay.h" #include <stdio.h> #include <string.h> #include "comm.h" //*****************************错误处理部分***************** enum ERROR_CODE { ERR_QUEUE_MALLOC_FAIL = 1, ERR_QUEUE_DATA_FULL, ERR_QUEUE_DATA_NULL, ERR_MALLOC_FAIL, ERR_COMM_MALLOC_FAIL, ERR_NAND_MALLOC_FAIL, ERR_UPAN_WRITE_FAIL, ERR_UPAN_CLOSE_FAIL, ERR_UPAN_OPEN_FAIL, ERR_NAND_BADBLOCK_FULL, ERR_MAINPROC_FAIL, ERR_BBM_MALLOC_FAIL, }; void ErrorHandle(U32 u32ErrCode) { while(1) { // Led_Error(); printf("error code = %x \r\n", u32ErrCode); DelayMs(500); // COMM_WriteCmd(COMM_MAINCMD_CONTROL,COMM_SUBCMD_CONTROL_ERROR); DelayMs(500); } } //*****************************错误处理部分***************** void Queue_Init(pQueueInfo pQInfo,Q_U16Data MaxSize) { Q_U8Data *pBuf; pBuf = mymalloc(SRAMIN,MaxSize); if(pBuf == NULL) { ErrorHandle(ERR_QUEUE_MALLOC_FAIL); } pQInfo->pDataBuf = pBuf; pQInfo->MaxQueueSize = MaxSize; pQInfo->Front = 0; pQInfo->Rear = 0; pQInfo->QueueLength = 0; } void Queue_ClearData(pQueueInfo pQInfo) { pQInfo->Front = 0; pQInfo->Rear = 0; pQInfo->QueueLength = 0; } Q_U32Data Queue_GetLength(pQueueInfo pQInfo) { Q_U32Data Ret; Ret = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize); //取余是当Real < Front时 return Ret; } /******************数据空间************************ | ---------- | ------------- | ---------------- | 0 Front Rear 256 该数据空间大小申请的是256,数据以头尾相连的方式进行存取, 函数首先判断的是存入的空间是否足够,即除开front--rear段, 剩下的空间是否足够存入buf,其次开始存入时,先按顺序存入 在rear到256的数据段,最后存入的是0--front的数据段。 ****************************************************/ void Queue_AddData(Q_U8Data *pAddBuf, pQueueInfo pQInfo, Q_U16Data DataCnt) { Q_U16Data u16QCnt; Q_U16Data u16QLen; u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize); if(u16QLen + DataCnt > pQInfo->MaxQueueSize)//判断是否超出256 { while(1) { printf("Queue Size is overflow!In src:%s Line:%d\r\n",__FILE__,__LINE__); DelayMs(100); } } else { u16QCnt = (pQInfo->MaxQueueSize) - pQInfo->Rear;//计算Rear后可存空间(剩余的就是Front前可存空间) if(u16QCnt >= DataCnt)//front--rear段足够存下 { memcpy(pQInfo->pDataBuf + pQInfo->Rear, pAddBuf, DataCnt); } else//分两段存,先是front--rear段,然后是0--front段 { memcpy(pQInfo->pDataBuf + pQInfo->Rear, pAddBuf, u16QCnt); memcpy(pQInfo->pDataBuf, pAddBuf + u16QCnt, DataCnt - u16QCnt); } pQInfo->Rear = (pQInfo->Rear + DataCnt)%(pQInfo->MaxQueueSize); pQInfo->QueueLength += DataCnt; } } void Queue_GetData(Q_U8Data *pSaveBuf, pQueueInfo pQInfo, Q_U32Data DataCnt) { Q_U16Data u16QCnt; Q_U16Data u16QLen; u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize); if(u16QLen < DataCnt) { while(1) { printf("Queue is not enough data to read!In src:%s Line:%d\r\n",__FILE__,__LINE__); DelayMs(100); } } else { u16QCnt = (pQInfo->MaxQueueSize) - pQInfo->Front; if(u16QCnt >= DataCnt) { memcpy(pSaveBuf, pQInfo->pDataBuf + pQInfo->Front, DataCnt); } else { memcpy(pSaveBuf, pQInfo->pDataBuf + pQInfo->Front, u16QCnt); memcpy(pSaveBuf + u16QCnt, pQInfo->pDataBuf, DataCnt - u16QCnt); } } pQInfo->Front = (pQInfo->Front + DataCnt)%(pQInfo->MaxQueueSize); pQInfo->QueueLength -= DataCnt; } //丢弃数据函数 //在队列里移动Front,模拟读出的过程移动Front,但是没有Buf接收,形成丢弃 void Queue_DummyRead(pQueueInfo pQInfo,Q_U16Data DataCnt) { Q_U16Data u16QLen; u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize); if(u16QLen < DataCnt) { while(1) { printf("Queue is not enough data to read!In src:%s Line:%d\r\n",__FILE__,__LINE__); DelayMs(100); } else { pQInfo->Front = (pQInfo->Front + DataCnt)%(pQInfo->MaxQueueSize); pQInfo->QueueLength -= DataCnt; } }

函数调用方法

QueueInfo Q_UART1Info; //定义一个队列结构体 Queue_Init(&Q_UART1Info, 256); //初始化队列结构体,并设置其最大为256个字节 if(Queue_GetLength(&Q_UART1Info) > 100) { //队列中的数据长度 > 100个字节时才进行处理 Queue_GetData(...); }
最新回复(0)