概述
心血来潮加上上班摸鱼,写了个队列,感觉还是比较通用的吧,先看头文件:
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <stdint.h>
struct queue_handle_t
{
//队列的名字
char name[32];
//创建内存地址的起始位置
void *start_addr;
//末尾地址
void *finish_addr;
//指向队首成员
void *head_ptr;
//指向队尾成员
void *tail_ptr;
//队列中最大成员数量
uint32_t max_member;
//队列中单个成员的尺寸
uint32_t member_size;
//当前成员数量
uint32_t member_num;
//是否被初始化
uint16_t is_init;
uint16_t is_creat;
//内部用到的函数
int (*internal_print)(const char *, ...);
void *(*internal_malloc)(size_t);
void (*internal_free)(void *);
};
/*
* 初始化队列句柄
* @param:
* handle:队列句柄
* @note:
* 在创建队列 creat_queue() 前调用
* @return:
* 0是成功
*/
int init_queue(struct queue_handle_t *handle,
void *(*malloc_func)(size_t),
void (*free_func)(void *),
int (*log_func)(const char *format, ...));
/*
* 创建队列
* @param:
* handle:队列句柄
* name:队列的名字
* max_member:队列元素个数的最大数量
* size:每个元素的尺寸
* @return:
* 0是成功
*/
int creat_queue(struct queue_handle_t *handle, const char *name, const uint32_t max_member, const uint32_t size);
/*
*删除队列
*@param:
* handle:队列句柄
*/
int delete_queue(struct queue_handle_t *handle);
/*
* 入队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* @return:
* 0是成功
*/
int entern_queue(struct queue_handle_t *handle, const void *data_ptr);
/*
* 出队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* @return:
* 0是成功
* @note:
* 会删除队首元素
*/
int read_queue(struct queue_handle_t *handle, void *data_ptr);
/*
* 出队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* @return:
* 0是成功
* @note:
* 不会删除队首元素
*/
int peek_queue(struct queue_handle_t *handle, void *data_ptr);
/*
* 读取队尾的元素
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* @return:
* 0是成功
* @note:
*/
int read_tail_queue(struct queue_handle_t *handle, void *data_ptr);
#endif
相信有的帅批看完头文件已经知道我是咋写的了,源文件:
//缺点:一个队列里的每个元素只能是大小一样的,在队列初始时就决定了队列的大小
#include "queue.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//提高这个值可以稍微提高一些安全性(避免空指针引用啥的)
#define QUEUE_SAFE_LEVEL 0
#define QUEUE_INIT_FLG 0XF1a5
#define QUEUE_CREAT_FLG 0XF1a5
#define QUEUE_LOG(fmt,arg...) if(handle->internal_print){handle->internal_print(fmt, ##arg);}
static inline int check_handle(struct queue_handle_t *handle)
{
#if QUEUE_SAFE_LEVEL >= 1
if (handle == NULL)
{
return -1;
}
if (handle->is_init != QUEUE_INIT_FLG)
{
return -2;
}
if (handle->internal_malloc == NULL || handle->internal_free == NULL)
{
return -3;
}
#endif
return 0;
}
/*
* 初始化队列句柄
* @param:
* handle:队列句柄
* @note:
* 在创建队列时 creat_queue() 前调用
* @return:
* 0是成功
*/
int init_queue(struct queue_handle_t *handle,
void *(*malloc_func)(size_t),
void (*free_func)(void *),
int (*log_func)(const char *format, ...))
{
if (handle == NULL || malloc_func == NULL || free_func == NULL)
{
return -1;
}
memset(handle, 0, sizeof(struct queue_handle_t));
handle->internal_malloc = malloc_func;
handle->internal_free = free_func;
handle->internal_print = log_func;
handle->is_init = QUEUE_INIT_FLG;
return 0;
}
/*
* 创建队列
* @param:
* handle:队列句柄
* name:队列的名字
* max_member:队列元素个数的最大数量
* size:每个元素的尺寸
* @return:
* 0是成功
*/
int creat_queue(struct queue_handle_t *handle, const char *name, const uint32_t max_member, const uint32_t size)
{
void *p_start;
uint32_t sum_size = max_member * size;
if (check_handle(handle))
{
return -1;
}
//判断队列是否被创建
if (handle->is_creat)
{
QUEUE_LOG("Warring:%s:%d:Queue %s May be Created Or Hnadle Not Init,New Queue Will Not be Createdn", __FUNCTION__, __LINE__, handle->name);
return -1;
}
//队列名字是否合法
if (strlen(name) <= 0 || strlen(name) >= 32)
{
QUEUE_LOG("Error:%s:%d:Queue Name Len Must More Than 0 But Less Than 32n", __FUNCTION__, __LINE__, handle->name);
return -1;
}
p_start = handle->internal_malloc(sum_size);
if (p_start == NULL)
{
QUEUE_LOG("Error:%s:%d:Queue Creat Failn", __FUNCTION__, __LINE__);
handle->start_addr = NULL;
return -1;
}
handle->start_addr = p_start;
handle->head_ptr = p_start;
handle->tail_ptr = p_start;
handle->max_member = max_member;
handle->member_size = size;
handle->member_num = 0;
handle->finish_addr = (uint8_t *)p_start + sum_size;
handle->is_creat = QUEUE_CREAT_FLG;
strcpy(handle->name, name);
memset(handle->start_addr, 0, sum_size);
return 0;
}
/*
*删除队列
*@param:
* handle:队列句柄
*/
int delete_queue(struct queue_handle_t *handle)
{
if (check_handle(handle) || handle->start_addr == NULL)
{
QUEUE_LOG("Error:%s:%d:Queue Delete Failn", __FUNCTION__, __LINE__);
return -1;
}
handle->internal_free(handle->start_addr);
memset(handle, 0, sizeof(struct queue_handle_t));
handle->start_addr = NULL;
handle->finish_addr = NULL;
return 0;
}
/*
* 入队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* size:加入元素的大小
* @return:
* 0是成功
*/
int entern_queue(struct queue_handle_t *handle, const void *data_ptr)
{
if (check_handle(handle))
{
return -1;
}
//判断队列是否被创建
if (handle->start_addr == NULL)
{
QUEUE_LOG("Error:%s:%d:Queue Enter Fail,Maybe Not Creatn", __FUNCTION__, __LINE__);
return -1;
}
//判断元素数量是否达到上限
if (handle->member_num >= handle->max_member)
{
QUEUE_LOG("Error:%s:%d:Queue Enter Fail,Member Too Muchn", __FUNCTION__, __LINE__);
return -1;
}
//如果队尾指针已经来到内存边界,那么将尾指针指回开头
if (handle->tail_ptr >= handle->finish_addr)
{
handle->tail_ptr = handle->start_addr;
}
memcpy(handle->tail_ptr, data_ptr, handle->member_size);
handle->tail_ptr = (uint8_t *)handle->tail_ptr + handle->member_size;
handle->member_num++;
return 0;
}
/*
* 出队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* size:加入元素的大小
* @return:
* 0是成功
* @note:
* 会删除队首元素
*/
int read_queue(struct queue_handle_t *handle, void *data_ptr)
{
if (check_handle(handle))
{
return -1;
}
//判断元素数量是否大于0
if (handle->member_num <= 0)
{
QUEUE_LOG("Error:%s:%d:Queue Read Fail,Member Too Lessn", __FUNCTION__, __LINE__);
return -1;
}
//如果队首指针已经来到内存边界,那么将首指针指回开头
if (handle->head_ptr >= handle->finish_addr)
{
handle->head_ptr = handle->start_addr;
}
memcpy(data_ptr, handle->head_ptr, handle->member_size);
handle->head_ptr = (uint8_t*)handle->head_ptr + handle->member_size;
handle->member_num--;
return 0;
}
/*
* 出队
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* size:加入元素的大小
* @return:
* 0是成功
* @note:
* 不会删除队首元素
*/
int peek_queue(struct queue_handle_t *handle, void *data_ptr)
{
if (check_handle(handle))
{
return -1;
}
//判断元素数量是否大于0
if (handle->member_num <= 0)
{
QUEUE_LOG("Error:%s:%d:Queue Read Fail,Member Too Lessn", __FUNCTION__, __LINE__);
return -1;
}
//如果队首指针已经来到内存边界,那么将首指针指回开头
if (handle->head_ptr >= handle->finish_addr)
{
handle->head_ptr = handle->start_addr;
}
memcpy(data_ptr, handle->head_ptr, handle->member_size);
return 0;
}
/*
* 读取队尾的元素
* @param:
* handle:队列句柄
* data_ptr:加入的元素
* size:加入元素的大小
* @return:
* 0是成功
* @note:
*/
int read_tail_queue(struct queue_handle_t *handle, void *data_ptr)
{
if (check_handle(handle))
{
return -1;
}
//判断元素数量是否大于0
if (handle->member_num <= 0)
{
QUEUE_LOG("Error:%s:%d:Queue Read Fail,Member Too Lessn", __FUNCTION__, __LINE__);
return -1;
}
//指向最后一个元素
if (handle->tail_ptr <= handle->start_addr)
{
handle->tail_ptr = (uint8_t *)handle->finish_addr - handle->member_size;
}
else
{
handle->tail_ptr = (uint8_t*)handle->tail_ptr - handle->member_size;
}
memcpy(data_ptr, handle->tail_ptr, handle->member_size);
handle->member_num--;
return 0;
}
#if 0
struct a_t
{
uint64_t v1;
char v2;
uint64_t v3;
} a ,aa;
int main()
{
struct queue_handle_t h1;
uint16_t arr[5] = {1, 2, 3};
uint16_t read;
double count = 100000;
init_queue(&h1,malloc,free,printf);
creat_queue(&h1, "test", 100, sizeof(a));
printf("%ldn", sizeof(struct a_t));
for (double i = 0; i < count; i++)
{
a.v3 = i;
entern_queue(&h1, &a);
entern_queue(&h1, &a);
entern_queue(&h1, &a);
entern_queue(&h1, &a);
read_queue(&h1, &aa);
read_tail_queue(&h1, &aa);
read_tail_queue(&h1, &aa);
read_queue(&h1, &aa);
printf("%.10f%%r", 100 * (i / count));
fflush(stdout);
}
printf("n%dn", aa.v3);
return 0;
}
#endif
#undef QUEUE_INIT_FLG
#undef QUEUE_CREAT_FLG
#undef QUEUE_LOG
感觉单片机上也可以跑,什么,没有malloc?没事,用全局变量就可以了比如下面这样:
static char rnm_tq[100];
void *rnm_tq_malloc(size_t n)
{
return &rnm_tq[0];
}
反正也是个静态队列。
哦,对了,如果涉及多线程的话,该还是得自己加锁的
最后
以上就是神勇书包为你收集整理的相对通用的C语言队列的全部内容,希望文章能够帮你解决相对通用的C语言队列所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复