C语言进阶——通讯录模拟实现
🌇个人主页:_麦麦_
📚今日名言:只有走在路上,才能摆脱局限,摆脱执着,让所有的选择,探寻,猜测,想象都生机勃勃。——余秋雨《文化苦旅》
目录
一、前言
二、正文
1.大体框架
2.界面显示
3. 创建通讯录
4.初始化通讯录
5.增加联系人
6.显示联系人
7. 删除联系人
8.查找联系人
9.修改联系人
10. 排序联系人
三、结语
一、前言
在上一章的结构体的学习中,相信小伙伴们或多或少都有所收获,但是有的小伙伴可能会问,结构体到底能用来做什么呢?今天,我们就借助结构体和之前所学的知识来实现通讯录。
二、正文
1.大体框架
相信在座的小伙伴们一定有人做过类似的小游戏或项目,编程的大忌就是将所有的代码都放在同一个文件里,写的时候有多好爽快,后期对代码进行修改和维护的时候就有痛苦。这期通讯录的实现我们大致分为三个模块,一个用于测试通讯录,即对各种函数的调用【text.c】;另一个用于通讯录的实现,其中放置着通讯录功能的具体实现【contact.c】;最后一个就是函数的声明了[contact.h].
2.界面显示
就像之前的扫雷与三子棋游戏一样,这个通讯录的第一步一定是要让使用者看到通讯录的页面,继而在使用者选择之后进行下一步的操作。因而我们仍旧采取do while 循环,先将页面显示,再根据使用者的输入进行相应的操作。具体实现代码如下:
//通讯录界面显示
void menu()
{printf("******************************\n");printf("***** 1.Add 2.Del *****\n"); //增加联系人 删除联系人printf("***** 3.Search 4.Modify *****\n"); //搜索联系人 修改联系人printf("***** 5.Show 6.Sort *****\n"); //显示联系人 排序联系人printf("*** 0.Exit *****\n"); //退出通讯录printf("******************************\n");
}int main()
{ int input = 0;do{menu(); //打印菜单printf("请选择你所需的功能:");scanf("%d", &input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;case 0:printf("退出通讯录\n");break;default:printf("输入错误,请重新输入\n");}}while (input);return 0;
}
在以上代码的逻辑下,使用者刚开始就能够看到我们设置好的界面,并进行功能的输入,如果输入为0就退出通讯录,通讯录为功能相应的数字就进行相应的功能【还未填写完整】,若为其他数字,则重新输入。
3. 创建通讯录
为了实现我们菜单中的各个功能,首先我们要有这些功能的受体——通讯录,只有创建好通讯录 ,才能进行功能的操作。在生活中,我们手机上的通讯录都存有联系人的相关信息,例如姓名,年龄,性别,手机号码等等 ,其次在后面的功能中我们还需要知道这个通讯录中联系人的数量是多少。显然,我们需要一个自定义结构变量来定义通讯录,在这个结构体中有两个变量,一个是存放联系人信息的变量,另一个是存放联系人数量的变量。而存放联系人的信息显然需要一个数组,数组的大小即对应着能存放多少联系人,而数组中的元素就是联系人的信息,这也无法用一个单一类型变量来定义,所以我们还需要额外定义一个结构体变量来代表联系人的各种信息。具体代码如下:
//结构体——联系人的信息
struct peo
{char name[20]; //姓名char sex[10]; //性别int age; //年龄 char addr[40]; //地址char tel[20]; //电话
};//结构体——通讯录
typedef struct contact
{struct peo Peo[contact_num]; //通讯录中联系人的信息int sz; //当前存放联系人的个数
}contact;
4.初始化通讯录
在通讯录的创建之后,就是对其的初始化了,为了方便,我们就都置成0就好了。
//Init_Contact——初始化通讯录void Init_Contact(contact* pc)
{pc->sz = 0;memset(pc, 0, sizeof(pc->Peo));
}
5.增加联系人
在通讯录的创建和初始化完成之后,就是通讯录功能的实现了。首先是“增加联系人”这一功能。我们先是定义一个函数,这个函数的参数就是我们的通讯录,采用传递通讯录地址的方式,返回值为空,因为我们只是对通讯录的内容进行改变,并不需要返回任何东西。然后是函数的具体实现,我们要做的是在联系人信息这一数组中添加一个联系人,并在添加之后将通讯录当前存储的联系人数量+1。此外如果通讯录已满,我们需要提醒使用者无法再添加联系人。具体代码如下:
//Add——增加联系人void Add(contact* Contact){assert(Contact);if (Contact->sz < contact_num){printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[Contact->sz]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[Contact->sz].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[Contact->sz].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[Contact->sz].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[Contact->sz].tel);Contact->sz++;}elseprintf("通讯录已满无法添加\n");}
6.显示联系人
为了观察我们在执行增加联系人这个函数是否成功,我们接下来进行“显示联系人”这一功能的实现。同样的先是定义显示联系人这一函数,函数参数是通讯录,采取传址调用的方式,无需返回任何参数。函数的实现就是依据通讯录中所存储的联系人数量,来调用存储联系人信息的数组,并将其显示在屏幕上,为了数据显示的整齐和美观,笔者对打印的数据类型进行了小小的改善,对数据所占空间进行了设置,并将数据左对齐并在数据后输出一个水平制表符。
//Show——展示联系人void Show( const contact* Contact){assert(Contact);int pos = 0; //联系人对应下标printf("%-20s\t%-10s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");for (pos = 0; pos < Contact->sz; pos++){printf("%-20s\t%-10s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);}}
7. 删除联系人
首先是“删除联系人”这一函数的定义,参数为通讯录这一结构体,采取传址调用的方式,返回参数无。继而是函数具体的实现,笔者是根据使用者所输入的所要删除联系人的姓名来找到联系人在数组中对应的下标,从而进行各项信息的删除。这里有个小技巧,无论是删除联系人,修改联系人,搜索联系人都需要在根据输入的姓名对联系人进行查找,因而我们可以将这个功能封装成一个函数,在使用这一功能的时候只需要调用就行了。具体代码实现如下:
//Find_by_name——通过姓名,找到联系人所对应的下标int Find_by_name( const contact* Contact, char *name){int i = 0;for (i = 0; i < Contact->sz; i++){if (strcmp(&(Contact->Peo[i].name),name)==0)return i;}return -1;}//Del——删除联系人void Del(contact* Contact){char name[20] = { 0 };int i = 0;printf("请输入要删除的联系人:>");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{for (i = pos; i < Contact->sz-1; i++){Contact->Peo[i] = Contact->Peo[i + 1];}Contact->sz--;}}
8.查找联系人
首先是对“查找联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再将其显示在屏幕上。具体代码如下:
//Search——搜索联系人void Search(const contact* Contact){char name[20] = {0};printf("请输入要寻找的联系人:>");scanf("%s", name);int pos= Find_by_name(Contact, &name);if (-1==pos){printf("该联系人不存在\n");return;}else{printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);} }
9.修改联系人
首先是对“修改联系人”函数的定义,函数参数为通讯录,采取传址调用的方式,返回参数为0。然后是具体功能的实现,先是根据输入的姓名查找到对应的下标,再依据添加联系人的代码实现联系人信息的修改。具体代码如下:
//Modify——修改联系人void Modify(contact* Contact){assert(Contact);char name[20] = { 0 };printf("请输入要修改的联系人\n");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[pos]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[pos].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[pos].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[pos].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[pos].tel);}}
10. 排序联系人
对联系人排序依据有很多,这里仅对联系人的年龄进行排序。采取冒泡排序的方式,冒泡排序的实现在前面的推文已经介绍过了,有兴趣的小伙伴可以康一康。https://blog.csdn.net/m0_73953114/article/details/128766018
//sort——按照年龄对联系人进行排序void sort(contact* Contact,contact* tmp){//执行冒泡排序的趟数int i = 0;for (i = 0; i < Contact->sz - 1; i++){//一趟冒泡排序中交换的次数int j = 0;for (j = 0; j < Contact->sz - 1-i; j++){if (Contact->Peo[j].age > Contact->Peo[j + 1].age){tmp->Peo[0] = Contact->Peo[j];Contact->Peo[j] = Contact->Peo[j + 1];Contact->Peo[j + 1] = tmp->Peo[0];}}}}
到这里,整个通讯录就写完了,整体的代码如下:
//main.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("*** 0.Exit *****\n");printf("******************************\n");
}int main()
{contact Contact; //创建通讯录contact tmp;Init_Contact(&Contact); //初始化通讯录Init_Contact(&tmp); int input = 0;do{menu(); //打印菜单printf("请选择你所需的功能:");scanf("%d", &input);switch (input){case 1:Add(&Contact);break;case 2:Del(&Contact);break;case 3:Search(&Contact);break;case 4:Modify(&Contact);break;case 5:Show(&Contact);break;case 6:sort(&Contact,&tmp);break;case 0:printf("退出通讯录\n");break;default:printf("输入错误,请重新输入\n");}}while (input);return 0;
}//contact.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#define contact_num 100
#include <stdio.h>
#include <string.h>
#include <assert.h>//结构体——联系人的信息
struct peo
{char name[20]; //姓名char sex[10]; //性别int age; //年龄char addr[40]; //地址char tel[20]; //电话
};
//结构体——通讯录
typedef struct contact
{struct peo Peo[contact_num]; //通讯录中联系人的信息int sz; //当前存放联系人的个数
}contact;void Init_Contact(contact* pc); //初始化通讯录
void Add(contact* Contact); //添加联系人
void Show(const contact* Contact); //展示联系人
void Search(const contact* Contact); //搜索联系人
void Del(contact* Contact); //删除联系人
void Modify(contact* Contact); //修改联系人
void sort(contact* Contact,contact* tmp); //排序联系人——年龄//contact.c
#include "contact.h"//Init_Contact——初始化通讯录void Init_Contact(contact* pc)
{pc->sz = 0;memset(pc, 0, sizeof(pc->Peo));
}//Add——增加联系人void Add(contact* Contact){assert(Contact);if (Contact->sz < contact_num){printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[Contact->sz]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[Contact->sz].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[Contact->sz].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[Contact->sz].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[Contact->sz].tel);Contact->sz++;}elseprintf("通讯录已满无法添加\n");}//Show——展示联系人void Show( const contact* Contact){assert(Contact);int pos = 0;printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n","姓名", "性别", "年龄", "地址", "电话");for (pos = 0; pos < Contact->sz; pos++){printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);}}//Find_by_name——通过姓名,找到联系人所对应的下标int Find_by_name( const contact* Contact, char *name){int i = 0;for (i = 0; i < Contact->sz; i++){if (strcmp(&(Contact->Peo[i].name),name)==0)return i;}return -1;}//Search——搜索联系人void Search(const contact* Contact){char name[20] = {0};printf("请输入要寻找的联系人:>");scanf("%s", name);int pos= Find_by_name(Contact, &name);if (-1==pos){printf("该联系人不存在\n");return;}else{printf("%-10s\t%-6s\t%-4s\t%-40s\t%-20s\n", "姓名", "性别", "年龄", "地址", "电话");printf("%-10s\t%-6s\t%-4d%\t%-40s\t%-20s\n", Contact->Peo[pos].name,Contact->Peo[pos].sex,Contact->Peo[pos].age,Contact->Peo[pos].addr,Contact->Peo[pos].tel);} }//Del——删除联系人void Del(contact* Contact){char name[20] = { 0 };int i = 0;printf("请输入要删除的联系人:>");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{for (i = pos; i < Contact->sz-1; i++){Contact->Peo[i] = Contact->Peo[i + 1];}Contact->sz--;}}//Modify——修改联系人void Modify(contact* Contact){assert(Contact);char name[20] = { 0 };printf("请输入要修改的联系人\n");scanf("%s", name);int pos = Find_by_name(Contact, &name);if (-1 == pos){printf("该联系人不存在\n");return;}else{printf("请输入联系人的姓名:>\n");scanf("%s", (Contact->Peo[pos]).name);printf("请输入联系人的性别:>\n");scanf("%s", Contact->Peo[pos].sex);printf("请输入联系人的年龄:>\n");scanf("%d", &(Contact->Peo[pos].age));printf("请输入联系人的地址:>\n");scanf("%s", Contact->Peo[pos].addr);printf("请输入联系人的电话:>\n");scanf("%s", Contact->Peo[pos].tel);}}//sort——按照年龄对联系人进行排序void sort(contact* Contact,contact* tmp){//执行冒泡排序的趟数int i = 0;for (i = 0; i < Contact->sz - 1; i++){//一趟冒泡排序中交换的次数int j = 0;for (j = 0; j < Contact->sz - 1-i; j++){if (Contact->Peo[j].age > Contact->Peo[j + 1].age){tmp->Peo[0] = Contact->Peo[j];Contact->Peo[j] = Contact->Peo[j + 1];Contact->Peo[j + 1] = tmp->Peo[0];}}}}
三、结语
关于通讯录的讲解就已经全部结束了,下期我们会分享自定义类型的其他成员!
关注我 _麦麦_分享更多干货:_麦麦_的博客_CSDN博客-领域博主
大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!
相关文章:

C语言进阶——通讯录模拟实现
🌇个人主页:_麦麦_ 📚今日名言:只有走在路上,才能摆脱局限,摆脱执着,让所有的选择,探寻,猜测,想象都生机勃勃。——余秋雨《文化苦旅》 目录 一、前言 二、正…...
【C#基础】C# 变量和常量的使用
序号系列文章1【C#基础】C# 程序通用结构总结2【C#基础】C# 程序基础语法解析3【C#基础】C# 数据类型总结文章目录前言一. 变量(variable)1,变量定义及初始化2,变量的类别3,接收输出变量二. 常量(constant&…...
nvm安装后出现‘node‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件
出现这个问题多半是path地址不对。 打开系统环境变量。看看path里面有没有?没有的话,加上就行! 我的报错原因就是因为path里没有自动加上nvm的相关路径。 注意项: 1,在安装nvm之前,提前要把本机以前安装…...

张驰咨询:关于六西格玛,有一些常见的疑惑!
很多想要学习六西格玛的学员,经常会有这些困惑: 以前没有接触过六西格玛,需要什么基础吗?自学还是培训?哪些行业会用到六西格玛呢?学习六西格玛对以后的工作有哪些帮助?如何选择六西格玛培…...

【Vercel】教你部署imsyy/home个人主页
本篇博客教你如何部署一个自己的个人主页 项目地址:https://github.com/imsyy/home 本文首发于 慕雪的寒舍 1.fork仓库vercel部署 首先我们点击fork,将仓库复刻到自己的账户 随后进入vercel,点击dashboard-add new-project 选择你复刻的仓库…...

GeekChallenge
2.GeekChallenge 1.web 1.朋友的学妹 url:http://49.234.224.119:7413/ 右键点击查看源码,找到flagU1lDe0YxQF80c19oNExwZnVsbGxsbGx9 然后base64解码得到SYC{F1_4s_h4Lpfullllll} 2.EZwww url:http://47.100.46.169:3901/ 根据网站提示…...
Java文件IO
文章目录Java中的文件操作File常用构造方法方法文件内容的读写——数据流InputStreamFileInputStream利用Scanner进行字符读取OutputStreamPrintWriter按字符读取文件(FileReader)练习代码实例如何按字节进行数据读如何按字节进行数据写如何按字符进行数据读如何按字符进行数据…...
useSSL使用安全套接字协议(史上最全最详细)
useSSL使用安全套接字协议(史上最全最详细) SSL即为:Secure Sockets Layer 安全套接字协议。 useSSLfalse和useSSLtrue的区别: 在MySQL进行连接时: 如果MySQL的版本是5.7之后的版本必须要加上useSSLfalse,…...
面向对象复习(2)
面向对象(2) 对象与引用 java语言中除基本类型之外的变量都称之为引用类型 java中的对象时通过引用对其操作的 Car bm new Car(); 右边的new Car是以Car类为模板,调用无参构造函数,在堆空间中创建一个Car对象 左边的Car bm 在栈中创建了一个Car类型的引用变量,所谓Car的…...

python中使用numpy包的向量矩阵相乘
一直对np的线性运算不太清晰,正好上课讲到了,做一个笔记整个理解一下 1.向量和矩阵 在numpy中,一重方括号表示的是向量vector,vector没有行列的概念。二重方括号表示矩阵matrix,有行列。 代码显示如下: …...
ElasticSearch 学习(一)
目录一、Elasticsearch 简介二、Elasticsearch 发展史三、Elasticsearch 功能四、Elasticsearch 特点五、Elasticsearch 应用场景一、Elasticsearch 简介 Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据…...
【新】华为OD机试 - 交换字符(Python)| 刷完获取OD招聘渠道
交换字符 题目 给定一个字符串 S 变化规则: 交换字符串中任意两个不同位置的字符 M S 都是小写字符组成 1 <= S.length <= 1000 输入 一串小写字母组成的字符串 输出 按照要求变换得到最小字符串 示例一 输入 abcdef输出 abcdef示例二 输入 bcdefa输出 acde…...

手把手教你解决传说中的NPE空指针异常
1. 前言最近有好几个初学java的小伙伴,甚至是学习到了JavaWeb、框架阶段的小伙伴也跑来问壹哥,该如何解决Java中的NullPointerException空指针异常。因为NPE是初学者特别常见的典型异常,所以壹哥在这里专门写一篇文章,来手把手地教…...

【pytorch安装】conda安装pytorch无法安装cpu版本(完整解决过程)
问题描述 在安装pytorch过程中,发现最后验证torch时总是返回结果为False,结果翻上去发现自己安装的是cpu版本的。 然后又通过conda去更换不同版本尝试,发现都是cpu版本的。 问题分析 通过conda安装pytorch是从源中搜索匹配指令中的文件&am…...

云计算ACP云服务器ECS实例题库
😘作者简介:一名99年软件运维应届毕业生,正在自学云计算课程。👊宣言:人生就是B(birth)和D(death)之间的C(choise),做好每一个选择。&…...
面试题:作用域、变量提升、块级作用域、函数作用域、暂存性死区、var和let的区别
<script>var a 10;(function () {console.log(a)a 5console.log(window.a)var a 20;console.log(a)})() </script> 上述代码: 1、主要是涉及到变量提升和函数作用域,var a20这行代码会在函数作用域中提升var a 至最顶部…...
JAVA练习49-爬楼梯
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-爬楼梯 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 前言 提示:这里可以添加本文要记录的大概内容: 2月13日练习内容…...

深兰科技机器人商丘制造基地正式投产,助力商丘经济高质量发展
2月9日,深兰科技机器人商丘制造基地投产仪式在商丘市梁园区北航创新园隆重举行。商丘市人大常委会副主任、梁园区委书记张兵,梁园区区长薛天江、河南省装备制造业协会会长张桦,河南省机器人行业协会会长王济昌,深兰科技集团董事长…...
ES倒排索引/查询、写入流程
ES学习笔记 Elasticsearch学习笔记_巨輪的博客-CSDN博客 Elasticsearch学习之图解Elasticsearch中的_source、_all、store和index属性_BUse的博客-CSDN博客 倒排索引 倒排索引:ES倒排索引底层原理及FST算法的实现过程_es fst_Elastic开源社区的博客-CSDN博客 【…...

2023软考考哪个证书好?
软考有三个级别(初级,中级和高级),这三个级别分别对应5个方向,下面这张图片呢,可以一目了然,一些小小建议!!!遵循一个原则:首先选专业对口的科目&…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...