C语言数据结构———循环队列(数组实形式用宏定义方式实现)
意图目的
使用宏定义方式来实现循环队列的效率比较高。
一、数据类型定义
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef unsigned long long int u64;
typedef signed char s8;
typedef signed short int s16;
typedef signed int s32;
typedef signed long long int s64;
二、队列结构体定义
#define QUEUE_SIZE 200//队列大小
typedef struct
{
u16 usFront; //队首
u16 usRear; //队尾
u8 ubDatBase[QUEUE_SIZE]; //基地址
}Queue_TypeDef, * pQueue_TypeDef;
三、操作队列的函数
/********************************************************************************
* 1. vQueueInit() : 队列初始化。队首和队尾为零
* 2. usQueueSize() : 获取队列的大小。数据存储空间
* 3. ubQueueIsFull() : 判断队列是否已满。已满(1),未满(0)
* 4. ubQueueIsEmpty() : 判断队列是否为空。为空(1),非空(0)
* 5. ubQueueClear() : 清空队列。队首和队尾为零
* 6. ubQueueWrite() : 向队列写入数据。向队尾指向的位置写入数据,队尾指向下一个写入数据位置
* 7. ubQueueRead() : 从队列读取数据。从队首指向的位置读取数据,队首指向下一个读取数据位置
* 8. ubQueueLen() : 获取队列使用长度。队列最大使用长度 = 队列大小 - 1
* 9. ubQueueMove() : 从队列中移除数据。忽略此时队首位置指向的数据,队首指向下一个读取数据位置
* 10. ubQueuePost() : 获取队列位置。返回此时队首和队尾指向的位置
* 11. ubQueueGet() : 获取队列中指定位置数据。以队首指向的位置为起始获取指定位置数据,
* 12. ubQueuePush() : 向队列写入数据。队列已满时先从队列中移除数据,在写入数据
*********************************************************************************/
#define vQueueInit(q) (q.usFront = q.usRear = 0)
#define usQueueSize(q) (sizeof(q.ubDatBase)/sizeof(q.ubDatBase[0])) //队列大小
#define ubQueueIsFull(q) ((((q.usRear + 1) % usQueueSize(q)) == q.usFront) ? 1 : 0) //队列是否满
#define ubQueueIsEmpty(q) ((q.usRear == q.usFront) ? 1 : 0) //队列是否空
#define ubQueueClear(q) (q.usRear = q.usFront = 0) //清空队列
#define ubQueueWrite(q, d) (ubQueueIsFull(q) ? 0 : ((q.ubDatBase[q.usRear] = d), (q.usRear = ((q.usRear + 1) % usQueueSize(q))), 1)) //向队列中写入数据
#define ubQueueRead(q, d) (ubQueueIsEmpty(q) ? 0 : ((d = q.ubDatBase[q.usFront]), (q.usFront = ((q.usFront + 1) % usQueueSize(q))), 1)) //从队列中读取数据
#define ubQueueLen(q) ((q.usRear - q.usFront + usQueueSize(q)) % usQueueSize(q)) //获取队列使用大小
#define ubQueueMove(q) (ubQueueIsEmpty(q) ? 0 : ((q.usFront = ((q.usFront + 1) % usQueueSize(q))), 1)) //删除数据
#define ubQueuePost(q, f, r) ((f = q.usFront), (r = q.usRear)) //获取队列位置
#define ubQueueGet(q, i) (ubQueueIsEmpty(q) ? 0 : (q.ubDatBase[(((q.usFront + i) == q.usRear) ? (q.usFront + i + 1) : (q.usFront + i)) % usQueueSize(q)])) //获取指定位置数据
#define ubQueuePush(q, d) (ubQueueIsFull(q) ? (ubQueueMove(q), ubQueueWrite(q, d)) : ubQueueWrite(q, d)) //向队列中写入数据
四、简单测试
int main(void)
{
Queue_TypeDef AppQueue;
vQueueInit(AppQueue);
ubQueueWrite(AppQueue, 10);
ubQueueWrite(AppQueue, 20);
ubQueueWrite(AppQueue, 30);
ubQueueWrite(AppQueue, 40);
ubQueueWrite(AppQueue, 50);
ubQueueWrite(AppQueue, 60);
printf("ubQueueLen %d\r\n", ubQueueLen(AppQueue));
printf("\r\n\r\nCompiler Date : %s %s", __DATE__, __TIME__);
while (1);
return 0;
}