当前位置: 首页 > news >正文

通讯录完善版本(详细讲解+源码)

目录

前言

一、使通讯可以动态更新内存

1、contact.h

2、contact.c

存信息:

删除联系人,并试一个不存在的人的信息,看看会不会把其他人删了

​编辑

修改:

​编辑

排序:

​编辑

销毁:

​编辑

​编辑

二、通讯录的信息保存,加载

通讯录的信息保存;

再增加一个保存信息的函数

Save_Contact:

再增加一个从文件中加载信息的函数

Load_Contact:

​编辑

​编辑

三、下面是完整的代码:

test.c

castact.c

contact.h

总结


前言

     经过长达六个月的时间,年迈的博主终于想起来,通讯录还需要完善,那么这篇文章就对我们的初代通讯录(初代通讯录(详细讲解+代码)_化学系通讯录最简单三个步骤-CSDN博客)进行完善,增加动态更新内存的内容,以及建立一个文件,将通讯录的信息保存下来;


一、使通讯可以动态更新内存

我们先看一下原通讯录

1、contact.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<math.h>
#pragma once#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100//定义人的信息
typedef struct PeoInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//定义通讯录的信息
typedef struct Contact
{PeoInfo data[MAX];//存放人的信息int sz;//记录目前通讯录中存放的人的信息个数
}Contact;//初始化通讯录
void Init_Contact(Contact* pc);
//增加联系人
void Add_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
查找联系人
void Search_Contact(Contact* pc);
修改联系人信息
void Modify_Contact(Contact* pc);
通讯录信息查看
void Show_Contact(Contact* pc);
通讯录信息排列
void Sort_Contact(Contact* pc);
2、contact.c
#include"contact.h"//初始化通讯录
void Init_Contact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}
//增加联系人
void Add_Contact(Contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录满了,无法添加");return;}//添加一个联系人的信息//printf("请输入你要添加的联系人的信息:");//scanf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n", pc->data[pc->sz].name, pc->data[pc->sz].sex, &(pc->data[pc->sz].age), pc->data[pc->sz].tele, pc->data[pc->sz].addr);printf("请输入姓名:");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age)); printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;}
//删除联系人
void Del_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除");return;}//不为空,删除printf("请输入要删除人的名字:");scanf("%s", name);int i = 0;int del = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;break;}}for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("已成功删除该联系人");}
//查找联系人
void Search_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空");return;}printf("请输入要查找的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;			}}printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].sex,pc->data[pos].age,pc->data[pos].tele,pc->data[pos].addr);}
//修改联系人信息
void Modify_Contact(Contact* pc) 
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法修改");return;}printf("请输入要修改的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;}}printf("请输入姓名:");scanf("%s", pc->data[pos].name);printf("请输入性别:");scanf("%s", pc->data[pos].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pos].age));printf("请输入电话:");scanf("%s", pc->data[pos].tele);printf("请输入地址:");scanf("%s", pc->data[pos].addr);}
//通讯录信息查看/打印通讯录
void Show_Contact(Contact* pc)
{assert(pc);printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}//通讯录信息排列
void Sort_Contact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法排序\n");return;}qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);printf("排序完成\n");}

可以看到原通讯录是用100大小的静态数组存储信息的,现在我们将其改为动态的数组;

主要是初始化,增加联系人,信息排列,销毁通讯录需要用到动态内存管理;

动态内存函数可以在这里看:动态内存函数_内存创建用什么函数-CSDN博客

我们先将定义进行更改,增加容量capacity,以及将存放信息的data数组不加限制;

然后在初始化Init_Contact这里进行修改,先设置初始容量capacity的值,然后再通过malloc设置初始内存,再用assert断言确保内存设置好了,不为空;

然后就是增加联系人这块,当通讯录满了即pc->sz == pc->capacity的时候,将pc->capacity乘2,增加容量,当然了,想扩大多少倍看你自己喜欢,然后再对存放数据的data数组经行扩容,扩成修改后的capacity大小;最后加个assert断言

然后是信息排列

最后是对动态数组的销毁,先将内存释放掉,然后置为空,再将capacitysz置为0;

将各个功能都试一下;

存信息:

删除联系人,并试一个不存在的人的信息,看看会不会把其他人删了

修改:

排序:

销毁:

ok,这边的通讯录动态数组已经没问题,我们接着来看

二、通讯录的信息保存,加载

通讯录的信息保存,加载涉及文件的读写操作:c语言文件操作-CSDN博客

通讯录的信息保存;

首先创建一个记事本文档,再在代码中定义上

然后完善增加两个函数的目录

#include"contact.h"
void menu()
{printf("**************************************\n");printf("****** 1.add     2.del     ***********\n");printf("****** 3.search  4.modify  ***********\n");printf("****** 5.show    6.sort    ***********\n");printf("****** 7.save    8.load    ***********\n");printf("****** 0.exit   9.destory  ***********\n");printf("**************************************\n");}
enum
{Exit,Add,Del,Search,Modify,Show,Sort,Save,Load,Destory
};//directory
int main()
{//创建通讯录Contact con;Init_Contact(&con);int input = 0;do{menu();printf("请输入:");scanf("%d", &input);switch (input){case Exit:printf("已退出通讯录\n");break; case Add:Add_Contact(&con);break;case Del:Del_Contact(&con);break;case Search:Search_Contact(&con);break;case Modify:Modify_Contact(&con);break;case Show:Show_Contact(&con);break;case Sort:Sort_Contact(&con);break;case Save:Save_Contact(&con);break; case Load:Load_Contact(&con);break;case Destory:Destory_Contact(&con); break;default:printf("选择错误,请重新选择\n");break;}	} while (input);//Destory_Contact(&con);return 0;
}

再增加一个保存信息的函数

Save_Contact:

void Save_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "w");if (!file) {printf("无法打开文件进行保存\n");return;}for (int i = 0; i < pc->sz; i++) {fprintf(file, "%s %s %d %s %s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}fclose(file);printf("联系人信息已经保存到文件\n");
}

再增加一个从文件中加载信息的函数

1. **打开文件**:
   - 使用 `fopen` 函数以只读模式打开指定的文件。如果文件打开失败,程序会输出错误信息并返回。

2. **动态扩展内存**:
   - 在读取每个联系人之前,检查当前的联系人数量 `sz` 是否达到了当前容量 `capacity`。如果达到了,就使用 `realloc` 扩展内存,以便可以存储更多的联系人信息。

3. **读取数据**:
   - 使用 `fscanf` 从文件中读取每个联系人的信息。格式字符串 `"%s %s %d %s %s\n"` 指定了要读取的数据类型:
     - `%s` 用于读取字符串(姓名、性别、电话、地址)。
     - `%d` 用于读取整数(年龄)。

4. **存储数据**:
   - 将读取到的数据存储到 `PeoInfo` 结构体的相应字段中。

为什么 `age` 需要加引用

在 C 语言中,`fscanf` 函数的工作原理是通过指针来修改变量的值。具体来说:

引用的概念:
 在 C 语言中,变量的值是存储在内存中的某个地址。当你想要修改一个变量的值时,你需要提供这个变量的地址。
  使用 `&` 符号可以获取变量的地址。例如,`&pc->data[pc->sz].age` 获取 `age` 字段的地址。

fscanf 的参数:
  fscanf的参数需要是指向变量的指针,以便它可以直接在内存中修改该变量的值。
  对于 age字段,fscanf需要知道它的地址,以便将读取到的整数值存储到这个地址中。因此,必须使用 `&` 符号。

 示例:

假设我们有以下代码:

int age;
fscanf(file, "%d", &age);

`&age` 将 `age` 变量的地址传递给 `fscanf`,这样 `fscanf` 就可以在该地址上写入读取到的整数值。
- 如果不使用 `&`,例如 `fscanf(file, "%d", age);`,编译器会报错,因为 `age` 是一个整数,而 `fscanf` 需要的是一个指向整数的指针。

Load_Contact:

void Load_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "r");if (!file) {printf("无法打开文件进行加载\n");return;}while (!feof(file)) {if (pc->sz == pc->capacity) {pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data, pc->capacity * sizeof(PeoInfo));//重新分配assert(pc->data);//确保内存分配成功}fscanf(file, "%s %s %d %s %s\n",pc->data[pc->sz].name,pc->data[pc->sz].sex,&pc->data[pc->sz].age,pc->data[pc->sz].tele,pc->data[pc->sz].addr);pc->sz++;}fclose(file);printf("联系人信息已经加载\n");
}

再来验一下货,看看我们的代码灵不灵

应该是没有问题

三、下面是完整的代码:
test.c
#include"contact.h"
void menu()
{printf("**************************************\n");printf("****** 1.add     2.del     ***********\n");printf("****** 3.search  4.modify  ***********\n");printf("****** 5.show    6.sort    ***********\n");printf("****** 7.save    8.load    ***********\n");printf("****** 0.exit   9.destory  ***********\n");printf("**************************************\n");}
enum
{Exit,Add,Del,Search,Modify,Show,Sort,Save,Load,Destory
};//directory
int main()
{//创建通讯录Contact con;Init_Contact(&con);int input = 0;do{menu();printf("请输入:");scanf("%d", &input);switch (input){case Exit:printf("已退出通讯录\n");break; case Add:Add_Contact(&con);break;case Del:Del_Contact(&con);break;case Search:Search_Contact(&con);break;case Modify:Modify_Contact(&con);break;case Show:Show_Contact(&con);break;case Sort:Sort_Contact(&con);break;case Save:Save_Contact(&con);break; case Load:Load_Contact(&con);break;case Destory:Destory_Contact(&con); break;default:printf("选择错误,请重新选择\n");break;}	} while (input);//Destory_Contact(&con);return 0;
}
castact.c
#include"contact.h"//初始化通讯录
void Init_Contact(Contact* pc)
{assert(pc);pc->sz = 0;pc->capacity = 2;//设置初始容量pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));//初始内存assert(pc->data);//确保内存不为空}
//增加联系人
void Add_Contact(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){//printf("通讯录满了,无法添加");//return;pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data,pc->capacity*sizeof(PeoInfo));assert(pc->data);//确保内存分配成功}//添加一个联系人的信息//printf("请输入你要添加的联系人的信息:");//scanf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n", pc->data[pc->sz].name, pc->data[pc->sz].sex, &(pc->data[pc->sz].age), pc->data[pc->sz].tele, pc->data[pc->sz].addr);printf("请输入姓名:");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age)); printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;}
//删除联系人
void Del_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除");return;}//不为空,删除printf("请输入要删除人的名字:");scanf("%s", name);int i = 0;int del = -1;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;break;}}if (del == -1) {printf("未找到该联系人");return;}for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("已成功删除该联系人");}
//查找联系人
void Search_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空");return;}printf("请输入要查找的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;	printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].sex,pc->data[pos].age,pc->data[pos].tele,pc->data[pos].addr);return;}}printf("未找到该联系人");}
//修改联系人信息
void Modify_Contact(Contact* pc) 
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法修改");return;}printf("请输入要修改的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;printf("请输入姓名:");scanf("%s", pc->data[pos].name);printf("请输入性别:");scanf("%s", pc->data[pos].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pos].age));printf("请输入电话:");scanf("%s", pc->data[pos].tele);printf("请输入地址:");scanf("%s", pc->data[pos].addr);return;}}printf("未找到该联系人");}
//通讯录信息查看/打印通讯录
void Show_Contact(Contact* pc)
{assert(pc);printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}//通讯录信息排列
void Sort_Contact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法排序\n");return;}//qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序完成\n");}
void Destory_Contact(Contact* pc)
{assert(pc);free(pc->data);//释放内存/*if (pc->sz == 0){printf("通讯录为空\n");return;}for (int i =pc->sz; i >=0; i--){pc->sz--;pc->data[i] = pc->data[i + 1];}*/pc->data = NULL;//置空pc->sz = 0;pc->capacity = 0;printf("已全部删除,通讯录销毁\n");}void Save_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "w");if (!file) {printf("无法打开文件进行保存\n");return;}for (int i = 0; i < pc->sz; i++) {fprintf(file, "%s %s %d %s %s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}fclose(file);printf("联系人信息已经保存到文件\n");
}void Load_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "r");if (!file) {printf("无法打开文件进行加载\n");return;}while (!feof(file)) {if (pc->sz == pc->capacity) {pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data, pc->capacity * sizeof(PeoInfo));//重新分配assert(pc->data);//确保内存分配成功}fscanf(file, "%s %s %d %s %s\n",pc->data[pc->sz].name,pc->data[pc->sz].sex,&pc->data[pc->sz].age,pc->data[pc->sz].tele,pc->data[pc->sz].addr);pc->sz++;}fclose(file);printf("联系人信息已经加载\n");
}
contact.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<math.h>
#pragma once
#define FILENAME "contacts.txt"//文件名#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
//#define MAX 1000//定义人的信息
typedef struct PeoInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//定义通讯录的信息
typedef struct Contact
{//PeoInfo data[MAX];//存放人的信息PeoInfo* data;//存放人的信息int sz;//记录目前通讯录中存放的人的信息个数int capacity;//记录目前容量
}Contact;//初始化通讯录
void Init_Contact(Contact* pc);
//增加联系人
void Add_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
查找联系人
void Search_Contact(Contact* pc);
修改联系人信息
void Modify_Contact(Contact* pc);
通讯录信息查看
void Show_Contact(Contact* pc);
通讯录信息排列
void Sort_Contact(Contact* pc);
//通讯录删除全部联系人
void Destory_Contact(Contact* pc);void Save_Contact(Contact* pc); //保存void Load_Contact(Contact* pc);//加载


总结

首先非常感谢大家的观看,这期对通讯录进行了完善,增加了动态变化数组已经信息的保存与加载

修改了很多缺陷:

1.这个通讯录能保存了,不会出现一旦退出就消失了

2.这个通讯录没有固定大小,减少了空间的浪费

本期内容到这里就结束了,有什么不足的地方可以提出来,我会虚心接受改进的,大家一起加油吧

相关文章:

通讯录完善版本(详细讲解+源码)

目录 前言 一、使通讯可以动态更新内存 1、contact.h 2、contact.c 存信息&#xff1a; 删除联系人&#xff0c;并试一个不存在的人的信息&#xff0c;看看会不会把其他人删了 ​编辑 修改&#xff1a; ​编辑 排序&#xff1a; ​编辑 销毁&#xff1a; ​编辑 ​…...

第3讲:ggplot2完美入门与美化细节打磨——从基础绘制到专业级润色

目录 1. 为什么选择ggplot2? 2. 快速了解ggplot2绘图核心逻辑 3. 基础绘图示范:柱状图、折线图、散点图 (1)简单柱状图 (2)折线图示范 (3)高级散点图 + 拟合线 4. 精细美化:细节打磨决定专业感 5. 推荐的美化小插件(可选进阶) 6. 小练习:快速上手一幅美化…...

带宽?增益带宽积?压摆率?

一、带宽&#xff08;Bandwidth&#xff09; 1.科学定义&#xff1a; 带宽指信号或系统能够有效通过的频率范围&#xff0c;通常定义为信号功率下降到中频值的一半&#xff08;即 - 3dB&#xff09;时的最高频率与最低频率之差。对于运算放大器&#xff08;Op-Amp&#xff09…...

为什么栈内存比堆内存速度快?

博主介绍&#xff1a;程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章&#xff0c;首发gzh&#xff0c;见文末&#x1f447;&#x1…...

什么是非关系型数据库

什么是非关系型数据库&#xff1f; 引言 随着互联网应用的快速发展&#xff0c;传统的基于表格的关系型数据库&#xff08;如 MySQL、Oracle 等&#xff09;已经不能完全满足现代应用程序的需求。在这种背景下&#xff0c;非关系型数据库&#xff08;NoSQL 数据库&#xff09…...

制作一个简单的操作系统9

自定义 myprintf 函数实现解析 探索如何实现一个自定义的 printf 函数来处理任意 %d 和 %s 组合 (说实话,想不用任何库函数和头文件,纯C实现太难了,我放弃了,弄了一个简陋版本 对付用) 运行效果: Hello 123 World 456 Coding这样参数传递:(最多支持5个参数,按顺序…...

华为Pura X的智控键:让折叠机体验更上一层楼的设计

还记得Mate 70系列刚出那会&#xff0c;我体验了下智控键&#xff0c;那时候就觉得这个“把快捷方式做进电源键”的交互方式非常惊艳&#xff0c;没想到在Pura X上&#xff0c;这种便捷体验感更上了一层楼。 智控键&#xff1a;折叠屏手机的天选快捷方式&#xff1f; 传统折叠…...

打造高功率、高电流和高可靠性电路板的厚铜PCB生产

厚铜PCB生产是指制作一种具有较厚铜层的PCB&#xff08;Printed Circuit Board&#xff0c;印刷电路板&#xff09;。这种PCB通常用于高功率、高电流和高可靠性的电子设备中。厚铜PCB的生产过程包括以下几个 主要步骤&#xff1a; 1. 基材准备 厚铜PCB的基材通常采用FR4或CEM-…...

AI超级智能体教程(三)---程序调用AI大模型的四种方式(SpringAI+LangChain4j+SDK+HTTP)

文章目录 1.安装SDK&#xff08;查看文档&#xff09;2.创建API-key3.项目引入灵积大模型4.HTTP接入的方式5.SpringAI引入5.1添加依赖5.2添加配置5.3测试代码 6.LangChain4j引入6.1依赖引入6.2测试提问 1.安装SDK&#xff08;查看文档&#xff09; 安装阿里云百炼SDK_大模型服…...

JDBC连接数据库

一、查询 sqlserver数据库 private List<Map<String, String>> getPathList(String id) throws Exception {String driverName "com.microsoft.sqlserver.jdbc.SQLServerDriver";String dataBaseurl "jdbc:sqlserver://localhost:1433;SelectMeth…...

常见缓存淘汰算法(LRU、LFU、FIFO)的区别与实现

一、前言 缓存淘汰算法主要用于在内存资源有限的情况下&#xff0c;优化缓存空间的使用效率。以确保缓存系统在容量不足时能够智能地选择需要移除的数据。 二、LRU&#xff08;Least Recently Used&#xff09; 核心思想&#xff1a;淘汰最久未被访问的数据。实现方式&#x…...

深度学习--循环神经网络RNN

文章目录 前言一、RNN介绍1、传统神经网络存在的问题2、RNN的核心思想3、 RNN的局限性 二、RNN基本结构1、RNN基本结构2、推导3、注意4、循环的由来5、再谈RNN的局限 总结 前言 循环神经网络&#xff08;RNN&#xff09;的起源可以追溯到1982年&#xff0c;由Saratha Sathasiv…...

大学IP广播系统解决方案:构建数字化智慧化大学校园IP广播平台

大学IP广播系统解决方案:构建数字化智慧化大学校园IP广播平台 北京海特伟业科技有限公司任洪卓于2025年4月24日发布 随着教育信息化建设的深入推进&#xff0c;传统的模拟广播系统已无法满足现代化校园对智能化、场景化、融合化的管理需求。为此&#xff0c;海特伟业提出构建…...

#ifndef #else #endif条件编译

目录 一、#ifdef 1. 基本用法 2. 查看头文件 3. 目的 4. 常见用途 4. 取消定义 5.小结 二、#ifndef和#ifdef区别 1. #ifdef 2. #ifndef 3.结论 一、#ifdef 宏定义 #define H_PWM_L_ON 的作用是创建一个名为 H_PWM_L_ON 的宏。以下是这个宏定义的一些关键点&#xff…...

SystemVerilog语法之typedef与自定义结构

1.7 使用typedef创建新的类型 在Verilog中&#xff0c;你可以为操作数的位宽或者类型分别定义一个宏&#xff0c;但是你并没有创建新的数据类型&#xff0c;而是进行了文本的替换。在SystemVerilog中&#xff0c;可以使用typedef创建新的类型。可以将parameter和typedef语句放…...

【防火墙 pfsense】2配置

&#xff08;1&#xff09;接口配置和接口 IP 地址分配 ->配置广域网&#xff08;WAN&#xff09;和局域网&#xff08;LAN&#xff09;接口&#xff0c;分配设备标识符&#xff0c;如 eth0、eth1 等&#xff1b; ->如将WAN 接口将被分配到 eth0&#xff0c;而 LAN 接口将…...

数据结构之排序

排序 一.比较排序1.插入排序基本思想1.1直接插入排序1.2希尔排序 2.选择排序直接选择排序堆排序 3.交换排序冒泡排序快速排序hoare版本挖坑法lomuto前后指针非递归版本 4.归并排序非递归的归并排序 非比较排序1.计数排序 排序算法复杂度及稳定性分析 一.比较排序 1.插入排序 …...

cgroup sched_cfs_bandwidth_slice参数的作用及效果

一、背景 cgroup是一个非常重要的功能&#xff0c;其中cgroup cpu这块有不少功能&#xff0c;在之前的博客 CFS及RT调度整体介绍_rt调度器-CSDN博客 里&#xff0c;我们分析了cfs的组调度也就是cgroup cpu的这块内核逻辑的细节侧重于调度逻辑这块&#xff0c;在之前的博客 cgr…...

【C++指南】告别C字符串陷阱:如何实现封装string?

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f4ac; 注意&#xff1a;本章节只详讲string中常用接口及实现&#xff0c;有其他需求查阅文档介绍。 &#x1f680; 今天通过了…...

液体神经网络LNN-Attention创新结合——基于液体神经网络的时间序列预测(PyTorch框架)

1.数据集介绍 ETT(电变压器温度)&#xff1a;由两个小时级数据集&#xff08;ETTh&#xff09;和两个 15 分钟级数据集&#xff08;ETTm&#xff09;组成。它们中的每一个都包含 2016 年 7 月至 2018 年 7 月的七种石油和电力变压器的负载特征。 traffic(交通) &#xff1a;描…...

kafka和Spark-Streaming2

Kafka 工作流程及文件存储机制 Kafka 中消息是以topic 进行分类的&#xff0c;生产者生产消息&#xff0c;消费者消费消息&#xff0c;都是面向topic 的。 “.log”文件存储大量的数据&#xff0c;“.index”文件存储偏移量索引信息&#xff0c;“.timeindex”存储时间戳索引文…...

MySQL日期函数的详细教程(包含常用函数及其示例)

概述 以下是一个关于MySQL日期函数的详细教程&#xff0c;包含常用函数及其示例内容以转换为PDF电子书&#xff0c;喜欢的朋友可以转存慢慢享用&#xff1a;https://pan.quark.cn/s/57d2e491bbbe 1. 获取当前日期和时间 • CURDATE() / CURRENT_DATE() 返回当前日期&#xf…...

P4017 最大食物链计数-拓扑排序

P4017 最大食物链计数 题目来源-洛谷 题意 要求最长食物链的数量。按照题意&#xff0c;最长食物链就是指有向无环图DAG中入度为&#xff10;到出度为&#xff10;的不同路径的数量&#xff08;链数&#xff09; 思路 在计算时&#xff0c;明显&#xff1a;一个被捕食者所…...

C语言——字串处理

C语言——字串处理 一、问题描述二、格式要求1.输入形式2.输出形式3.样例 三、实验代码 一、问题描述 现有两个字符串s1和s2&#xff0c;它们最多都只能包含255个字符。编写程序&#xff0c;将字符串s1中所有出现在字符串s2中的字符删去&#xff0c;然后输出s1。 二、格式要求…...

工业排风轴流风机:强劲动力与节能设计的完美融合

在工业生产中&#xff0c;通风换气是保障作业环境安全、维持设备正常运行的关键环节。工业排风轴流风机凭借其独特的设计&#xff0c;将强劲动力与节能特性完美融合&#xff0c;成为众多工业场景的首选通风设备&#xff0c;为企业高效生产与绿色发展提供了可靠支持。​ 工业排风…...

【Test】单例模式❗

文章目录 1. 单例模式2. 单例模式简单示例3. 懒汉模式4. 饿汉模式5. 懒汉式和饿汉式的区别 1. 单例模式 &#x1f427;定义&#xff1a;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 单例模式是一种常用的软件设计模式&#xff0c;在它的核心结构中只包…...

3.3 Spring Boot文件上传

在 Spring Boot 项目中实现文件上传功能&#xff0c;首先创建项目并添加依赖&#xff0c;包括 Commons IO 用于文件操作。接着&#xff0c;创建文件上传控制器 FileUploadController&#xff0c;定义上传目录并实现文件上传逻辑&#xff0c;通过生成唯一文件名避免文件冲突。创…...

【玩泰山派】7、玩linux桌面环境xfce - (4)使用gstreamer

文章目录 前言gstreamergstreamer概述基本概念主要功能应用场景开发方式 安装gstreamer使用gstreamer使用gstreamer播放视频 前言 玩一下gstreamer&#xff0c;使用gstreamer去播放下音视频 gstreamer gstreamer概述 GStreamer是一个用于构建多媒体应用程序的开源库和框架&…...

cpu性能统计

cpu负载 top中avg&#xff0c;/proc/loadavg, 包括cpu密集型任务io型任务 统计流程 每cpu scheduler_tick ----calc_global_load_tick &#xff1a; 当前瞬时 cpu::this_rq:: nr_runningnr_inunterrupt->calc_load_tasks(全局变量) 全局 do_timer ----calc_global_load&a…...

Java对接企业微信实战笔记

Java对接企业微信实战笔记 微信开发文档 有关企业微信的服务商的一些配置参考企业微信创建的服务商配置信息 一 流程图 只要企业安装应用后&#xff0c;就可以获取到企业的信息 二 创建应用获取suite_ticket 1.创建应用 微信开发平台得是服务商角色才能进入服务商后台创建一…...

HashMap的源码解析

HashMap基于哈希表的Map接口实现&#xff0c;是以key-value存储形式存在&#xff0c;即主要用来存放键值对。HashMap的实现不是同步的&#xff0c;这意味着它不是线程安全的。它的key、value都可以为null。此外&#xff0c;HashMap中的映射不是有序的。 JDK1.8 之前 HashMap由数…...

【金仓数据库征文】金仓数据库KingbaseES:在技术与人文交织中开拓信创未来

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;AI 【引言】 在信息技术应用创新&#xff08;信创&#xff09;的浪潮下&#xff0c;数据库作为数字经济的基石&#xf…...

【AI】[特殊字符]生产规模的向量数据库 Pinecone 使用指南

一、Pinecone 的介绍 Pinecone是一个完全托管的向量数据库服务&#xff0c;专为大规模机器学习应用设计。它允许开发者轻松存储、搜索和管理高维向量数据&#xff0c;为推荐系统、语义搜索、异常检测等应用提供强大的基础设施支持。 1.1 Pinecone的核心特性 1. 高性能向量搜…...

OpenHarmony之电源模式定制开发指导

OpenHarmony之电源模式定制开发指导 概述 简介 OpenHarmony默认提供了电源模式&#xff08;如正常模式、性能模式、省电模式、极致省电模式&#xff09;的特性。但由于不同产品的部件存在差异&#xff0c;导致在同样场景下电源模式的配置需要也存在差异&#xff0c;为此&…...

Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互

Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示&#xff0c;实现前后端交互 前言一、JDBC 核心接口和类&#xff1a;数据库连接的“工具箱”1. 常用的 2 个“关键类”2. 必须掌握的 5 个“核心接口” 二、创建 JDBC 程序的步骤1. 第一步&#xf…...

JDBC之ORM思想及SQL注入

目录 一. ORM编程思想 1. 简介 2. 实操ORM思想 a. Students实体类 b. ORM映射 二. SQL注入 1. 简介 2. 解决SQL注入 三. 总结 前言 本文来讲解ORM编程思想和SQL注入&#xff0c;旨在帮助大家更容易的理解和掌握 个人主页&#xff1a;艺杯羹 系列专栏&#xff1a;JDBC …...

UniApp学习笔记

在uniapp中使用View标签来代替div标签&#xff0c;使用rpx来取代px&#xff0c;rpx动态适配屏幕宽度750rpx100vw H5端不支持*的css选择器 body的元素选择器请改为page div和ul和li等改为view、 span和font改为text a改为navigator img改为image scoped:非H5端默认并未启…...

统计术语学习

基期、现期 作为对比参照的时期称为基期&#xff0c;而相对于基期的称为现期。 描述具体数值时我们称之为基期量和现期量。 【例 1】2017 年比 2016 年第三产业 GDP 增长 6.8%&#xff0c; &#xff08;2016&#xff09;为基期&#xff0c;&#xff08;2017&#xff09; 为现…...

认识 Linux 内存构成:Linux 内存调优之页表、TLB、缺页异常、大页认知

写在前面 博文内容涉及 Linux 内存中 多级页表,缺页异常,TLB,以及大页相关基本认知理解不足小伙伴帮忙指正对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是…...

Java File 类的常用方法详解

Java File 类的常用方法详解 File 类是 Java 中用于操作文件和目录的核心类&#xff0c;位于 java.io 包。它提供了丰富的方法来管理文件系统&#xff0c;包括创建、删除、重命名、查询属性、遍历目录等操作。 1. 构造方法 File 类提供多种构造方法&#xff0c;用于创建文件或…...

【AIGC】基础篇:VS Code 配置 Python 命令行参数调试debug超详细教程

文章目录 前言一、安装必要的扩展二、安装 debugpy三、创建 launch.json 配置文件四、配置调试环境五、开始调试六、命令行调试七、远程调试八、调试技巧九、常见问题及解决方法 前言 在 Python 开发过程中&#xff0c;调试是必不可少的环节。VS Code 提供了强大的调试功能&am…...

【金仓数据库征文】金仓数据库KingbaseES:千行百业国产化征程中的璀璨之星

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;AI 【引言】 在数字化转型浪潮奔涌向前的时代&#xff0c;数据库作为数据存储与管理的核心枢纽&#xff0c;其重要性不…...

Linux进程学习【基本认知】

&#x1f33c;&#x1f33c;前言&#xff1a;前言理解冯诺依曼体系结构与操作系统原理 在计算机科学的基础理论中&#xff0c;冯诺依曼体系结构和操作系统是两个关键概念&#xff0c;它们共同构成了现代计算机的运行基础。本文将从这两个方面入手&#xff0c;简要讲解它们的基本…...

电子工厂POE交换机端口数量选择与部署策略

引言 在电子工厂的智能化升级过程中&#xff0c;POE&#xff08;Power over Ethernet&#xff09;交换机凭借其“供电数据传输”一体化功能&#xff0c;成为构建工业物联网的核心设备。与传统工业交换机相比&#xff0c;POE交换机通过单根网线实现设备供电与数据交互&#xff…...

Codeforces Round 1020 (Div. 3) A-D

A. Dr. TC https://codeforces.com/contest/2106/problem/A 题目大意&#xff1a; 对输入字符串每个位置字符依次翻转&#xff08;1->0 , 0->1) 比如: 101 001 翻转位置1 111 2 100 3 题解&#xff1a; 观察数学特征&#xff1a;ansn…...

电子病历高质量语料库构建方法与架构项目(提示词设计篇)

电子病历人工智能提示词工程是医疗AI应用中的关键技术环节,它直接影响大语言模型在医疗场景下的输出质量和可靠性。随着大语言模型在电子病历生成、质控、数据提取等领域的广泛应用,如何通过编程实现高效、精准的提示词工程成为医疗信息化建设的重要课题。本文将系统介绍电子…...

蓝桥杯 4. 卡片换位

卡片换位 原题目链接 题目描述 你玩过华容道的游戏吗&#xff1f; 这是一个类似的&#xff0c;但更简单的游戏。 看下面的 3 2 格子&#xff1a; --------- | A | * | * | --------- | B | | * | ---------在其中放置了 5 张牌&#xff0c;其中&#xff1a; A 表示关…...

用python进行OCR识别

原文链接&#xff1a;https://www.bilibili.com/opus/1036675560501149699 我担心原作者删除&#xff0c;所以重新拷贝了一遍 1.下载tesseract 链接&#xff1a;https://github.com/UB-Mannheim/tesseract/wiki 这里示例安装最新版本 点击下载tesseract安装包 2.安装tess…...

【大语言模型】大语言模型(LLMs)在工业缺陷检测领域的应用

大语言模型&#xff08;LLMs&#xff09;在工业缺陷检测领域的应用场景正在快速扩展&#xff0c;结合其多模态理解、文本生成和逻辑推理能力&#xff0c;为传统检测方法提供了新的技术路径。以下是该领域的主要应用场景及相关技术进展&#xff1a; 1. 多模态缺陷检测与解释 视…...

202531读书笔记|《天上大风:良宽俳句·短歌·汉诗400》——我别无他物款待君,除了山中冬日寂寥,陶然共一醉,不知是与非,一饱百情足,一酣万事休

202531读书笔记|《天上大风&#xff1a;良宽俳句短歌汉诗400》——我别无他物款待君&#xff0c;除了山中冬日寂寥&#xff0c;陶然共一醉&#xff0c;不知是与非&#xff0c;一饱百情足&#xff0c;一酣万事休 《天上大风&#xff1a;良宽俳句短歌汉诗400》良宽是公认与松尾芭…...