数据结构—环形缓冲区

写在前面,2023年11月开始进入岗位,工作岗位是嵌入式软件工程师。2024年是上班的第一年的,希望今年收获满满,增长见闻。

数据结构—环形缓冲区

为什么要使用环形数组,环形数组比起原来的常规数组的优势是什么?

环形数组(Circular Array)是一种特殊类型的数组,其元素在内存中首尾相接,形成一个环形。环形数组具有一些独特的优势和用途,使其在某些应用场景中比常规数组更为适用。以下是一些使用环形数组的原因和优势:

空间利用率高:由于环形数组的元素在内存中是首尾相接的,因此不需要为数组的头部和尾部留出额外的空间。这使得环形数组的空间利用率比常规数组更高。

高效的数据访问:在环形数组中,可以通过简单的模运算来确定一个元素在数组中的位置。这使得数据访问操作更加高效。

连续的数据结构:环形数组保持了数据的连续性,这有助于提高数据访问的局部性,从而优化CPU缓存的性能。

避免数组越界问题:由于环形数组的特性,当索引超出数组的界限时,会自动回到数组的开头或结尾,避免了常规数组越界访问导致的错误。

循环队列和缓冲区实现:环形数组可以方便地实现循环队列或缓冲区,无需移动大量数据即可进行队首和队尾的添加与删除操作。

减少内存碎片:由于环形数组的连续存储特性,它可以更有效地利用内存空间,减少内存碎片的产生。
易于实现动态扩展:当需要增加更多元素时,环形数组可以通过简单地扩展现有数组的大小来实现动态扩展,而无需重新分配和复制原有数据。

c代码实现

#include <stdio.h>  
#include <stdlib.h>  
#include <stdbool.h>  
  
#define BUFFER_SIZE 5 // 定义环形缓冲区的大小  
  
typedef struct {  
    int buffer[BUFFER_SIZE]; // 缓冲区数组  
    int head; // 指向缓冲区中第一个元素的位置  
    int tail; // 指向缓冲区中下一个要写入元素的位置  
} CircularBuffer;  
  
// 初始化环形缓冲区  
void init_circular_buffer(CircularBuffer *cb) {  
    cb->head = 0;  
    cb->tail = 0;  
    for (int i = 0; i < BUFFER_SIZE; i++) {  
        cb->buffer[i] = 0; // 可以选择性地初始化缓冲区的内容  
    }  
}  
  
// 检查环形缓冲区是否为空  
bool is_circular_buffer_empty(CircularBuffer *cb) {  
    return cb->head == cb->tail && cb->buffer[cb->head] == 0; // 如果头和尾相等且头部元素为空,则认为缓冲区为空  
}  
  
// 检查环形缓冲区是否已满  
bool is_circular_buffer_full(CircularBuffer *cb) {  
    return (cb->tail + 1) % BUFFER_SIZE == cb->head; // 如果下一个要写入的位置是头部,则认为缓冲区已满  
}  
  
// 向环形缓冲区中插入一个元素  
bool insert_into_circular_buffer(CircularBuffer *cb, int value) {  
    if (is_circular_buffer_full(cb)) {  
        return false; // 缓冲区已满,无法插入新元素  
    }  
    cb->buffer[cb->tail] = value; // 在尾部插入新元素  
    cb->tail = (cb->tail + 1) % BUFFER_SIZE; // 更新尾部指针到下一个位置  
    return true; // 插入成功  
}  
  
// 从环形缓冲区中移除一个元素并返回它  
int remove_from_circular_buffer(CircularBuffer *cb) {  
    if (is_circular_buffer_empty(cb)) {  
        return -1; // 缓冲区为空,无法移除元素,返回错误代码或特殊值  
    }  
    int value = cb->buffer[cb->head]; // 获取头部元素的值  
    cb->buffer[cb->head] = 0; // 可选:将移除的元素置零(根据具体需求决定是否需要这一步)  
    cb->head = (cb->head + 1) % BUFFER_SIZE; // 更新头部指针到下一个位置  
    return value; // 返回被移除的元素值  
}  
  
int main() {  
    CircularBuffer cb; // 声明一个环形缓冲区变量  
    init_circular_buffer(&cb); // 初始化环形缓冲区  
      
    // 向缓冲区中插入一些元素并检查其状态  
    for (int i = 1; i <= 6; i++) { // 尝试插入6个元素,但缓冲区大小只有5,所以会有一个插入失败  
        if (!insert_into_circular_buffer(&cb, i)) {  
            printf("Failed to insert element %d because the buffer is full.\n", i);  
        }  
    }  
      
    // 从缓冲区中移除一些元素并打印它们的值  
    for (int i = 0; i < 6; i++) { // 尝试移除6个元素,但只插入了5个,所以会有一个移除返回特殊值(这里是-1)  
        int value = remove_from_circular_buffer(&cb);  
        if (value == -1) {  
            printf("Failed to remove element because the buffer is empty.\n");  
        } else {  
            printf("Removed element: %d\n", value);  
        }  
    }  
      
    return 0;  
}

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/289708.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows 10系统用Xlight FTP搭建SFTP服务器

步骤&#xff1a; 1.安装SFTP服务器 刚开始我使用的是freeSSHd&#xff0c;后面发现由于公司网络原因&#xff0c;打不开这个软件&#xff0c;改成了使用Xlight FTP&#xff0c; 官网下载链接&#xff1a;Xlight FTP 服务器 - 下载免费的windows FTP 服务器 Xlight FTP有30…

LocalSend 开源跨平台的局域网文件互传工具

如果您需要在多平台设备之间进行文件传输&#xff0c;例如从Windows电脑到安卓手机&#xff0c;或者从安卓手机到macOS&#xff0c;通常会使用聊天工具或者U盘进行传输。为了简化这一过程&#xff0c;推荐使用一款全平台支持的文件共享传输工具&#xff1a;LocalSend。 LocalS…

Qt通过pos()获取坐标信息

背景&#xff1a;这是一个QWidget窗体&#xff0c;里面是各种布局的组合&#xff0c;一层套一层。 我希望得到绿色部分的坐标信息(x,y) QPoint get_pos(QWidget* w, QWidget* parent) {if ((QWidget*)w->parent() parent) {return w->pos();}else {QPoint pos(w->po…

以 Serverfull 方式运行无服务器服务

当前 IT 架构中最流行的用例是从 Serverfull 转向 Serverless 设计。在某些情况下&#xff0c;我们可能需要以 Serverfull 方式设计服务或迁移到 Serverfull 作为运营成本的一部分。 在本文中&#xff0c;我们将展示如何将 Kumologica flow 作为 Docker 容器运行。通常&#x…

alibabaCloud学习笔记01(小滴课堂)

微服务架构常见的核心组件 讲解业务微服务架构常见解决方案 讲解AlibabaCloud核心组件介绍 创建数据库。 建表&#xff1a; 添加数据&#xff1a; 再建个用户库&#xff1a; 建表&#xff1a; 插入数据&#xff1a; 创建订单库&#xff1a; 建表&#xff1a; 创建项目&#x…

基于SpringBoot的旅游网站

目录 前言 开发环境以及工具 项目功能介绍 用户端&#xff1a; 管理端&#xff1a; 详细设计 用户端首页 登录页面 管理端页面 源码获取 前言 本项目是一个基于IDEA和Java语言开发基于SpringBoot的旅游网站。应用包含管理端和用户端等多个功能模块。 改革开放以来&am…

redis 三主六从高可用dockerswarm高级版(不固定ip)

redis集群(cluster)笔记 redis 三主三从高可用集群docker swarm redis 三主六从高可用docker(不固定ip) redis 三主六从高可用dockerswarm高级版(不固定ip) 此博客解决&#xff0c;redis加入集群后&#xff0c;是用于停掉后重启&#xff0c;将nodes.conf中的旧的Ip替换为新的…

【机器学习】卷积神经网络(五)-计算机视觉应用

七、应用-计算机视觉 7.1 人脸检测 DenseBox\Femaleness-Net\MT-CNN\Cascade CNN 介绍 VJ框架的分类器级联用于卷积网络 用于人脸检测的紧凑卷积神经网络级联 问题&#xff1a;作者希望实时检测高分辨率视频流中的正面&#xff0c;由于人脸图像和背景的多样性和复杂性&#xff…

Godot4.2——爬虫小游戏简单制作

目录 一、项目 二、项目功能 怪物 人物 快捷键 分数 游戏说明 提示信息 三、学习视频 UI制作 游戏教程 四、总结 一、项目 视频演示&#xff1a;Godot4爬虫小游戏简单制作_哔哩哔哩bilibili 游戏教程&#xff1a;【小猫godot4入门教程 C#版 已完结】官方入门案例 第…

【人工智能】百度智能云千帆AppBuilder,快速构建您的专属AI原生应用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》&#xff0c;此序列是《人工智能》专栏文章。 这是2024年第5篇文章&#xff0c;此篇文章是进行人工智能相关的实践序列文章&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&…

ResNet论文阅读和简单实现

论文&#xff1a;https://arxiv.org/pdf/1512.03385.pdf Deep Residual Learning for Image Recognition 本模块主要是阅读论文&#xff0c;会做简单的翻译&#xff08;至少满足我自己能看明白&#xff09;。 Introduction 由上图可见&#xff0c;在20层和56层的网络上训练的…

Linux的chmod命令及快捷写法

通过chmod命令可以修改文件、文件夹的权限信息 只有文件、文件夹的所属用户或root用户可以修改 形式&#xff1a;chmod [-R] 权限 文件或文件夹 -R&#xff1a;对文件夹内的全部内容应用同样的操作 eg&#xff1a;chmod urwx,grx,ox test.txt &#xff0c;将文件权限修改为…

python实现巴特沃斯低通滤波器——数字图像处理

原理&#xff1a; 巴特沃斯低通滤波器&#xff08;Butterworth Low-Pass Filter&#xff09;是图像处理中常用的一种频率域滤波器&#xff0c;它相较于理想低通滤波器提供了更平滑的过渡&#xff0c;以减少图像处理时引入的振铃效应。 设计原理&#xff1a; 巴特沃斯低通滤波…

隐藏层节点数对分类准确率的影响

直线上有9个格子&#xff0c;4个石子&#xff0c; 数量 结构编号 6 0 1 1 1 1 0 0 0 0 0 5 2 1 1 1 0 1 0 0 0 0 5 1 1 0 1 1 1 0 0 0 0 4 3 1 1 0 0 1 1 0 0 0 4 4 1 0 1 0 1 1 0 0 0 3 5 1 0 1 0 1 0 1 0…

Vue中的选项式 API 和组合式 API,两者有什么区别

Vue中的选项式 API&#xff08;Option API&#xff09;和组合式 API&#xff08;Composition API&#xff09;是两种不同的组件编写方式&#xff0c;它们各有特点和适用场景&#xff1a; 选项式 API&#xff08;Option API&#xff09;: 传统方法&#xff1a;Vue最初的编程范式…

c# OpenCvSharp Cv2.Threshold()和Cv2.AdaptiveThreshold参数说明

一、 Cv2.Threshold()二值化的函数参数说明 Cv2.Threshold()是一个用于图像二值化的函数。具体来说&#xff0c;它会将图像中的每一个像素的灰度值与一个阈值进行比较&#xff0c;大于该阈值的像素会被赋值为最大灰度值(即 255)&#xff0c;小于该阈值的像素会被赋值为最小灰度…

Python 自学(四) 之元组字典与集合

目录 1. 列表&#xff0c;元组&#xff0c;字典与集合的区别 2. 元组的创建和删除 tuple() del P101 3. 单个元素的元组 P102 4. 元组元素的修改 P106 5. 元组的使用场景 6. 字典的创建和删除 dict() zip() : del clear() P1…

SWM341系列之86盒智能开关应用

SWM341系列 86盒智能开关应用 华芯微特SWM341系列的SWM34SRET6&#xff0c;在86盒智能开关产品中的应用。 SWM34SRET6性能和UI的描述 SWM34SRET6是一款基于ARM Cortex-M33内核&#xff0c;最高主频可达150MHz时钟&#xff0c;提供内置512KB Flash&#xff0c;64KB SRAM&#…

【零基础入门TypeScript】TypeScript - 运算符

目录 ​编辑 什么是操作员&#xff1f; 算术运算符 关系运算符 逻辑运算符 按位运算符 赋值运算符 杂项运算符 否定运算符 (-) 字符串运算符&#xff1a;连接运算符 () 条件运算符 (?) 类型运算符 类型运算符 实例化 什么是操作员&#xff1f; 运算符定义将对数…

论文阅读:通过时空生成卷积网络合成动态模式(重点论文)

原文链接 github code 介绍视频 视频序列包含丰富的动态模式&#xff0c;例如在时域中表现出平稳性的动态纹理模式&#xff0c;以及在空间或时域中表现出非平稳的动作模式。 我们证明了时空生成卷积网络可用于建模和合成动态模式。 该模型定义了视频序列上的概率分布&#xff0…