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

学C的第三十一天【通讯录的实现】

=========================================================================

相关代码gitee自取:C语言学习日记: 加油努力 (gitee.com)

 =========================================================================

接上期

学C的第三十天【自定义类型:结构体、枚举、联合】_高高的胖子的博客-CSDN博客

 =========================================================================

                     

通讯录需求:

             

实现一个通讯录

通讯录中存放保存人的信息

名字年龄性别

电话地址

             

        通讯录相关功能

  • 通讯录中可以存放100个人的信息
  • 增加联系人
  • 删除指定联系人
  • 修改指定联系人
  • 查找指定联系人
  • 显示所有联系人的信息
  • 排序功能

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

多文件实现通讯录

(1). contact.h文件 -- 相关函数和结构体类型的声明:

               

1 . 结构体 struct PeoInfo -- 存放通讯录联系人的信息:

                

使用 typedef 重命名结构体

struct PeoInfo 重命名PeoInfo

方便后续使用

              

图示:

              

              

2 . 结构体 struct contact -- 通讯录类型:

                

使用 typedef 重命名结构体, 

                     

创建通讯录信息结构体变量数组

                    

创建一个变量来记录当前通讯录data的人数

                      

图示:

                     

              

3 . 函数 InitContact() 的声明 -- 初始化通讯录类型变量

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                   

图示:

                     

              

4 . 函数 AddContact() 的声明 -- 增加通讯录成员:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

              

5 . 对常量使用进行优化 -- 设置 全局变量 和 枚举

                 

(一). 

设置 全局变量

contact.h 中,

定义全局变量 MAX 100 -- 设置通讯录最多人数,

其它通讯录信息也是同理

图示:

                

(二). 

设置 枚举

对测试中,用户输入的选项进行枚举

用对应的功能名字代表对应的选项

                 

在 contact.h 文件中设置好后,

在 test.c 文件中进行修改

图示:

                     

              

6 . 函数 ShowContact() 的声明 -- 打印通讯录所有成员信息:

                

参数接收 -- const Contact* pc

只是打印,不用修改所以设置为常量

           

返回类型 -- void

                  

图示:

                     

              

7 . 函数 FindByName() 的声明 -- 删除指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址 要查找的名字字符串

返回类型 -- int,返回找到的元素下标 或 未找到情况的-1

         

注:

该函数只在 contact.c文件 中支持其它函数,
为了保密可以不在该文件声明

               

图示:

                     

              

8 . 函数 DelContact() 的声明 -- 删除指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

                     

9 . 函数 SearchContact() 的声明 -- 查找指定通讯录成员信息:

                

参数接收 -- const Contact* pc

只是打印,不用修改所以设置为常量

           

返回类型 -- void

                   

图示:

                     

              

10 . 函数 ModifyContact() 的声明 -- 查找指定通讯录成员信息:

                

参数接收 -- 通讯录类型变量地址

返回类型 -- void

                 

图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1//contact.h文件 -- 相关函数和类型的声明://包含头文件:
#include <string.h>
#include <assert.h>
#include <stdio.h>//定义全局变量 MAX 100 -- 设置通讯录最多人数
#define MAX 100
//通讯录信息也是同理:
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30//对测试中,用户输入的选项进行枚举,
//用对应的功能名字代表对应的选项:
enum OPTION
{//枚举中的内容默认0开始往后排:EXIT,	// 0 对应 退出ADD,	// 1 对应 增加DEL,	// 2 对应 删除SEARCH, // 3 对应 搜索MODIFY, // 4 对应 修改SHOW,	// 5 对应 显示所有SORT	// 6 对应 排序
};//1.结构体 struct PeoInfo -- 存放保存人的信息:
//使用 typedef 重命名结构体,
typedef struct PeoInfo
{char name[MAX_NAME]; //名字int age; //年龄char sex[MAX_SEX]; //性别char tele[MAX_TELE]; //电话char addr[MAX_ADDR]; //地址
}PeoInfo;//2.结构体 struct contact -- 通讯录类型:
//使用 typedef 重命名结构体,
typedef struct contact
{//创建通讯信息录结构体变量数组:PeoInfo data[MAX];//创建一个变量来记录当前通讯录data的人数:int sz;
}Contact;//3.函数 InitContact() 的声明 -- 初始化通讯录类型变量
void InitContact(Contact* pc);//4.函数 AddContact() 的声明 -- 增加通讯录成员:
void AddContact(Contact* pc);//6.函数 ShowContact() 的声明 -- 打印通讯录所有成员信息:
void ShowContact(const Contact* pc);//7.函数 FindByName() 的声明 -- 删除指定通讯录成员信息:
//该函数只在 contact.c文件 中支持其它函数,
//为了保密可以不在该文件声明
int FindByName(Contact* pc, char name[]);//8.函数 DelContact() 的声明 -- 删除指定通讯录成员信息:
void DelContact(Contact* pc);//9.函数 SearchContact() 的声明 -- 查找指定通讯录成员信息:
void SearchContact(const Contact* pc);//10 . 函数 ModifyContact() 的声明 -- 查找指定通讯录成员信息:
void ModifyContact(Contact* pc);

                     

————————————————————————————————————————

                    

(2). contact.c文件 -- 自定义函数的实现:

              

1 . 函数 InitContact() -- 初始化通讯录类型变量

                

contact.h文件包含 <string.h> 头文件

再在 contact.c文件包含通讯录函数声明头文件:<contact.h>

              

使用 memset系统函数初始化data数组

参数1被设置的空间 -- data

参数2要设置的值 -- 0 (全部初始化为0)

参数3要设置的空间大小 -- sizeof(pc->data) ,直接计算出大小

                    

联系人个数 sz 初始化为0

                   

图示:

                     

              

2 . 函数 AddContact() -- 增加通讯录成员:

                

增加的前提还没放满

判断通讯录是否人数已满

                 

如果未满则开始添加信息

sz data数组 的下标对应的,
所以可以通过 sz 找到 data 的对应元素
通过对应元素找到对应元素的相应信息

如果对应的信息是数组,可以不加 取地址符&

使用 scanf()函数 将信息放进去

               

添加完一个联系人后,将指针移向下一个联系人位置

               

打印添加成功信息

                   

图示:

                     

              

3 . 函数 ShowContact() -- 打印通讯录所有成员信息:

                

打印列标题

再使用 for循环 循环打印信息

注意巧用 printf()函数

            

图示:

                     

              

4 . 函数 FindByName() -- 删除指定通讯录成员信息:

                

使用 for循环 循环在通讯录中查找该人坐标

使用 strcmp函数 进行判断名字是否存在

如果找到了则返回下标未找到则返回-1

                

图示:

                     

              

5 . 函数 DelContact() -- 删除指定通讯录成员信息:

                

判断通讯录是否为空为空没法删除则直接返回

                

不为空

输入接收删除的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了删除该下标的联系人

            

删除后,将指针向前移一位

            

最后打印删除成功

                 

图示:

                     

              

6 . 函数 SearchContact() -- 查找指定通讯录成员信息:

                

输入接收查找的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了打印该下标的联系人信息

               

图示:

                     

              

7 . 函数 ModifyContact() -- 查找指定通讯录成员信息:

                

输入接收修改的联系人名字

                 

调用 FindByName()函数 在通讯录中查找该人下标

               

未找到打印相应信息并返回

         

找到了修改该下标联系人信息

               
 图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1//contact.c文件 -- 自定义函数的实现://包含头文件:
#include "contact.h"//1.函数 InitContact() --初始化通讯录类型变量
void InitContact(Contact* pc)
{//断言:assert(pc);memset(pc->data, 0, sizeof(pc->data));/*使用 memset系统函数,初始化data数组。参数1:被设置的空间 -- data参数2:要设置的指-- 0 (全部初始化为0)参数3:要设置的空间大小-- sizeof(pc->data) ,直接计算出大小*///联系人个数初始化为0:pc->sz = 0;
}//2.函数 AddContact() 的声明 -- 增加通讯录成员:
void AddContact(Contact* pc)
{//断言:assert(pc);//增加的前提是还没放满:if (pc->sz == MAX){printf("通讯录已满,无法添加\n");//无法添加直接返回:return;}//没满则开始增加信息:// sz 和 data数组 的下标是对应的,// 所以可以通过 sz 找到 data 的对应元素,// 再通过对应元素找到对应元素的相应信息// 如果对应的信息是数组。可以不加&//名字:printf("请输入名字:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pc->sz].name);//年龄:printf("请输入年龄:>");//使用 scanf()函数 将信息放进去scanf("%d", &pc->data[pc->sz].age);//性别:printf("请输入性别:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pc->sz].sex);//电话:printf("请输入电话:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pc->sz].tele);//地址:printf("请输入地址:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pc->sz].addr);//添加完一个联系人后,将指针移向下一个联系人位置:pc->sz++;//打印添加成功信息:printf("成功添加联系人\n");
}//3 . 函数 ShowContact() -- 打印通讯录所有成员信息:
void ShowContact(const Contact* pc)
{//断言:assert(pc);printf("\n");//打印列标题:printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");//使用 for循环 循环打印信息:int i = 0;for (i = 0; i < pc->sz; i++){printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);// %20S:打印20个字符,这里名字是20个字符// \t: 使用制表符进行对齐// %4d:打印4个整型,这里是年龄// “-”号 :左对齐}printf("\n");}//4 . 函数 FindByName() -- 删除指定通讯录成员信息:
int FindByName(const Contact* pc, char name[])
{//遍历查找该人坐标:int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)//如果 找到了一个下标元素的name 和 要找的name 一样{return i; //返回此时找到的下标}}return -1; //未找到则返回-1
}//5 . 函数 DelContact() --删除指定通讯录成员信息:
void DelContact(Contact* pc)
{//断言:assert(pc);//先判断通讯录是否为空:if (pc->sz == 0){//为空就没法删除了,直接返回printf("通讯录为空,无法删除\n");return;}//创建存放要删除联系人名字的字符数组:char name[MAX_NAME] = { 0 };//输入并接收删除联系人名字:printf("请输入要删除的人名字:>");scanf("%s", name);//因为在通讯录中查找某人是多个功能所需要的,//所以可以将其封装成函数,再调用:int del = FindByName(pc, name);//如果del为-1,说明未找到:if (del == -1){printf("要删除的人不存在\n");return; //直接返回}//如果找到了则删除坐标为del的联系人:int i = 0;for (i = del; i < pc->sz-1; i++)//从del下标开始,到倒数第二个元素{pc->data[i] = pc->data[i + 1];//把del后1个元素赋给del,循环覆盖掉del的元素//倒数第二个元素+1 为最后一个元素为止}//删除一个后,将pc指针向前移一位:pc->sz--;//打印提示:printf("成功删除该联系人\n");
}//6 . 函数 SearchContact() -- 查找指定通讯录成员信息:
void SearchContact(const Contact* pc)
{//断言:assert(pc);//创建存放要查找的联系人名字的字符数组:char name[MAX_NAME] = { 0 };//输入并接收要查找联系人名字:printf("请输入要查找的联系人名字:>");scanf("%s", name);//使用 FindByName() 函数查找该人在通讯录中的下标:int pos = FindByName(pc, name);//如果del为-1,说明未找到:if (pos == -1){printf("要查找的人不存在\n");return; //直接返回}else //找到了则打印该人信息: {//打印列标题:printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n","名字", "年龄", "性别", "电话", "地址");//打印对应信息:printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);}}//7 . 函数 ModifyContact() -- 查找指定通讯录成员信息:
void ModifyContact(Contact* pc)
{//断言:assert(pc);//创建存放要修改的联系人名字的字符数组:char name[MAX_NAME] = { 0 };//输入并接收要修改联系人名字:printf("请输入要修改的联系人名字:>");scanf("%s", name);//使用 FindByName() 函数查找该人在通讯录中的下标:int pos = FindByName(pc, name);//如果del为-1,说明未找到:if (pos == -1){printf("要修改的人不存在\n");return; //直接返回}else //找到了则修改该人信息: {//名字:printf("请输入名字:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pos].name);//年龄:printf("请输入年龄:>");//使用 scanf()函数 将信息放进去scanf("%d", &pc->data[pos].age);//性别:printf("请输入性别:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pos].sex);//电话:printf("请输入电话:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pos].tele);//地址:printf("请输入地址:>");//使用 scanf()函数 将信息放进去scanf("%s", pc->data[pos].addr);printf("修改成功\n");}
}

                     

————————————————————————————————————————

                    

(3). test.c文件 -- 测试通讯录:

              

1 . 函数 void menu() -- 打印通讯录菜单:

                

告知使用者输入对应数字实现对应功能

               

图示:

                     

              

2 . 函数 void test() -- 完成通讯录测试:

                

(一). 

使用 do while 循环

                  

打印菜单

              

根据输入的选项判断是否需要再进行服务

可以使用 switch 语句进行筛选判断

图示:

             

(二).

包含<contact.h>头文件

通过结构体 struct contact (Contact),

创建通讯录类型变量 -- con

包含data数组,存放有效的通讯录数据

sz,记录存放数据的个数

                    

创建后还需要初始化

调用 函数InitContact() 进行初始化

参数接收通讯录类型变量的地址 -- &con

图示:

               

(三).

如果用户输入 1

则调用 函数AddContact()

增加联系人,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 2 ,

则调用 函数DelContact()

删除指定通讯录成员,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 3 ,

则调用 函数SearchContact()

查找指定联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 4 ,

则调用 函数ModifyContact()

修改指定联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 5 ,

则调用 函数ShowContact()

打印所有联系人信息,

参数接收 &con 对通讯录进行对应操作

            

如果用户输入 0

打印对应信息退出程序

               

如果用户 输入非法 

打印对应信息重新输入

              

图示:

                     

              

3 . 主函数

                

直接调用 test()测试函数即可

                

图示:

                     

该文件对应代码:

#define _CRT_SECURE_NO_WARNINGS 1//test.c文件 -- 测试通讯录://包含<contact.h>头文件:
#include "contact.h"//1 . 函数 void menu() -- 打印通讯录菜单:
void menu()
{// 选1:增加联系人		选2:删除联系人// 选3:搜索联系人		选4:修改联系人信息// 选5:显示所有联系人	选6:对联系人进行排序//				选0:退出通讯录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");
}//函数 void test() -- 完成通讯录测试:
void test()
{//创建通讯录类型变量:Contact con;//调用函数初始化通讯录类型变量:InitContact(&con);int input = 0;//接收输入的数据do{//调用菜单函数打印菜单:menu();//接收输入数据:printf("请选择:>");scanf("%d", &input);//使用switch语句进行筛选判断:switch (input){case ADD://如果用户输入1,//则调用AddContact()函数//添加联系人:AddContact(&con);//参数接收 &con ,对通讯录进行对应操作break;case DEL://如果用户输入2,//则调用DelContact()函数//删除指定联系人:DelContact(&con);//参数接收 &con ,对通讯录进行对应操作break;case SEARCH://如果用户输入3,//则调用SearchContact()函数//查找指定联系人:SearchContact(&con);//参数接收 &con ,对通讯录进行对应操作break;case MODIFY://如果用户输入 4 ,//则调用ModifyContact()函数//修改指定联系人信息ModifyContact(&con);//参数接收 &con ,对通讯录进行对应操作break;case SHOW://如果用户输入5,//则调用ShowContact()函数//打印所有联系人信息:ShowContact(&con);//参数接收 &con ,对通讯录进行对应操作break;case SORT://待定break;case EXIT://如果用户输入0,//打印对应信息并退出程序:printf("退出通讯录\n");break;default://如果用户 输入非法,//打印对应信息并程序输入:printf("选择错误,重新选择\n");break;}} while (input);//只要输入数据不为0就继续进行
}//主函数:
int main()
{//调用测试函数进行测试:test();return;
}

             

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

最终实现效果:

相关文章:

学C的第三十一天【通讯录的实现】

相关代码gitee自取&#xff1a;C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十天【自定义类型&#xff1a;结构体、枚举、联合】_高高的胖子的博客-CSDN博客 通讯录需求&#xff1a; 实现一个通讯录&#xff0c; 通讯录中存放保存人的信息&#xff1…...

Linux操作系统学习,Linux基础命令大全

目录 第一章、Linux简介和安装1.1&#xff09;Linux简介和分类1.2&#xff09;安装VMware虚拟机&#xff0c;在虚拟机中安装CentOS 7 第二章、虚拟机中Linux的IP地址配置详解2.1&#xff09;什么是IP地址&#xff0c;如何查看2.2&#xff09;虚拟机NAT模式中Linux的IP地址设置有…...

【软件测试】说说你对TDD测试驱动开发的理解?

很多公司在面测试中高级岗时&#xff0c;都会不同程度地问到“有没有了解过TDD”“你认为TDD可以解决什么问题”或者“说说测试驱动开发的流程”等等&#xff0c;即使公司并不会用到此开发流程&#xff0c;面试官也会通过你对这个相对还比较“陌生”的概念的讲述来了解你对一些…...

B. Binary Cafe(二进制的妙用)

题目&#xff1a;Problem - B - Codeforces 总结&#xff1a; 对于该题最简单的方法为使用二进制的数表示状态 例如&#xff1a; 对于一个数7的二进制&#xff1a;111 它的每一位都可表示两种状态我们可以理解为取或者不取 对于7这个数字它可以表示一种状态即在三个位置都…...

SpringBoot单元测试

目录 1.什么是单元测试? 2.单元测试有哪些好处? 3.Spring Boot单元测试使⽤ 单元测试的实现步骤 1. ⽣成单元测试类 2. 添加单元测试代码 2.1 .添加Spring Boot框架测试注解:SpringBootTest 2.2 添加单元测试业务逻辑 简单的断⾔说明 1.什么是单元测试? 单元测试(un…...

刷题 41-45

四十一、移除元素 示例 1&#xff1a; 输入&#xff1a;nums [3,2,2,3], val 3 输出&#xff1a;2, nums [2,2] 解释&#xff1a;函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如&#xff0c;函数返回的新长度为 2 …...

Centos时间同步

前言 在 Linux 操作系统中&#xff0c;正确的时间同步是非常重要的&#xff0c;因为它对于很多应用程序都是必需的。本文将介绍两种在 Centos 系统中同步当前时间的方式。 方法一&#xff1a;使用 ntpdate 命令同步当前时间 ntpdate 命令是一种简单快捷的同步当前时间的方式&a…...

Linux 查看磁盘空间

1 查看当前目录的总大小 &#xff1a;du -sh ps&#xff1a;du(disk usage) 2 查看某个目录的总大小&#xff1a;du -sh 目录名 3 查找出/目录下占用空间最大的前10个文件或者文件夹&#xff1a;sudo du -a / | sort -n -r | head -n 10 4 查看磁盘信息:df -h...

我的会议(我的审批,会议签字附源码)

目录 前言&#xff1a; 3.我的审批&#xff1a; 3.1实现的特色功能&#xff1a; 3.2显示的效果 3.3思路&#xff1a; 3.4寻找相关的案例或者自己使用JavaScript去写一个类似的功能 3.5具体的步骤&#xff1a; 3.5.1添加静态的jsp代码&#xff08;我的审批数据的显示&…...

Python 装饰器该如何理解?

哈喽大家好&#xff0c;今天带大家了解下在Python中装饰器的使用 定义 首先我们先来了解下装饰器的定义。顾名思义&#xff0c;在Python中&#xff0c;装饰器本质上就是一个函数&#xff0c;它可以接收一个函数作为参数&#xff0c;然后返回一个新的函数。这个新的函数可以在…...

IDEA 模块不加载依旧是灰色 没有变成小蓝色的方块

Settings > Build, Execution, Deployment > Build Tools > Maven > Ignored Files下降对应的模块勾选掉 但通常在Maven的配置中&#xff0c;您会找到一个名为“ignoredFiles”的列表&#xff0c;其中包含被忽略的文件和目录。您可以通过取消选中所需的文件或目录…...

可以写进简历的kafka优化-----吞吐量提升一倍的方法

冲突 在看到项目工程里kafka 生产端配置的batch.size为500&#xff0c;而实际业务数据平均有1K大小的时候&#xff1b;我有点懵了。是的&#xff0c;这里矛盾了&#xff1b;莫非之前的作者认为这个batch.size是发送的条数&#xff0c;而不是kafka生产端内存缓存记录的大小&…...

JavaScript中,for in 和for of的区别

for in 遍历的是数组的索引&#xff08;即键名&#xff09;&#xff0c;而 for of 遍历的是数组元素值&#xff08;即键值&#xff09;。for...in 循环出的是 key&#xff0c;for...of 循环出的是 value 推荐在循环对象属性的时候使用 for...in&#xff0c;在遍历数组的时候的时…...

计算机毕设 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…...

vue3 axios接口封装

在Vue 3中&#xff0c;可以通过封装axios来实现接口的统一管理和调用。封装后的接口调用更加简洁&#xff0c;代码可维护性也更好。以下是一个简单的Vue 3中axios接口封装的示例&#xff1a; 1.首先&#xff0c;安装axios和qs&#xff08;如果需要处理复杂数据&#xff09;&am…...

誉天程序员-2301-3-day08

4. 书籍管理实现CURD 这个结构比较复杂&#xff0c;是有一套复杂的机制&#xff0c;注意它们之间的关系和控制实现。  新增和修改怎么复用对话框  对话框中的数据&#xff0c;表格中展现的数据&#xff0c;临时记录正在操作的数据统一联动起来  单条删除怎么传递数据&am…...

Python爬虫(1)一次性搞定Selenium(新版)8种find_element元素定位方式

selenium中有8种不错的元素定位方式&#xff0c;每个方式和应用场景都不一样&#xff0c;需要根据自己的使用情况来进行修改 8种find_element元素定位方式 1.id定位2.CSS定位3.XPATH定位4.name定位5.class_name定位6.Link_Text定位7.PARTIAL_LINK_TEXT定位8.TAG_NAME定位总结 …...

前端(十一)——Vue vs. React:两大前端框架的深度对比与分析

&#x1f60a;博主&#xff1a;小猫娃来啦 &#x1f60a;文章核心&#xff1a;Vue vs. React&#xff1a;两大前端框架的深度对比与分析 文章目录 前言概述原理与设计思想算法生态系统与社区支持API与语法性能与优化开发体验与工程化对比总结结语 前言 在当今快速发展的前端领…...

三分钟白话RocketMQ系列—— 核心概念

目录 关键字摘要 Q1&#xff1a;RocketMQ是什么&#xff1f; Q2: 作为消息中间件&#xff0c;RocketMQ和kafka有什么区别&#xff1f; Q3: RocketMQ的基本架构是怎样的&#xff1f; Q4&#xff1a;RocketMQ有哪些核心概念&#xff1f; 总结 RocketMQ是一个开源的分布式消…...

递归竖栏菜单简单思路

自己的项目要写一个竖栏菜单&#xff0c;所以记录一下思路吧&#xff0c;先粗糙的实现一把&#xff0c;有机会再把细节修饰一下 功能上就是无论这个菜单有多少层级&#xff0c;都能显示出来&#xff0c;另外&#xff0c;需要带图标&#xff0c;基于element-plus写成&#xff0…...

组件化、跨平台…未来前端框架将如何演进?

前端框架在过去几年间取得了显著的进步和演进。前端框架也将继续不断地演化&#xff0c;以满足日益复杂的业务需求和用户体验要求。从全球web发展角度看&#xff0c;框架竞争已经从第一阶段的前端框架之争&#xff08;比如Vue、React、Angular等&#xff09;&#xff0c;过渡到…...

vue 修改端口号

在根目录创建一个vue.config.js文件夹 module.exports {lintOnSave: false,devServer: {port: 3000,open: true} }运行后...

hive的metastore问题汇总

1. metastore内存飙升 1 问题 metastore内存飙升降不下来; spark集群提交的任务无法运行, 只申请到了dirver的资源; 2 原因 当Spark任务无法获取足够资源时&#xff0c;因为任务无法继续进行&#xff0c;不能将元数据从Metastore返回给任务 后&#xff0c;这些元数据暂存在…...

【phaser微信抖音小游戏开发003】游戏状态state场景规划

经过目录优化后的执行结果&#xff1a; 经历过上001&#xff0c;002的规划&#xff0c;我们虽然实现了helloworld .但略显有些繁杂&#xff0c;我们将做以下的修改。修改后的目录和文件结构如图。 game.js//小游戏的重要文件&#xff0c;从这个开始。 main.js 游戏的初始化&a…...

字符串性能优化

String 对象作为 Java 语言中重要的数据类型&#xff0c;是内存中占据空间最大的一个对象。高效地 使用字符串&#xff0c;可以提升系统的整体性能。 来一到题来引出这个话题 通过三种不同的方式创建了三个对象&#xff0c;再依次两两匹配&#xff0c;每组被匹配的两个对象是否…...

从零开始理解Linux中断架构(23)中断运行临界区和占先调度

Linux在内核中定义了6种运行临界区。 in_interrupt in_interrupt在驱动中使用频率最高的函数了,in_interrupt()就是指示Core是否正在中断处理中,包含了硬中断,软中断运行临界区。如果在中断处理中,则不能调用__do_softirq执行软中断处理。硬中断中不可调度不可中断,所有…...

(3)Gymnasium--CartPole的测试基于DQN

1、使用Pytorch基于DQN的实现 1.1 主要参考 (1)推荐pytorch官方的教程 Reinforcement Learning (DQN) Tutorial — PyTorch Tutorials 2.0.1cu117 documentation (2) Pytorch 深度强化学习 – CartPole问题|极客笔记 2.2 pytorch官方的教程原理 待续&#xff0c;这两天时…...

利用sklearn 实现线性回归、非线性回归

代码&#xff1a; import pandas as pd import numpy as np import matplotlib import random from matplotlib import pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression# 创建虚拟数据 x np.array(r…...

Java课题笔记~ MyBatis入门

一、ORM框架 当今企业级应用的开发环境中&#xff0c;对象和关系数据是业务实体的两种表现形式。业务实体在内存中表现为对象&#xff0c;在数据库中变现为关系数据。当采用面向对象的方法编写程序时&#xff0c;一旦需要访问数据库&#xff0c;就需要回到关系数据的访问方式&…...

Activity的自启动模式

以下内容摘自郭霖《第一行代码》第三版 文章目录 Activity的自启动模式1.standard&#xff08;默认&#xff09;2.singleTop3.singleTask4.singleInstance Activity的自启动模式 启动模式一共有4种&#xff0c;分别是standard、singleTop、singleTask和singleInstance&#x…...