环形队列的通用实现方法

环形队列实现

1.说明:

完成一个通用型的环形队列,通用型表现为
(1)随时需要,随时创建;
(2)需要多大的队列长度、需要多大的单条消息长度都可以在创建时候指定(一次性申请的而非每有数据再申请);
(3)采用了顺序存储结构而不是链式存储结构,所以速度运行速度还可以。

2.需要的运行条件:

作者是在STM32F103里面运行的。

3.程序实现:

(1)结构体的抽象;

typedef struct _QUEUE{
	
	char name[10];	//队列名
	
	/* 操作函数 */
	int (* readData)(struct _QUEUE *queue,void * data);
	int (* writeData)(struct _QUEUE *queue,void * data);
	int (* getcnt)(struct _QUEUE *queue);		
	int (* is_full)(struct _QUEUE *queue);
	int (* is_empty)(struct _QUEUE *queue);
	int (* free)(struct _QUEUE *queue);
	
	int msg_len;			//队列长度
	int queue_len;			//队列有效长度
	int queue_max;			//队列最大长度
	int read,write;			//读写指针
	void *data;				//用户数据
	
}QUEUE,*qQUEUE;

操作函数和普通的环形队列基本上差不多。
这个数据结构能兼容所有的数据类型(包括用户自定义数据类型)的关键在于定义了指针类型的数据,这个指针所指向的地址就是存放用户的数据。
定义成(void *)是为了兼容所有的数据类型输入,不用去刻意转换,我们把转换放在函数内部完成。

4.所有代码展示:

.c文件:

#include "queue.h"
#include "stdlib.h"
#include "string.h"
#include "stdio.h"
/*
 *队列是否满
 */
static int queue_is_full(qQUEUE queue)
{
	return ( (queue->write+1)%queue->queue_max == queue->read );
}

/*
 *队列是否空
 */
static int queue_is_empty(qQUEUE queue)
{

	return ( queue->read == queue->write );
}

/*
 *读队列
 */
static int queue_read(qQUEUE queue,void * data)
{
	if( queue_is_empty(queue) )
	{
		/* 队空,无法读取 */
		DBG("Empty\r\n");
		return 1;
	}
	
	/* 类型转换,因为void *类型的指针偏移大小无法被编译器所识别,所以统一为char * */
	char *tmp = (char *)(&queue->data)+(queue->msg_len * queue->read);
		
	memcpy(data,tmp,queue->msg_len);	
	
	queue->read = ( queue->read+1)%queue->queue_max ;
	
	return 0;
}

/*
 *写队列
 */
static int queue_write(qQUEUE queue,void * data)
{
	if( queue_is_full(queue) )
	{	
		/* 队满,无法写入 */
		DBG("Full\r\n");
		return 1;
	}
	
	/* 类型转换,因为void *类型的指针偏移大小无法被编译器所识别,所以统一为char * */
	char *tmp = (char *)(&queue->data)+(queue->msg_len * queue->write);

	memcpy(tmp,data,queue->msg_len);
	
	queue->write = ( queue->write+1)%queue->queue_max;
	
	return 0;
}

/*
 *队列元素个数
 */
static int queue_get_cnt(qQUEUE queue)
{
	return ( (queue->write+queue->queue_max-queue->read)%queue->queue_max );
}

/*
 *队列内存释放
 */
static int queue_free(qQUEUE queue)
{
	free(queue);
	return 0;
}

/*
 *创建一个队列
 */
qQUEUE create_new_queue(int msg_len,int queue_len,char *name)
{
	/* 分配内存 */
	
	/* 计算方法:
			队列的有效长度 = 队列最大长度 - 1
			内存总长度 = 单消息长度*(队列最大长度)+ QUEUE结构体长度 - 1条单消息长度
	
			即,内存总长度 = 单消息长度*(队列的有效长度)+ QUEUE结构体长度
	*/
	int q_len = msg_len*(queue_len)+sizeof(QUEUE);
	qQUEUE q 	= malloc(q_len);
	
	/* 创建一个队列 */
	if(!q)
	{
		DBG("q NULL\r\n");
		return NULL;
	}
	
	/* 赋值 */
	q->write = q->read = 0;
	q->msg_len 		= msg_len;
	q->queue_len 	= queue_len;
	q->queue_max	=	queue_len+1;
	strcpy(q->name,name);
	
	/* 函数调用 */
	q->readData = queue_read;
	q->writeData= queue_write;
	q->getcnt		=	queue_get_cnt;
	q->is_empty	=	queue_is_empty;
	q->is_full	=	queue_is_full;
	q->free			= queue_free;
	
	return q;
}

.h文件

#ifndef __QUEUE__H_

#define __QUEUE__H_

#define DBG printf

/* 定义一个队列 */
typedef struct _QUEUE{
	
	char name[10];	//队列名
	
	/* 操作函数 */
	int (* readData)(struct _QUEUE *queue,void * data);
	int (* writeData)(struct _QUEUE *queue,void * data);
	int (* getcnt)(struct _QUEUE *queue);		
	int (* is_full)(struct _QUEUE *queue);
	int (* is_empty)(struct _QUEUE *queue);
	int (* free)(struct _QUEUE *queue);
	
	int msg_len;				//队列长度
	int queue_len;			//队列有效长度
	int queue_max;			//队列最大长度
	int read,write;			//读写指针
	void *data;	
	
}QUEUE,*qQUEUE;

qQUEUE create_new_queue(int msg_len,int queue_len,char *name);

#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值