通讯录项目实现
引言:通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。
目录
顺序表与通讯录的比较
各源文件文件大榄
Contact.c中通讯录相关函数的定义
初始化和销毁通讯录
添加联系人:
删除联系人:
打印通讯录中存储的所有的联系人的信息
查找联系人(通过名字)
修改联系人的信息
保存顺序表的内容
将文件的内容读入顺序表
将通讯录中的联系人的信息写入文件
优化后的的通讯录初始化和销毁函数
test.c
SeqList.h
SeqList.c
Contact.h
Contact.c
结语:
顺序表与通讯录的比较
通讯录的底层逻辑就是顺序表,与存储int数据的顺序表相比,通讯录这个结构体存储的每个元素的类型为结构体,并且这个结构体定义的是每个联系人的基本信息。
图解:
各源文件文件大榄
SeqList.h | 顺序表的结构的声明,顺序表相关函数的声明,#define定义的符号 |
SeqList.c | 顺序表函数的定义 |
Contact.h | 通讯录中每个联系人的结构的定义,通讯录相关函数的声明 |
Contact.c | 通讯录相关函数的定义 |
test.c | 可以测试,通讯录的流程实现 |
Contact.h
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADRR_MAX 20//联系人的信息的结构
typedef struct personInfo
{char name[NAME_MAX];//姓名char gender[GENDER_MAX];//性别int age;//年龄char tel[TEL_MAX];//电话char addr[ADRR_MAX];//家庭地址
}peoInfo;typedef struct SeqList Contact;//前置声明,将顺组表中的struct SeqList 改为 Contact 增加代码的可读性
//初始化和销毁
void ContactInit(Contact* ps);
void ContactDestory(Contact* ps);//添加和删除
void ContactAdd(Contact* ps);
void ContactDel(Contact* ps);//打印通讯录中的联系人
void ContactPrint(Contact* ps);//修改联系人的信息
void ContactModify(Contact* ps);//查找想要查找的联系人
void ContactFind(Contact* ps);//将文件的信息加载进通讯录
void ContactLoad(Contact* ps);
//销毁通讯录前将通讯录中的信息写入文件
void ContactSave(Contact* ps);
SeqList.h
#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"//顺序表中存储的元素的类型为定义的联系人的结构体
#define SLDataType peoInfo
typedef struct SeqList
{SLDataType* arr;int size;int capacity;
}SL;//初始化
void SLInit(SL* ps);
void SLDestory(SL* ps);
//打印
//void SLPrint(SL ps);
//尾插,尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//尾删,头删
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);
//任意插,任意删
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
Contact.c中通讯录相关函数的定义
初始化和销毁通讯录
//初始化
void ContactInit(Contact* ps)
{SLInit(ps);
}
//销毁
void ContactDestory(Contact* ps)
{SLDestory(ps);
}
直接通过顺序表的初始化和销毁实现就可以了。
添加联系人:
void ContactAdd(Contact* ps)
{peoInfo s;//先定义一个联系人的变量存储要添加的联系人的信息printf("请输入要添加的联系人姓名:\n");scanf("%s", s.name);printf("请输入要添加联系人的性别:\n");scanf("%s", s.gender);printf("请输入要添加联系人的年龄:\n");scanf("%d", &s.age);printf("请输入要添加联系人的电话:\n");scanf("%s", s.tel);printf("请输入要添加联系人的地址:\n");scanf("%s", s.addr);SLPushFront(ps, s);//顺序表的头插,这里用尾插也可以
}
注意:用顺序表的头插或尾插将联系人的信息插入进通讯录.
删除联系人:
//通过名字在通讯录中找到要删除的人
int FindByName(Contact* ps, char* name)
{for (int i = 0; i < ps->size; i++){if (strcmp(ps->arr[i].name, name) == 0)return i;}return -1;
}//删除一个联系人
void ContactDel(Contact* ps)
{char name[NAME_MAX];printf("请输入你要删除的联系人的姓名:\n");scanf("%s",name);//如果通过名字找到联系人则返回存储该联系人的下标int find = FindByName(ps, name);if (find < 0){printf("你的通讯录中没有您要删除的人\n");return;}//通过顺序表的任意删除函数删除SLErase(ps, find);
}
问题:如何删除一个联系人呢?
首先,你需要给出这个联系人的名字或手机号,或家庭地址,通过这些信息找到这个联系人在顺序表中存储的位置;然后,在通过下标,利用顺序表的任意删除顺序表中的数据,删除该联系人。
这里再讲一下FindByName 函数,如果顺序表中存储的联系人的结构体的名字中有这个名字,则返回在顺序表中存储该联系人的下标;若没找到,则返回一个比0小的数。
打印通讯录中存储的所有的联系人的信息
预期结果:
实现代码:
void ContactPrint(Contact* ps)
{printf("%-5s%-5s%-5s%-5s%-5s\n", "姓名", "性别", "年龄", "电话", "家庭地址");for (int i = 0; i < ps->size; i++){printf("%-5s%-5s%-5d%-5s%-5s\n",ps->arr[i].name,ps->arr[i].gender,ps->arr[i].age,ps->arr[i].tel,ps->arr[i].addr);}}
这里代码比较简单,就不多说了。
查找联系人(通过名字)
//通过名字在顺序表中查询
int FindByName(Contact* ps, char* name)
{for (int i = 0; i < ps->size; i++){if (strcmp(ps->arr[i].name, name) == 0)return i;}return -1;
}//查找联系人
void ContactFind(Contact* ps)
{char name[NAME_MAX];printf("请输入想要查找的联系人的姓名:\n");scanf("%s", name);int find = FindByName(ps, name);//通过名字查找if (find < 0){printf("你想要查找的联系人的姓名不在通讯录中\n");return;}//找到了该联系人则打印一下这个联系人的信息printf("%-5s%-5s%-5s%-5s%-5s\n","姓名", "性别", "年龄", "电话", "家庭地址");printf("%-5s%-5s%-5d%-5s%-5s\n",ps->arr[find].name,ps->arr[find].gender,ps->arr[find].age,ps->arr[find].tel,ps->arr[find].addr);
}
这里的查找只是通过名字查找,你也可以通过电话,或家庭地址查找。
修改联系人的信息
void ContactModify(Contact* ps)
{char name[NAME_MAX];printf("请输入想要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(ps, name);if (find < 0){printf("你想要修改的联系人的姓名不在通讯录中\n");return;}printf("请输入要添加的联系人姓名:\n");scanf("%s", ps->arr[find].name);printf("请输入要添加联系人的性别:\n");scanf("%s", ps->arr[find].gender);printf("请输入要添加联系人的年龄:\n");scanf("%d", &ps->arr[find].age);printf("请输入要添加联系人的电话:\n");scanf("%s", ps->arr[find].tel);printf("请输入要添加联系人的地址:\n");scanf("%s", ps->arr[find].addr);
}
实现思路:通过名字找到你想要修改的联系人在顺序表中存储的下标,有了下标就可以直接对这个位置的数据进行修改。
保存顺序表的内容
每次程序运行完,通讯录中的数据就会丢失,如何在下次运行程序时,继续使用上次的程序呢?
在每次销毁顺序表之前将通讯录中联系人的信息写入一个文件,每次初始化通讯录后将文件的内容读入通讯录就可以了。
将文件的内容读入顺序表
void ContactLoad(Contact* ps)
{FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return;}peoInfo s;//定义一个联系人的变量存储每次从文件中读出的联系人的信息while (fread(&s, sizeof(peoInfo), 1, pf))//每次读一个联系人的信息直至没有联系人的信息可以读{SLPushFront(ps, s);//将联系人的信息写入通讯录}fclose(pf);pf = NULL;
}
将通讯录中的联系人的信息写入文件
void ContactSave(Contact* ps)
{assert(ps);FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return;}fwrite(ps->arr, sizeof(peoInfo), ps->size, pf);//将通讯录中size个联系人的数据,也就是所有联系人的数据写入文件fclose(pf);pf = NULL;
}
优化后的的通讯录初始化和销毁函数
void ContactInit(Contact* ps)
{SLInit(ps);ContactLoad(ps);
}void ContactDestory(Contact* ps)
{ContactSave(ps);SLDestory(ps);
}
test.c
void menu()
{printf("************************************\n");printf("****1.添加联系人****2.删除联系人****\n"); printf("****3.修改联系人****4.查找联系人****\n");printf("****5.展示联系人****0. 退出 ****\n");}
int main()
{//ContactTest1();Contact s;ContactInit(&s);//初始化并载入文件中的联系人数据int op;do{menu();printf("请输入你的操作:\n");scanf("%d", &op);switch (op){case 1:ContactAdd(&s);break;case 2:ContactDel(&s);break;case 3:ContactModify(&s);break;case 4:ContactFind(&s);break;case 5:ContactPrint(&s);break;case 0:printf("退出.....emo\n");break;default:printf("你在干什么?请输入正确的操作数:\n");break;}} while (op);//销毁并肩现在通讯录中联系人的信息写入文件ContactDestory(&s);return 0;
}
SeqList.h
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"#define SLDataType peoInfo
typedef struct SeqList
{SLDataType* arr;int size;int capacity;
}SL;//初始化
void SLInit(SL* ps);
void SLDestory(SL* ps);
//打印
//void SLPrint(SL ps);
//尾插,尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);
//尾删,头删
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);
//任意插,任意删
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
SeqList.c
#include "SeqList.h"void CheckSLCapacity(SL* ps)
{if (ps->capacity == ps->size){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("realloc");exit(-1);}//开辟成功ps->arr = tmp;ps->capacity = newcapacity;}
}void SLInit(SL* ps)
{assert(ps);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}void SLDestory(SL* ps)
{assert(ps);free(ps->arr);ps->arr = NULL;ps->size = 0;ps->capacity = 0;
}//void SLPrint(SL s)
//{
// for (int i = 0; i < s.size; i++)
// printf("%d ", s.arr[i]);
// printf("\n");
//}void SLPushBack(SL* ps, SLDataType x)
{assert(ps != NULL);CheckSLCapacity(ps);ps->arr[ps->size] = x;ps->size++;
}void SLPushFront(SL* ps, SLDataType x)
{assert(ps != NULL);CheckSLCapacity(ps);for (int i = ps->size; i>0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}void SLPopBack(SL* ps)
{assert(ps != NULL);assert(ps->size > 0);ps->size--;
}void SLPopFront(SL* ps)
{assert(ps != NULL);assert(ps->size > 0);for (int i = 0; i <ps->size-1 ; i++)ps->arr[i] = ps->arr[i + 1];ps->size--;
}void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);CheckSLCapacity(ps);for (int i = ps->size; i>pos ; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[pos] = x;ps->size++;
}void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;}
Contact.h
#pragma once
#define NAME_MAX 20
#define GENDER_MAX 20
#define TEL_MAX 20
#define ADRR_MAX 20typedef struct personInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char addr[ADRR_MAX];
}peoInfo;typedef struct SeqList Contact;
//初始化和销毁
void ContactInit(Contact* ps);
void ContactDestory(Contact* ps);//添加和删除
void ContactAdd(Contact* ps);
void ContactDel(Contact* ps);//打印通讯录中的联系人
void ContactPrint(Contact* ps);//修改联系人的信息
void ContactModify(Contact* ps);//查找想要查找的联系人
void ContactFind(Contact* ps);//将文件的信息加载进通讯录
void ContactLoad(Contact* ps);
//销毁通讯录前将通讯录中的信息写入文件
void ContactSave(Contact* ps);
Contact.c
#include "SeqList.h"//这个文件中有Contact的定义void ContactInit(Contact* ps)
{SLInit(ps);ContactLoad(ps);
}void ContactDestory(Contact* ps)
{ContactSave(ps);SLDestory(ps);
}void ContactAdd(Contact* ps)
{peoInfo s;printf("请输入要添加的联系人姓名:\n");scanf("%s", s.name);printf("请输入要添加联系人的性别:\n");scanf("%s", s.gender);printf("请输入要添加联系人的年龄:\n");scanf("%d", &s.age);printf("请输入要添加联系人的电话:\n");scanf("%s", s.tel);printf("请输入要添加联系人的地址:\n");scanf("%s", s.addr);SLPushFront(ps, s);
}int FindByName(Contact* ps, char* name)
{for (int i = 0; i < ps->size; i++){if (strcmp(ps->arr[i].name, name) == 0)return i;}return -1;
}void ContactDel(Contact* ps)
{char name[NAME_MAX];printf("请输入你要删除的联系人的姓名:\n");scanf("%s",name);int find = FindByName(ps, name);if (find < 0){printf("你的通讯录中没有您要删除的人\n");return;}SLErase(ps, find);
}void ContactPrint(Contact* ps)
{printf("%-5s%-5s%-5s%-5s%-5s\n", "姓名", "性别", "年龄", "电话", "家庭地址");for (int i = 0; i < ps->size; i++){printf("%-5s%-5s%-5d%-5s%-5s\n",ps->arr[i].name,ps->arr[i].gender,ps->arr[i].age,ps->arr[i].tel,ps->arr[i].addr);}}void ContactModify(Contact* ps)
{char name[NAME_MAX];printf("请输入想要修改的联系人的姓名:\n");scanf("%s", name);int find = FindByName(ps, name);if (find < 0){printf("你想要修改的联系人的姓名不在通讯录中\n");return;}printf("请输入要添加的联系人姓名:\n");scanf("%s", ps->arr[find].name);printf("请输入要添加联系人的性别:\n");scanf("%s", ps->arr[find].gender);printf("请输入要添加联系人的年龄:\n");scanf("%d", &ps->arr[find].age);printf("请输入要添加联系人的电话:\n");scanf("%s", ps->arr[find].tel);printf("请输入要添加联系人的地址:\n");scanf("%s", ps->arr[find].addr);
}void ContactFind(Contact* ps)
{char name[NAME_MAX];printf("请输入想要查找的联系人的姓名:\n");scanf("%s", name);int find = FindByName(ps, name);if (find < 0){printf("你想要查找的联系人的姓名不在通讯录中\n");return;}printf("%-5s%-5s%-5s%-5s%-5s\n","姓名", "性别", "年龄", "电话", "家庭地址");printf("%-5s%-5s%-5d%-5s%-5s\n",ps->arr[find].name,ps->arr[find].gender,ps->arr[find].age,ps->arr[find].tel,ps->arr[find].addr);
}void ContactLoad(Contact* ps)
{FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return;}peoInfo s;while (fread(&s, sizeof(peoInfo), 1, pf)){SLPushFront(ps, s);}fclose(pf);pf = NULL;
}void ContactSave(Contact* ps)
{assert(ps);FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return;}fwrite(ps->arr, sizeof(peoInfo), ps->size, pf);fclose(pf);pf = NULL;
}
最终结果展示:
第一次写:
写完之后文件中有一个联系人: 22 22 22 22 22 22
文件的内容:
第二次使用程序:
结语:
总算写完了,现在脑袋还是昏昏的,哈哈哈哈.
下次的项目就是贪吃蛇了。
相关文章:

通讯录项目实现
引言:通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。 目录 顺序表与通讯录的比较 各源文件文件大榄 Contact.c中通讯录相关函数的定义 初始化和销毁通讯录 添加联系人: 删除联系人…...
xss相关知识点与绕过思路总结
前言 对xss的绕过进行了系统的学习与实践后,重新审视一下xss,对他的绕过进行一个总结。 (当然我也是个小白,这些也是我当时瞎鸡儿乱搞绕过了几个xss自己做的小总结) 可能有点丑陋,献丑了。 好博客推荐 …...
深入解析语言模型:原理、实战与评估
引言 随着人工智能的飞速发展,语言模型作为自然语言处理(NLP)的核心技术之一,日益受到业界的广泛关注。本文旨在深入探讨语言模型的原理、实战应用以及评估方法,帮助读者更好地理解和应用这一技术。 一、语言模型原理…...
Elasticsearch 的索引优化常规项
优化常规项 https://blog.csdn.net/bairo007/article/details/132019575 1、按实际情况适当调整主分片的数量 如果主分片数量太少,会导致每个分片中的数据量过大,而且无法利用集群中所有节点的计算资源。如果主分片数量太多,会导致索引过度…...
【JavaParser笔记01】JavaParser解析Java源代码中的类信息(javadoc注释、类名称)
这篇文章,主要介绍如何使用JavaParser解析Java源代码中的类信息(javadoc注释、类名称)。 目录 一、JavaParser依赖库 1.1、引入依赖 1.2、获取类注释信息...

Stable Diffusion扩散模型【详解】小白也能看懂!!
文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导,需要参考这篇文章: Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…...
关于rabbitmq的prefetch机制
消息预取机制(Prefetch Mechanism)是RabbitMQ中用于控制消息传递给消费者的一种机制。它定义了在一个信道上,消费者允许的最大未确认的消息数量。一旦未确认的消息数量达到了设置的预取值,RabbitMQ就会停止向该消费者发送更多消息…...
机器学习介绍
机器学习是人工智能(AI)的一个分支,它使计算机系统能够从数据中学习并改进它们的性能。机器学习的核心在于开发算法,这些算法可以从大量数据中识别模式和特征,并用这些信息来做出预测或决策,而无需进行明确…...

OpenCV4.9开发之Window开发环境搭建
1.打开OpenCV所在github地址 2.点击opencv仓库,进入仓库详情,点击右下方的OpenCV 4.9.0进入下载页面 3.点击opencv-4.9.0-windows.exe下载 开始下载中... 下载完成 下载完成后,双击运行解压,默认解压路径,修改为c:/...
DDD 中的实体和值对象有什么区别?
在DDD中,实体 Entity 和值对象 Value Object 是两个基本的概念,它们之间有一些重要的区别。 唯一性:实体是唯一的,每个实体都有一个唯一的标识符,即使它的属性在一段时间内发生了变化,它仍然是这个实体。与…...

算法-最值问题
#include<iostream> using namespace std; int main() {int a[7];//上午上课时间int b[7];//下午上课时间int c[7];//一天总上课时间for (int i 0; i < 7; i) {cin >> a[i] >> b[i];c[i] a[i] b[i];}int max c[0];//max记录最长时间int index -1;//索…...
Go 性能压测工具之wrk介绍与使用
在项目正式上线之前,我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug;压力测试(压测)是确保系统在高负载情况下仍能稳定运行的重要步骤。通过模拟高并发场景,可以评估系统的性能瓶颈、可靠…...
数学思想论(有目录)
数学思想是数学发展过程中的重要指导原则,它涉及对数学概念、方法和理论的理解和认识,以及如何利用这些工具来解决实际问题。数学思想的形成和演进是随着数学的发展而逐渐深化的,它体现了人类对数学本质和应用的不断探索和思考。 一些主要的数学思想包括: 函数与方程思想…...

C++的并发世界(五)——线程状态切换
0.线程状态 初始化:该线程正在被创建; 就绪:该线程在列表中就绪,等待CPU调度; 运行:该线程正在运行; 阻塞:该线程被阻塞挂机,Blocked状态包括:pendÿ…...

C语言——指针
地址是由物理的电线上产生的,能够标识唯一一个内存单元。在C语言中,地址也叫做指针。 在32位机器中,有32根地址线。地址是由32个0/1组成的二进制序列,也就是用4个字节来存储地址。 在64位机器中,有64根地址线。地址是…...
手搓二分查找
第一种: 该种方法是若a[mid]目标数,则让r一直等于mid,让l往右移动,一直移动到rl,这时候跳出循环,在循环外判断 但是不能写成让lmid,让r往左移动,比如a[2]key,这时&#x…...

pycharm调试(步过(Step Over)、单步执行(Step Into)、步入(Step Into)、步出(Step Out))
pycharm调试 pycharm调试 pycharm调试为什么要学会调试?1. 步过 (Step Over)2. 单步执行 (Step Into)3. 步入(Step Into)4. 步出(Step Out) 为什么要学会调试? 调试可以帮助初学者更深入地理解编程基础&am…...

Linux是什么,该如何学习
🐇明明跟你说过:个人主页 🏅个人专栏:《Linux :从菜鸟到飞鸟的逆袭》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Linux的起源与发展 2、Linux在现代计算机领域…...

C++ | Leetcode C++题解之第7题整数反转
题目: 题解: class Solution { public:int reverse(int x) {int rev 0;while (x ! 0) {if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {return 0;}int digit x % 10;x / 10;rev rev * 10 digit;}return rev;} };...

Linux------一篇博客了解Linux最常用的指令
🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:Linux 🤝希望本文对您有所裨益,如有不足之处&#…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...