当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
pygame draw arc
mysql学习总结 & 索引
Detailed introduction to drawing complex surfaces using the plot_surface command
Flink + sklearn - use JPMML implement flink deployment on machine learning model
7. Redis
unity-shader(入门)
仿真结果的格式&定制
第二十五章:一文掌握while循环
Introduction to MATLAB drawing functions ezplot explanation
光波导k域布局可视化(“神奇的圆环”)
随机推荐
模板系列-并查集
剑指offer:删除链表中重复的节点
LeetCode 2353. 设计食物评分系统 维护哈希表+set
pygame draw arc
深入理解Mysql索引底层数据结构与算法
LITESTAR 4D应用:室内植物照明模拟
golang gc垃圾回收
第三十三章:图的基本概念与性质
cmake configure libtorch error Failed to compute shorthash for libnvrtc.so
队列与栈
Unity-Ads广告插件
7.Redis
C#实现简单的计算器
Flink + sklearn - use JPMML implement flink deployment on machine learning model
Detailed explanation of Golang garbage collection mechanism
Codeforces Round #624 (Div. 3)
5. Transaction management
Redis common interview questions
4.发布帖子,评论帖子
2. Log out, log in state examination, verification code