当前位置:网站首页>queue的c实现
queue的c实现
2022-08-02 14:12:00 【Soonyang Zhang】
用c模拟实现C++中的queue。使用了环形缓冲区,只能向队列中放指针。纯属个人娱乐。
ringbuf.h
#ifndef RING_BUG_H_
#define RING_BUG_H_
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _RingBuf RingBuf;
struct _RingBuf{
void *start;
void *end;
int header;
int tail;
size_t used;
};
RingBuf *my_ring_buf_new(int cap);
void my_ring_buf_dtor(RingBuf *buf);
bool my_ring_buf_empty(RingBuf *buf);
bool my_ring_buf_has_space(RingBuf *buf);
void my_ring_buf_extend(RingBuf *buf);
void my_ring_buf_push_back(RingBuf *buf,void *ele);
void my_ring_buf_push_front(RingBuf *buf,void *ele);
void *my_ring_buf_front(RingBuf *buf);
void *my_ring_buf_back(RingBuf *buf);
void my_ring_buf_pop_front(RingBuf *buf);
void my_ring_buf_pop_back(RingBuf *buf);
typedef void (*ItorCb)(void *ele);
void my_ring_buf_itor(RingBuf *buf,ItorCb cb);
void* my_malloc(size_t size);
void my_free(void *ptr);
#ifdef __cplusplus
}
#endif
#endif // RING_BUG_H_
ringbuf.c
#include "ringbuf.h"
#define RING_BUG_CAP 2
void* my_malloc(size_t size){
void *ptr=0;
ptr=malloc(size);
if(ptr){
memset(ptr,0,size);
}
return ptr;
}
void my_free(void *ptr){
if(ptr){
free(ptr);
}
}
RingBuf *my_ring_buf_new(int cap){
int eles=0;
if(!cap){
eles=RING_BUG_CAP;
}
int allo=sizeof(RingBuf);
RingBuf *buf=0;
buf=my_malloc(allo);
void *content=0;
content=my_malloc(eles*sizeof(void*));
if(buf){
buf->start=content;
buf->end=content+eles*sizeof(void*);
buf->header=0;
buf->tail=0;
buf->used=0;
}
return buf;
}
void my_ring_buf_dtor(RingBuf *buf){
if(buf){
while(!my_ring_buf_empty(buf)){
void *ptr;
ptr=my_ring_buf_back(buf);
my_ring_buf_pop_back(buf);
my_free(ptr);
}
if(buf->start){
my_free(buf->start);
buf->start=0;
}
my_free(buf);
}
}
bool my_ring_buf_empty(RingBuf *buf){
bool ret=true;
if(buf&&buf->used){
ret=false;
}
return ret;
}
bool my_ring_buf_has_space(RingBuf *buf){
bool ret=false;
if(buf){
int cap=(buf->end-buf->start)/sizeof(void*);
if(buf->used<cap){
ret=true;
}
}
return ret;
}
void my_ring_buf_extend(RingBuf *buf){
void *old=buf->start;
int cap=(buf->end-buf->start)/sizeof(void*);
void *content=my_malloc(2*cap*sizeof(void*));
void **pos=(void**)content;
int i=0;
while(!my_ring_buf_empty(buf)){
void *ele=my_ring_buf_front(buf);
my_ring_buf_pop_front(buf);
pos[i]=ele;
i++;
}
buf->start=content;
buf->end=content+2*cap*sizeof(void*);
buf->tail=i-1;
buf->header=0;
buf->used=i;
my_free(old);
}
void my_ring_buf_push_front(RingBuf *buf,void *ele){
if(buf){
if(buf->used==0){
void *w_addr=buf->start+buf->header*sizeof(void*);
void **pos=(void**)(w_addr);
*pos=ele;
}else{
if(my_ring_buf_has_space(buf)){
}else{
my_ring_buf_extend(buf);
}
int cap=(buf->end-buf->start)/sizeof(void*);
buf->header=(buf->header+cap-1)%cap;
void *w_addr=buf->start+buf->header*sizeof(void*);
void **pos=(void**)(w_addr);
*pos=ele;
}
buf->used++;
}
}
void my_ring_buf_push_back(RingBuf *buf,void *ele){
if(buf){
if(buf->used==0){
void *w_addr=buf->start+buf->tail*sizeof(void*);
void **pos=(void**)(w_addr);
*pos=ele;
}else{
if(my_ring_buf_has_space(buf)){
}else{
my_ring_buf_extend(buf);
}
int cap=(buf->end-buf->start)/sizeof(void*);
buf->tail=(buf->tail+cap+1)%cap;
void *w_addr=buf->start+buf->tail*sizeof(void*);
void **pos=(void**)(w_addr);
*pos=ele;
//help me find a bug
//buf->tail=i-1;
//printf("off %d\n",(w_addr-buf->start)/sizeof(void*));
}
buf->used++;
}
}
void *my_ring_buf_front(RingBuf *buf){
void *ptr=0;
if(buf&&buf->used){
void **pos=(void**)(buf->start+buf->header*sizeof(void*));
ptr=*pos;
}
return ptr;
}
void* my_ring_buf_back(RingBuf *buf){
void *ptr=0;
if(buf&&buf->used){
void **pos=(void**)(buf->start+buf->tail*sizeof(void*));
ptr=*pos;
}
return ptr;
}
void my_ring_buf_pop_front(RingBuf *buf){
if(!buf){
return;
}
int cap=(buf->end-buf->start)/sizeof(void*);
if(buf->used==1){
}else{
buf->header=(buf->header+cap+1)%cap;
}
buf->used--;
}
void my_ring_buf_pop_back(RingBuf *buf){
if(!buf){
return;
}
int cap=(buf->end-buf->start)/sizeof(void*);
if(buf->used==1){
}else{
buf->tail=(buf->tail+cap-1)%cap;
}
buf->used--;
}
void my_ring_buf_itor(RingBuf *buf,ItorCb cb){
int total=buf->used;
int cap=(buf->end-buf->start)/sizeof(void*);
int i=0;
for(i=0;i<total;i++){
int offset=(buf->header+i+cap)%cap;
void **pos=(void**)(buf->start+offset*(sizeof(void*)));
cb(*pos);
}
}
main.c
#include <stdio.h>
#include "ringbuf.h"
typedef struct{
int a;
}MyValue;
void PrintEle(MyValue *v){
printf("itor %d\n",v->a);
}
int main(){
RingBuf *buf=my_ring_buf_new(0);
my_ring_buf_has_space(buf);
MyValue *v=0;
int i=0;
for(i=0;i<5;i++){
v=(MyValue*)my_malloc(sizeof(MyValue));
v->a=i+1;
my_ring_buf_push_back(buf,v);
printf("v %p\n",v);
}
for(i=5;i<10;i++){
v=(MyValue*)my_malloc(sizeof(MyValue));
v->a=i+1;
my_ring_buf_push_front(buf,v);
printf("v %p\n",v);
}
MyValue *ptr=0;
my_ring_buf_itor(buf,PrintEle);
for(i=0;i<5;i++){
ptr=my_ring_buf_back(buf);
my_ring_buf_pop_back(buf);
printf("ptr %p, %d\n",ptr,ptr->a);
my_free(ptr);
}
my_ring_buf_dtor(buf);
return 0;
}
边栏推荐
猜你喜欢
Software Testing Basics (Back)
Installation and configuration of Spark and related ecological components - quick recall
灵活的区域定义
EastWave应用:光场与石墨烯和特异介质相互作用的研究
第三十二章:二叉树的存储与遍历
动态规划理论篇
第三十三章:图的基本概念与性质
[System Design and Implementation] Flink-based distracted driving prediction and data analysis system
UnityAPI-Ray-Physics
光波导的入射耦合和出射耦合区域
随机推荐
MATLAB drawing command fimplicit detailed introduction to drawing implicit function graphics
计算机导论——数据库
奇技淫巧-位运算
光学好书推荐
第二十六章:二维数组
剑指offer:合并两个排序的链表
泰伯效应的建模
KiCad Common Shortcuts
Unity-存档与读档
Codeforces Round #605 (Div. 3)
二叉树的遍历:递归法/ 迭代法/ 统一迭代法(强QAQ)
锥形相位掩模的Talbot图像
Redis common interview questions
Unity中事件的3种实现方法
unity 和C# 一些官方优化资料
C#高级教程
golang-reflect-method-callback
剑指offer:数值的整数次方
冷读123
TCP的三次握手和四次挥手