适合小白的嵌入式软件项目(C++)详解-----卡码缓存系统(二)实现最简单缓存
本期我们进入实际操作环节我采用Windows系统用VScode ssh远程连接Linux服务器进行操作。因为本人一直跑的是python的项目配置的anaconda环境这里conda deactivate退出。新建cache文件夹 并cd cache 下一步搭建基本的代码框架。基本的项目框架首先我们需要三个文件夹include放头文件src放源代码文件build放编译生成的中间文件以及可执行程序命令mkdir include src build结构cache├── include类的声明函数声明结构体定义├── src真正执行的 C 代码函数实现main 函数└── build编译垃圾桶/编译产物目录不把它和源代码混在一起接下来需要创建一个空文件CMakeLists.txtC 项目的“编译说明书”这个文件是给 CMake 用的。CMake 是 C 项目常用的构建工具它负责告诉编译器:项目叫什么用哪个 C 标准头文件在哪里源代码在哪里?最后生成什么可执行文件?命令touch CMakeLists.txt最后就是项目核心的LRUCache.h以及main.cpp先从最基础的LRU淘汰策略做起命令touch include/LRUCache.h touch src/main.cpp总结一下CMakeLists.txt 编译说明书include/LRUCache.h LRU缓存类的头文件src/main.cpp 程序入口和测试代码build 编译生成文件存放处框架搭好之后开始编辑内容先写C项目的编译配置文件因为我们后面不会直接手动写很长的g编译命令而是用 CMake 来管理项目。没有CMakeLists.txtCMake 就不知道怎么编译你的项目。cat CMakeLists.txt EOFcmake_minimum_required(VERSION 3.10)##版本号project(kama_cache)##项目名称set(CMAKE_CXX_STANDARD 17)##C17标准set(CMAKE_CXX_STANDARD_REQUIRED ON)include_directories(include)##头文件放进includeadd_executable(kama_cachesrc/main.cpp)##把src/main.cpp编译成一个可执行程序程序名字叫kama_cacheEOF接下来在main里编译一个简单的测试程序#include iostreamint main(){std::cout Kama Cache project is running! std::endl;return 0;}##std::cout输出工具将右边的内容放到左边输出流里 std::endl换行下一步执行程序cd buildcmake ..让 CMake 去上一级目录..找CMakeLists.txt然后根据它生成 Makefile其中CMakeLists.txt 是我们写的“项目编译说明书”cmake .. 根据说明书生成 Makefilemake 根据 Makefile 真正编译代码这里已经生成了可执行文件下一步直接在目录下./kama_cache。[ 50%] Building CXX object CMakeFiles/kama_cache.dir/src/main.cpp.o先把 C 代码翻译成机器更接近能执行的中间文件[100%] Linking CXX executable kama_cache把编译好的中间文件和需要的库组合起来变成真正能运行的程序[100%] Built target kama_cache这里涉及编译器原理放在下一节成功再复习一下流程。写源代码↓告诉 CMake 项目怎么编译↓在 build 文件夹里生成编译文件↓真正编译生成可执行程序↓运行程序最简单的缓存项目LRUcache基础架构int key int value 哈希表 双向链表#ifndef LRU_CACHE_H #define LRU_CACHE_H #include unordered_map //包含哈希表 class LRU_Cache//定义LRU_Cache类 { private: struct Node//定义双向链表节点类 { int key; int value; Node *prev; Node *next; Node (int k, int v) :key(k), value(v), prev(nullptr), next(nullptr) {} }; //; private : int capacity_; std::unordered_mapint, Node * cache_;//哈希表根据key快速找到节点 Node *dummyHead_;//虚拟节点指向头尾节点 Node *dummyTail_; public: LRU_Cache(int capacity)//建立一个空的双向链表函数 : capacity_(capacity) { dummyHead_ new Node(0, 0); dummyTail_ new Node(0, 0); dummyHead_-next dummyTail_; dummyTail_-prev dummyHead_; } ~LRU_Cache()//释放内存 { Node *current dummyHead_; while (current ! nullptr) { Node *nextNode current-next; delete current; current nextNode; } } }; #endifLRUCache 是一个缓存类。它里面有1. Node 节点每个节点保存 key、value、prev、next。2. capacity_缓存最大容量。3. cache_哈希表用 key 快速找到 Node 节点。4. dummyHead_ 和 dummyTail_双向链表的虚拟头节点和虚拟尾节点。写代码需注意class / struct 的大括号后面要加分号。函数的大括号后面一般不加分号。Node(int k, int v) 是构造函数用来初始化节点。std::unordered_mapint, Node* cache_ 是哈希表int key - Node* 节点地址。LRUCache(int capacity) : capacity_(capacity)表示创建缓存时把容量保存到成员变量 capacity_。读取与写入函数在public里加入get(int key)和put(int key , int value)int get(int key) //缓存的查询函数{if(cache_.find(key)cache_.end()){return -1;}Node* node cache_[key];moveToHead(node);return node-value;}void put(int key, int value) //缓存的插入函数{if(cache_.find(key)!cache_.end())//key已经存在{Node *node cache_[key];//cache_[]是哈希表的访问方式返回的是Node*类型node-value value;moveToHead(node);}if(cache_.size()capacity_)//key不存在容量已满{Node *tailNode removeTail();cache_.erase(tailNode-key);//从哈希表中删除delete tailNode;}Node *newNode new Node(key, value);cache_[key] newNode;//插入哈希表addToHead(newNode);//插入双向链表头部}简单的测试在main.cpp中写一段测试代码测试这几个功能put 插入数据get 查询数据访问后移动到最近使用容量满后淘汰最久未使用数据另外重点解释一下哈希表里的链表与我们自己写的LRU双向链表要区分开哈希表正常存放数据他解决哈希冲突与我们无关是标准库的事但是内部每个节点能够快速指向我们写的LRU双向链表上的节点地址所以我写了put(1, 100); put(2, 200);不管哈希表怎么存我们LRU双向链表上都是前后两个点。#include iostream #include LRUCache.h int main() { LRU_Cache cache(2); // 创建一个容量为2的LRU缓存 cache.put(1, 100); // 缓存中添加键值对 (1, 100) cache.put(2, 200); // 缓存中添加键值对 (2, 200) std::cout get(1): cache.get(1) std::endl; // 输出: 100键1存在于缓存中 cache.put(3, 300); // 缓存容量已满移除最久未使用的键2 std::cout get(2): cache.get(2) std::endl; std::cout get(3): cache.get(3) std::endl; return 0; }std::cout get(1): cache.get(1) std::endl;//std::cout是标准输出对象C里允许连续输出这句话拆成三段std::cout get(1): ;std::cout cache.get(1);std::cout std::endl; //换行依旧是cd build make(CMakeLists.txt 是编译说明; cmake .. 生成 Makefile; make 根据 Makefile 真正编译代码) ./kama_cache(运行当前目录下的可执行文件)成功编译器既然这里提到编译器就顺便解释编译器。等待补充中。。。

相关新闻

云耀计算AI-Claura,在树莓派运行的AI

云耀计算AI-Claura,在树莓派运行的AI

模型下载地址:https://gitee.com/jiasiqi2025/Open-Claura 官方网站:https://bksy.top 正文 Claura这个项目有意思的地方在于,它把一个能对话的AI塞进了400MB,跑在树莓派和15年前的老爷电脑上。不是靠魔法,是靠几项扎…

2026/6/23 22:47:09阅读更多 →
Shell脚本为何成为AI智能体视觉(TVA)的“反射弧”(6)

Shell脚本为何成为AI智能体视觉(TVA)的“反射弧”(6)

前沿技术介绍:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,属于“物理AI” 领域的一种全新技术形态,实现了从“虚拟世界”到“…

2026/6/23 22:42:06阅读更多 →
还在手写INSERT?这个免费的Chrome插件可以直接把网页表格变SQL

还在手写INSERT?这个免费的Chrome插件可以直接把网页表格变SQL

一、为什么SQL开发这么“浪费时间”? https://chromewebstore.google.com/detail/table-to-sql-generator/cnnbcnlgapdikanhgclfmfhmeeolnmgj 在数据库开发中,我们经常会遇到这些重复操作: 手写 INSERT 语句拼接 UPDATE 条件写 DELETE WHE…

2026/6/23 22:42:06阅读更多 →
haproxy(七层代理)、python代码的读写分离

haproxy(七层代理)、python代码的读写分离

一、haproxy----高可用、负载均衡1.安装安装ntpdate[roothaproxy ~]# yum -y install ntpdate.x86_64安装ntp[roothaproxy ~]# yum -y install ntp同步时间[roothaproxy ~]# ntpdate cn.ntp.org.cn启动ntp服务[roothaproxy ~]# systemctl start ntpd设置开机自启[roothaproxy ~…

2026/6/24 0:02:41阅读更多 →
使用自动化脚本一般可以实现哪些任务?

使用自动化脚本一般可以实现哪些任务?

我们一般通过编写或使用自动化脚本来完成各种任务,从而节省时间和提高效率。以下是一些常见的自动化脚本任务:游戏搬砖脚本技术:这种技术涉及使用自动化脚本来执行游戏中的重复任务。例如,在一个交易游戏中,脚本可以自…

2026/6/24 0:02:41阅读更多 →
Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作 【免费下载链接】Wan2.1-Fun-V1.1-1.3B-InP 项目地址: https://ai.gitcode.com/hf_mirrors/PAI/Wan2.1-Fun-V1.1-1.3B-InP Wan2.1-Fun-V1.1-1.3B-InP是一款强大的AI视频创作工具,…

2026/6/24 0:02:41阅读更多 →
终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果 【免费下载链接】angular-mobile-nav An angular navigation service for mobile applications 项目地址: https://gitcode.com/gh_mirrors/an/angular-mobile-nav angular-mobile-nav是一款专为…

2026/6/24 0:02:41阅读更多 →
TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理 【免费下载链接】TaskJuggler TaskJuggler - Project Management beyond Gantt chart drawing 项目地址: https://gitcode.com/gh_mirrors/ta/TaskJuggler TaskJuggler是一款强大的开源项目管理工具&#…

2026/6/24 0:02:41阅读更多 →
Angular移动导航插件开发:如何创建自定义导航组件

Angular移动导航插件开发:如何创建自定义导航组件

Angular移动导航插件开发:如何创建自定义导航组件 【免费下载链接】angular-mobile-nav An angular navigation service for mobile applications 项目地址: https://gitcode.com/gh_mirrors/an/angular-mobile-nav angular-mobile-nav 是一个专为移动应用设…

2026/6/23 23:57:41阅读更多 →
【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体

【人工智能】一文搞定到底什么是智能体 一文搞定到底什么是智能体【人工智能】一文搞定到底什么是智能体一. LM,WorkFlow,Agent分别有什么么不同二. Agent的思考过程是怎样的三. Agent的五个核心部分1)LLM2)Prompt3)Me…

2026/6/23 7:04:52阅读更多 →
嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

嵌入式GUI控件实战:ROTARY、SCROLLBAR、SLIDER原理与应用

1. 嵌入式GUI控件:从原理到实战的深度解析在嵌入式系统开发中,图形用户界面(GUI)的设计与实现往往是项目从“能用”到“好用”的关键一跃。不同于资源充沛的PC或移动平台,嵌入式设备的GUI需要在有限的CPU性能、内存空间…

2026/6/23 1:55:32阅读更多 →
Google AI Studio 300美元额度的真相与实战指南

Google AI Studio 300美元额度的真相与实战指南

1. 这300美金不是“送钱”,而是Google埋下的第一道技术门槛 你看到标题里那个醒目的“$300美金”时,第一反应可能是:又一个免费额度?领完就完事?我亲手试过——这300美金根本不是红包,而是一张入场券&…

2026/6/23 5:55:37阅读更多 →
TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理

TaskJuggler脚本编程入门:用代码实现自动化项目管理 【免费下载链接】TaskJuggler TaskJuggler - Project Management beyond Gantt chart drawing 项目地址: https://gitcode.com/gh_mirrors/ta/TaskJuggler TaskJuggler是一款强大的开源项目管理工具&#…

2026/6/24 0:02:41阅读更多 →
终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果

终极教程:使用angular-mobile-nav实现流畅的移动页面过渡效果 【免费下载链接】angular-mobile-nav An angular navigation service for mobile applications 项目地址: https://gitcode.com/gh_mirrors/an/angular-mobile-nav angular-mobile-nav是一款专为…

2026/6/24 0:02:41阅读更多 →
Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作

Wan2.1-Fun-V1.1-1.3B-InP Web UI使用教程:无需代码的AI视频创作 【免费下载链接】Wan2.1-Fun-V1.1-1.3B-InP 项目地址: https://ai.gitcode.com/hf_mirrors/PAI/Wan2.1-Fun-V1.1-1.3B-InP Wan2.1-Fun-V1.1-1.3B-InP是一款强大的AI视频创作工具,…

2026/6/24 0:02:41阅读更多 →