C语言环形buffer
C语言环形数组
这是一个循环缓冲区,终于写完了,指针指来指取还是很麻烦的,稍微不注意就出错了
但是思路还是挺简单的,不过对于小白的我还是用了蛮久的时间的,关键是开始没有构思好
所以出了很多问题,这是最终版本,以后希望对自己有用,今天是2019.7.25 大吉大利的晚上,各位加油头文件
#include<stdio.h>
#include <string.h>
- 函数声明和环形存储区的建立,环形结构体指针的声明
- 在这里我将以数组作为环形存储区的存储区域,在这里也可以用动态申请内存,这里设置的类型也是int 这里可以根据自己需要更改数据类型,或者定义为一个void *类型,函数的功能就更强大了,不够后面要强制转换,我是个小白,所以以比较简单的想法写的,
#define RB_MAX_LEN 10
typedef unsigned int uint_t;
typedef struct
{uint_t sizerb;int *write;int *read;int *buffer;uint_t rw;//0代表已经读 1代表已经写,}rb_t;
rb_t rb;
static uint_t rbBuf[RB_MAX_LEN]; void creatrb(rb_t* rb);
- 初始化一个环形存储区域
void buff_init(void)
{rb.sizerb = RB_MAX_LEN; //定义长度rb.buffer = rbBuf; //将申请的一个空间的首地址给buffercreatrb(&rb); //然后运行创建函数}
- 创建一个环形存储区
void creatrb(rb_t* rb)
{if(NULL == rb) //判断指针是否为空{printf("fault\n");return;}rb->write= rb->buffer; //将读和写都指向首地址,创建完毕rb->read = rb->buffer;rb->rw =0;}
- 删除环形存储区
static void deleterb(rb_t *rb)
{if(NULL == rb){printf("error");}rb->write = NULL;rb->read = NULL;rb->buffer= NULL;rb->sizerb = 0;rb->rw =0;}
- 获取存储区域大小
static uint_t getrb_capacity(rb_t *rb)
{if(NULL == rb) //判断指针是否为空{printf("fault\n");return -1;}return rb->sizerb;}
- 获取存储区域可写字节的大小
static uint_t rbcanWrite(rb_t *rb)
{if(NULL == rb) //判断指针是否为空{printf("fault\n");return -1;}if(rb->write >rb->read){return getrb_capacity(rb)- (rb->write-rb->read);}else if((rb->write == rb->read)){if(0 ==rb->rw){return getrb_capacity(rb);}else{return 0;}}else if((rb->write < rb->read)){return (rb->read - rb->write);}}
- 获取环形缓冲区可读字节的大小
static uint_t rbcanRead(rb_t *rb)
{if(NULL == rb) //判断指针是否为空{printf("fault can read\n");return -1;}return getrb_capacity(rb)- rbcanWrite(rb);}
- 从环形存储区读取想要的数据个数
static uint_t rbRead(rb_t *rb,int *date,uint_t count)
{int cpysz = 0,r_end=0;if(NULL == rb) //判断指针是否为空{printf("fault\n");return -1;}if(NULL == date) //判断被放地址是否为空{printf("fault\n");return -1;}if(0==rbcanRead(rb)) //如果地址相同,并且在起点,表示无法读取没有数据{printf("fault\n");return -1;}//开始读取数据if(rb->write > rb->read) //读小余写{if(count>((rb->write) - (rb->read)))cpysz = ((rb->write) - (rb->read));elsecpysz = count;memcpy(date,rb->read,cpysz*sizeof(int));memset(rb->read,0,cpysz*sizeof(int));rb->read += cpysz;return cpysz;}else //读大于余写{r_end = rb->sizerb-(rb->read - rb->buffer);if(count>=rbcanRead(rb)){ cpysz = rbcanRead(rb);memcpy(date,rb->read,r_end*sizeof(int));memset(rb->read,0,r_end*sizeof(int));rb->rw=0; //表示读循环一次rb->read = rb->buffer;//date是个空类型memcpy(date+r_end,rb->read,(cpysz-r_end)*sizeof(int) );memset(rb->read,0,(cpysz-r_end)*sizeof(int));rb->read+=(cpysz-r_end);return cpysz;}else{cpysz = count;if(count < r_end){memcpy(date,rb->read,count*sizeof(int));memset(rb->read,0,count*sizeof(int));rb->read+=cpysz;}else{memcpy(date,rb->read,r_end*sizeof(int));memset(rb->read,0,r_end*sizeof(int));rb->rw=0; //表示读循环一次rb->read = rb->buffer;memcpy(date+r_end,rb->read,(count-r_end)*sizeof(int) );memset(rb->read,0,(count-r_end)*sizeof(int));rb->read+=(count-r_end); }return cpysz;}}}
- 向环形存储区写入数据
static uint_t rbWrite(rb_t *rb,int *date,uint_t count)
{int cpysz = 0,r_end=0;if(NULL == rb) //判断指针是否为空{printf("fault 1\n");return -1;}if(NULL == date) //判断被放地址是否为空{printf("fault 2\n");return -1;}if(0==rbcanWrite(rb)){printf("fault 3\n");return -1;}if(rb->write < rb->read) //写小于读{if(count>((rb -> read) - (rb->write))){cpysz = rb->read -rb->write;}else {printf("write\n");cpysz = count;}memcpy(rb->write,date,cpysz*sizeof(int));rb->write+= cpysz;return cpysz;}else //写大于等于读{r_end = rb->sizerb-(rb->write - rb->buffer);if(count > rbcanWrite(rb)){ cpysz = rbcanWrite(rb);memcpy(rb->write,date,r_end*sizeof(int));rb->rw=1; //表示写循环一次rb->write = rb->buffer;printf("mmp %d\n",r_end );memcpy(rb->write,date+r_end,(cpysz-r_end)*sizeof(int) );rb->write+=(rb->read-rb->buffer);return cpysz;}else {printf("this is write == \n\n\n");cpysz = count;if(count < r_end){memcpy(rb->write,date,count*sizeof(int));rb->write +=count;}else if(count >= r_end){memcpy(rb->write,date,r_end*sizeof(int));rb->rw=1; //表示写循环一次rb->write = rb->buffer;//rb->bufferprintf("mmp %d\n",r_end );memcpy(rb->write,date+r_end,(count-r_end)*sizeof(int) );rb->write += (count-r_end); }return cpysz;}}}
- 主函书进行初始化和调试,验证是否正确
int main(void)
{int i,a[50]={1,2,3,4,5,6,7,8,9,10,11},b[10]={0},a1[50]={99,88,77,66,55,22,33,22,11,00,82,54,56,22,1,346,45,15,15,1,6,26,15};unsigned int mmp=0;buff_init(); //创建一个环形存储区printf("开始创建环形缓冲区\n");printf("环形存储空间大小为 %d\n",getrb_capacity(&rb));printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));putchar('\n');putchar('\n');printf("准备给环形缓冲区内写入数据\n");for(i=0;i<10;i++)printf("not write rbBuff[%d]= %d\n",i,rbBuf[i]);mmp=rbWrite(&rb,a,10); //写入五个数据printf("成功写入 %d 个数据\n",mmp);printf("存储区域有自己数 = %d %d\n",sizeof(rbBuf),sizeof(size_t));for(i=0;i<10;i++)printf("写完数据 rbBuf[%d]= %d\n",i,rbBuf[i]);putchar('\n');putchar('\n');printf("查看空间\n");for(i=0;i<10;i++)printf("b[10] %d\n",*(b+i));printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));putchar('\n');putchar('\n');printf("begain to read\n");rbRead(&rb,b,3); //读取三个数据printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));for(i=0;i<10;i++)printf("b[10] %d\n",*(b+i));for(i=0;i<10;i++)printf("had write rbBuf[%d]= %d\n",i,rbBuf[i]);printf("再读数据\n");rbRead(&rb,b,2); //读取两个数据printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));for(i=0;i<10;i++)printf("b[10] %d\n",*(b+i));for(i=0;i<10;i++)printf("had write rbBuf[%d]= %d\n",i,rbBuf[i]);printf("\n\n再写数据\n");rbWrite(&rb,a1,20); //写入七个数据printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));for(i=0;i<10;i++)printf("had write rbBuf[%d]= %d\n",i,rbBuf[i]);putchar('\n');putchar('\n');printf("后面加再读数据\n");rbRead(&rb,b,11); //读取两个数据printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));for(i=0;i<10;i++)printf("b[10] %d\n",*(b+i));for(i=0;i<10;i++)printf("had write rbBuf[%d]= %d\n",i,rbBuf[i]);printf("canwrite %d\n",rbcanWrite(&rb));printf("canRead %d\n",rbcanRead(&rb));return 0;
}
C语言环形buffer相关推荐
- 环形buffer代码_为什么Buffer开发人员开源了他的代码
环形buffer代码 ``如果您要寻找开源的正式定义,您可能会偶然发现开源倡议董事会成员的这一提纲 . 如果您略过它,那么一定会发现自己觉得很符合的想法或概念. 从本质上讲,开放(和开放源代码)是关于 ...
- Go 语言 bytes.Buffer 源码详解之1
转载地址:Go 语言 bytes.Buffer 源码详解之1 - lifelmy的博客 前言 前面一篇文章 Go语言 strings.Reader 源码详解,我们对 strings 包中的 Reade ...
- c语言环形存储,环形缓存区bufferC语言实现
buffer[iput]=z; iput = addring(iput); n++; } else printf("Buffer is full\n"); } int main{v ...
- C语言--环形缓存区
环形缓存区工作原理 环形缓冲区是固定大小的缓冲区,工作原理就像内存是连续的且可循环.在生成和使用内存时,不需要将原来的数据全部清理掉,只要调整head/tail指针即可.当添加数据时,head指针前进 ...
- 环形buffer缓冲区
1 #include <stdio.h> 2 #include <string.h> 3 #include <malloc.h> 4 5 struct Circle ...
- C语言 FileStreaming buffer
setbuf void setbuf ( FILE * stream, char * buffer ); Set stream buffer 设置文件描述符的缓冲区大小 stream buffer是一 ...
- c语言环形赛跑程序,C语言实现简单龟兔赛跑
T代表乌龟,H代表兔子,使用随机数控制行走的步数 #include #include #include #include void main() { char rout[72]; char torto ...
- c语言环形队列用法,C语言,环形队列
什么是环形队列? 环形缓冲区是一个非常典型的数据结构,这种数据结构符合生产者,消费者模型,可以理解它是一个水坑,生产者不断的往里面灌水,消费者就不断的从里面取出水. 那就可能会有人问,既然需要灌水,又 ...
- c语言程序结构环形队列入队,C语言 环形队列
队列 :队列是一种先进先出的数据结构. 比如说 排队买票, 有一个售票口,最多能排30人,那么最大存储空间就是30人, 每当有1个新人过来排队,就会站在队尾,这就叫入队, 每当有1个人买到票了,就会离 ...
最新文章
- php gzipstream,c# – 在WebRequest中发送gzip数据?
- Java虚拟机详解----JVM常见问题总结
- EXC中时间控件的使用
- latex目录标题中间空一个字符
- Mobaxterm中使用git log报错/bin/busybox.exe less -R no such file or directory
- 生日快乐页面_宇智波佐助生日快乐!参与活动,豚豚为你送福利!
- CentOs7.3 搭建 Solr单机服务
- mysql merg引擎学习
- Nginx 安装配置
- restfulframework详解
- 电路布线问题的动态规划实现(java)
- SaaSBase:什么是零一裂变SCRM?
- 如何更改ElementUI组件的图标大小以及标签属性
- 【JavaWeb】如何优雅的实现第三方开放api接口签名(有状态/无状态)
- 怎么增加淘宝店铺标签权重
- 记事本文件管理器关联文本类
- SVG中的text文字高度ascentbaselinedescent(资料及测试)
- java安全体系:JCA、JCE、JSSE、JAAS
- 各种风格简洁单页响应式html5模板_简洁 响应式 单页 跳转 设计 案例 源码340多套订餐企业模板高大尚响应式网站模板html5网页静态模板Bootstrap扁平化网站源码css3手机seo自适响
- 一般计算机电源都在多少压力,一般计算机电源都在多少电压 计算机电源一般都在多少电压...