写一个自动扩容和缩容的环形缓冲区
时间: 2024-03-20 18:39:55 浏览: 23
好的,下面给出一个自动扩容和缩容的环形缓冲区的代码实现。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct ring_buffer {
int size; // 环形缓冲区的大小
int read; // 读指针
int write; // 写指针
char *buffer; // 缓冲区指针
} RingBuffer;
void rb_init(RingBuffer *rb, int size) {
rb->size = size;
rb->read = 0;
rb->write = 0;
rb->buffer = (char *) malloc(size * sizeof(char));
}
void rb_free(RingBuffer *rb) {
free(rb->buffer);
}
int rb_is_empty(RingBuffer *rb) {
return (rb->read == rb->write);
}
int rb_is_full(RingBuffer *rb) {
return ((rb->write + 1) % rb->size == rb->read);
}
int rb_can_read(RingBuffer *rb) {
return (rb->write - rb->read + rb->size) % rb->size;
}
int rb_can_write(RingBuffer *rb) {
return (rb->read - rb->write - 1 + rb->size) % rb->size;
}
int rb_read(RingBuffer *rb, char *data, int len) {
int can_read = rb_can_read(rb);
if (can_read == 0) {
return 0;
}
int n = len < can_read ? len : can_read;
for (int i = 0; i < n; i++) {
data[i] = rb->buffer[rb->read];
rb->read = (rb->read + 1) % rb->size;
}
return n;
}
int rb_write(RingBuffer *rb, char *data, int len) {
int can_write = rb_can_write(rb);
if (can_write == 0) {
return 0;
}
int n = len < can_write ? len : can_write;
for (int i = 0; i < n; i++) {
rb->buffer[rb->write] = data[i];
rb->write = (rb->write + 1) % rb->size;
}
return n;
}
void rb_resize(RingBuffer *rb, int size) {
char *new_buffer = (char *) malloc(size * sizeof(char));
int len = rb_can_read(rb);
for (int i = 0; i < len; i++) {
new_buffer[i] = rb->buffer[rb->read];
rb->read = (rb->read + 1) % rb->size;
}
free(rb->buffer);
rb->buffer = new_buffer;
rb->read = 0;
rb->write = len;
rb->size = size;
}
void rb_auto_resize(RingBuffer *rb) {
if (rb_is_full(rb)) {
rb_resize(rb, rb->size * 2);
} else if (rb_can_read(rb) < rb->size / 2) {
rb_resize(rb, rb->size / 2);
}
}
int main() {
RingBuffer rb;
rb_init(&rb, 10);
char data[100];
int ret;
// 写入数据
ret = rb_write(&rb, "12345", 5);
printf("write %d bytes\n", ret);
// 读取数据
ret = rb_read(&rb, data, 5);
printf("read %d bytes: %.*s\n", ret, ret, data);
// 写入数据至满
while (rb_can_write(&rb) > 0) {
rb_write(&rb, "a", 1);
}
printf("is full: %d\n", rb_is_full(&rb));
// 写入数据自动扩容
ret = rb_write(&rb, "bcdefghijklmnopqrstuvwxyz", 25);
printf("write %d bytes\n", ret);
printf("size: %d, can read: %d, can write: %d\n", rb.size, rb_can_read(&rb), rb_can_write(&rb));
// 读取数据自动缩容
ret = rb_read(&rb, data, 10);
printf("read %d bytes: %.*s\n", ret, ret, data);
printf("size: %d, can read: %d, can write: %d\n", rb.size, rb_can_read(&rb), rb_can_write(&rb));
// 释放资源
rb_free(&rb);
return 0;
}
```
这个环形缓冲区的实现中,通过 `rb_auto_resize` 函数实现了自动扩容和缩容的功能,当环形缓冲区满时,自动将缓冲区大小扩大为原来的两倍;当环形缓冲区的可读数据小于总大小的一半时,自动将缓冲区大小缩小为原来的一半。这样实现可以较好地平衡了空间和时间的开销,提高了程序的性能。