C语言小项目——通讯录

功能介绍:

1.联系人信息:姓名+年龄+性别+地址+电话

2.通讯录中可以存放100个人的信息

3.功能:

1>增加联系人

2>删除指定联系人

3>查找指定联系人的信息

4>修改指定联系人的信息

5显示所有联系人的信息

6>排序(名字)

  我们将采用模块化设计,分为三个模块:

1. test.c         ———        测试通讯录

2. contact.c   ———        通讯录的声明

3. contact.h    ———       函数的声明

  首先,我们需要一个菜单,以及主函数选择功能的部分。

```test.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>void menu()
{printf("*******************欢迎来到你的通讯录*******************\n");printf("**********1.添加联系人************2.删除联系人**********\n");printf("**********3.查找联系人************4.修改联系人**********\n");printf("**********5.显示联系人************6.联系人排序**********\n");printf("**********0.退出通讯录*********************************\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("退出通讯录");break;default:printf("选择错误\n");break;}} while (input);return 0;
}
```
  • main函数中,使用do-while循环不断调用menu函数显示菜单,并使用scanf函数获取用户的输入。然后通过switch语句根据用户的输入执行相应的操作,如果输入为0,则输出 “退出通讯录” 并结束程序;如果输入为其他值,则输出 “选择错误”。

那么通讯录中肯定需要人的信息,那么这些人的信息,我们可以把他封装成一个结构体。我们将这些类型信息放进头文件中,在这里我们将它放进已经创建好的contact.h中。

```contact.h
//人的信息
typedef struct Peopleinform
{char name[40];int age;char sex[5];char addr[20];char telephone[20];
}Peopleinform;
```

在这里,我们定义了一个名为Peopleinform的结构体类型,用于存储人员的信息。我们通过使用typedef关键字,可以为这个结构体类型定义一个别名Peopleinform,这样在后续的代码中就可以直接使用Peopleinform来声明该类型的变量,而不需要每次都写完整的struct Peopleinform

我们继续往下写,接下来我们创建通讯录,我们可以声明一个名为data的数组,数组的元素类型为Peopleinform结构体,当然我们在这里必须添加contact.h头文件才能使用它。代码部分如下:

```test.c
#include<stdio.h>
#include"contact.h"
/* --省略void menu部分--*/
int main()
{int input = 0;//创建通讯录Peopleinform data[100];do {menu();printf("请选择:>");scanf("%d", &input);/*-- 省略switch部分 --*/} while (input);return 0;
}
```

 在我们的项目中,自己创建的头文件通常用双引号''"包裹起来,这样我们就可以在.c文件中使用它啦!当然,我们如果把这个通讯录存放人的信息的容量,以及可以显示的当前创建的人的信息封装起来,变成一个结构体。为了方便之后修改我们增加一个预处理器指令#define MAX 100

```contact.h
#define MAX 100
typedef struct Contact
{Peopleinform data[MAX];//存放人的信息的容量int sz;//当前存放信息的个数
}Contact;
```

那么我们如果想在主函数中使用,只需要创建一个名为conContact类型的对象。这样就可以使用con来存储和操作通讯录相关的数据了。接着我们初始化通讯录。并在contact.h头文件中为他声明。

```test.c
int main()
{int input = 0;//创建通讯录Contact con;//创建一个名为con的Contact对象//初始化通讯录InitContact(&con);do {menu();printf("请选择:>");scanf("%d", &input);/*-- 省略switch部分 --*/} while (input);
```
```contact.h
void InitContact(Contact *pc);
```

接下来,contact.c文件终于出场了,由于我们在contact.h头文件声明过void InitContact(Contact *pc); 接下来,我们就可以在contact.c直接使用它。

我们给这个Contact结构体的函数初始化一下:

```contact.c
#include"contact.h"
void InitContact(Contact* pc)
{pc->sz=0;memset(pc->data,0,sizeof(pc->data));
}
```

这里我们选择使用memset函数进行初始化,

(注:memset函数是 C 标准库中的一个函数,定义在<string.h>头文件中。它的作用是将一段内存区域设置为指定的值。函数原型为void *memset(void *s, int c, size_t n),其中s是指向要填充的内存块的指针,c是要设置的值,n是要填充的字节数。) 

紧接着,我们在Switch()语句中,加入我们目前需要的语句,我们现在来写添加联系人模块。

添加联系人模块

```contact.h
//增加联系人
void AddContact(Contact* pc);
```
```contact.c
void AddContact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满!无法添加!\n");return;}//增加一个人的信息printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%s", &pc->data[pc->sz].age);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].telephone);pc->sz++;
}
```

(注:在InitContactAddContact函数中,pc用于访问和修改调用者提供的Contact结构体实例。当调用这些函数时,传递的是Contact结构体变量的地址,函数内部通过这个指针来操作外部传入的结构体。)

pc-sz++; 的作用 

假设 sz 初始值为 5,执行 pc->sz++; 后,sz 的值变为 6 ,表示通讯录中联系人的数量从 5 个增加到了 6 个。 这对于跟踪通讯录中实际存储的联系人数量非常重要,在后续的操作,如显示联系人列表、检查通讯录是否已满等功能中,都依赖这个计数。

 显示联系人模块

显示联系人模块也是一样,我们现将函数声明放在头文件当中,

void ShowContact(const Contact* pc);

然后我们用一个for循环遍历pc->data数组,其中,pc->data数组存储了所有联系人的信息,循环条件i < pc->sz确保只遍历已存储联系人的部分,pc->sz表示当前通讯录中实际存储的联系人数量。

```contact.c
void ShowContact(Contact* pc)
{int i = 0;printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名","年齡","性別","地址","電話");for (i = 0; i < pc->sz; i++){printf("%s\t%d\t%s\t%s\t%s\t",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].telephone);}
}
```

这样,我们就基本完成了这个显示联系人的设计啦!那么紧接着,我们如果想要删除这个指定的联系人,该怎么办呢?和上面一样,我们先在头文件中添加一个声明。

void DelContact(Contact* pc);

接着,我们在contact.c文件中去构建这个删除联系人模块,

删除联系人模块

void DelContact(Contact* pc)
{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 = 0; i < pc->sz; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功");}
}

当我们通讯录里面没有联系人的时候,我们输出“无可删除的联系人”。接着,我们使用 for 循环遍历联系人列表,使用 strcmp 函数比较每个联系人的名字和输入的名字,如果相等则将该元素的索引存储在 del 中并跳出循环。

那么接下来,我们可以发现的是,无论是删除模块、查找模块和修改模块中,我们都需要先找到联系人,才能进行下一步的操作,既然都需要,我们似乎就可以把这个查找部分封装成一个函数,

// 根据姓名查找联系人在数组中的位置,如果找到返回对应索引,未找到返回 -1
int FINDBY_NAME(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) // 比较字符串是否相等{return i; // 找到返回索引}}return -1; // 未找到返回 -1
}

 替换后代码如下:

// 删除联系人的函数
void DelContact(Contact* pc)
{if (pc->sz == 0){printf("没有联系人可删除\n");return;}// 输入要删除的联系人姓名char name[40] = { 0 };printf("请输入要删除的联系人姓名: ");scanf("%s", name);int ret = FINDBY_NAME(pc, name);if (ret == -1){printf("要删除的联系人不存在\n");return;}// 删除操作,将后面的元素依次往前移for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

我们来看查找联系人模块,

查找联系人模块

void SerContact(const Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:");scanf("%s",name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年齡", "性別", "地址", "電話");printf("%s\t%-5d\t%-5s\t%-5s\t%-5s\t\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].telephone);
}

 我们查找模块,首先输入要查找的联系人姓名,调用 FINDBY_NAME 函数查找该联系人的位置,如果不存在则提示联系人不存在并返回。否则,打印该联系人的详细信息。

紧接着,我们再来看修改联系人,

修改联系人模块

//修改联系人
void ReviContact(Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:");scanf("%s", name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要修改的人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &pc->data[pos].age);printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("请输入电话:>");scanf("%s", pc->data[pos].telephone);printf("修改完成\n");
}

我们想要修改联系人,首先肯定需要找到这个联系人,所以我们首先要查找,输入要修改的联系人姓名,调用FINDBY_NAME函数可以查找该联系人的位置,如果不存在则提示联系人不存在并返回。否则,依次输入新的联系人信息。

排序联系人模块

最后一个模块,就是对这些联系人进行排序,这里使用使用冒泡排序算法,比较相邻联系人的姓名,如果前一个联系人的姓名大于后一个联系人的姓名,则交换它们的位置。

// 排序联系人(按姓名升序排序)
void SortContact(Contact* pc)
{int i, j;Peopleinform temp;for (i = 0; i < pc->sz - 1; i++){for (j = 0; j < pc->sz - i - 1; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){temp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = temp;}}}printf("联系人已按姓名排序\n");
}

strcmp 是 C 语言标准库 <string.h> 中的一个字符串比较函数,用于比较两个字符串的大小。

函数原型int strcmp(const char *str1, const char *str2);

在 SortContact 函数中,strcmp(pc->data[j].name, pc->data[j + 1].name) > 0 表示如果 pc->data[j].name 这个字符串在字典序上大于 pc->data[j + 1].name 这个字符串,就交换这两个联系人的信息,从而实现按姓名排序的功能。

源代码如下:

```contact.h
#pragma once
#include<stdio.h>
#include<string.h>
#define MAX 100
#define NAME_MAX 40  // 定义 NAME_MAX 的大小
// 个人信息
typedef struct Peopleinform
{char name[40];int age;char sex[5];char addr[20];char telephone[20];
}Peopleinform;
typedef struct Contact
{Peopleinform data[MAX];// 存储个人信息的数组int sz;// 当前存储信息的数量
}Contact;// 初始化通讯录
void InitContact(Contact* pc);
// 添加联系人
void AddContact(Contact* pc);
// 删除联系人
void DelContact(Contact* pc);
// 查找联系人
void SerContact(const Contact* pc);
// 修改联系人
void ReviContact(Contact* pc);
// 排序联系人
void SortContact(Contact* pc);
// 显示联系人
void ShowContact(const Contact* pc);
```
```contact.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == MAX){printf("通讯录已满!无法添加!\n");return;}//增加一个人的信息printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:>");scanf("%d", &pc->data[pc->sz].age);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].telephone);pc->sz++;
}// 根据姓名查找联系人在数组中的位置,如果找到返回对应索引,未找到返回 -1
int FINDBY_NAME(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0) // 比较字符串是否相等{return i; // 找到返回索引}}return -1; // 未找到返回 -1
}// 删除联系人的函数
void DelContact(Contact* pc)
{if (pc->sz == 0){printf("没有联系人可删除\n");return;}// 输入要删除的联系人姓名char name[40] = { 0 };printf("请输入要删除的联系人姓名: ");scanf("%s", name);int ret = FINDBY_NAME(pc, name);if (ret == -1){printf("要删除的联系人不存在\n");return;}// 删除操作,将后面的元素依次往前移for (int i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}
//查找联系人
void SerContact(const Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:");scanf("%s",name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年齡", "性別", "地址", "電話");printf("%s\t%-5d\t%-5s\t%-5s\t%-5s\t\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].telephone);
}
//修改联系人
void ReviContact(Contact* pc)
{char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:");scanf("%s", name);int pos = FINDBY_NAME(pc, name);if (-1 == pos){printf("要修改的人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &pc->data[pos].age);printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("请输入电话:>");scanf("%s", pc->data[pos].telephone);printf("修改完成\n");
}
// 排序联系人(按姓名升序排序)
void SortContact(Contact* pc)
{int i, j;Peopleinform temp;for (i = 0; i < pc->sz - 1; i++){for (j = 0; j < pc->sz - i - 1; j++){if (strcmp(pc->data[j].name, pc->data[j + 1].name) > 0){temp = pc->data[j];pc->data[j] = pc->data[j + 1];pc->data[j + 1] = temp;}}}printf("联系人已按姓名排序\n");
}// 显示所有联系人信息的函数
void ShowContact(const Contact* pc)
{int i = 0;printf("%s\t%-5s\t%-5s\t%-5s\t%-5s\t\n", "姓名", "年龄", "性别", "地址", "电话");for (i = 0; i < pc->sz; i++){printf("%s\t%d\t%s\t%s\t%s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].telephone);}
}
```
```test.c
#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"void menu()
{printf("*******************欢迎来到你的通讯录*******************\n");printf("**********1.添加联系人************2.删除联系人**********\n");printf("**********3.查找联系人************4.修改联系人**********\n");printf("**********5.显示联系人************6.联系人排序**********\n");printf("**********0.退出通讯录**********************************\n");printf("*******************欢迎来到你的通讯录*******************\n");
}
int main()
{int input = 0;//创建通讯录Contact con;//创建一个名为con的Contact对象//初始化通讯录InitContact(&con);do {menu();printf("请选择:>");if (scanf("%d", &input) != 1) {// 处理输入错误的情况,例如提示用户重新输入printf("输入错误,请重新输入\n");// 清空输入缓冲区while (getchar() != '\n');continue;}switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:SerContact(&con);break;case 4:ReviContact(&con);break;case 5:ShowContact(&con);break;case 6:SortContact(&con);case 0:printf("退出通讯录");break;default:printf("选择错误\n");break;}} while (input!=0);
}
```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/893603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“深入浅出”系列之算法篇:(2)openCV、openMV、openGL

OpenCV是一个的跨平台计算机视觉库,可以运行在Linux囚、Windows 和Mac OS操作系统上。它轻量级而且高效,由一系列 C函数和少量C类构成&#xff0c;同时也提供了Python 接口&#xff0c;实现了图像处理和计算机视觉方面的很多通用算法。 OpenMV是一个开源&#xff0c;低成本&am…

ThinkPHP 8请求处理-获取请求对象与请求上下文

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用Composer初始化ThinkPHP 8应用_thinkphp8 compos…

飞行器半实物联合仿真:技术解析与应用实践

1.背景介绍 当前&#xff0c;飞行器已成为大国博弈复杂场景中的重要角色&#xff0c;其技术经过多次实践不断发展&#xff0c;性能持续提升&#xff0c;整体效能显著增强。随着计算机技术和系统仿真技术的发展&#xff0c;利用计算机模拟和仿真构造一个虚拟飞行器的飞行控制系…

c#配置config文件

1&#xff0c;引用命名空间 Configuration 及配置信息

【机器学习】机器学习引领数学难题攻克:迈向未知数学领域的新突破

我的个人主页 我的领域&#xff1a;人工智能篇&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;&#x1f44d;点赞 收藏❤ 一、引言 在数学的浩瀚领域中&#xff0c;存在着诸多长期未解的难题&#xff0c;这些难题犹如高耸的山峰&#xff0c;吸引着无数数…

OS Copilot功能测评:智能助手的炫彩魔法

简介&#xff1a; OS Copilot 是一款融合了人工智能技术的智能助手&#xff0c;专为Linux系统设计&#xff0c;旨在提升系统管理和运维效率。本文详细介绍了在阿里云ECS实例上安装和体验OS Copilot的过程&#xff0c;重点评测了其三个核心参数&#xff1a;-t&#xff08;模式…

JavaScript学习记录23

第十一节 JSON对象 1. JSON 格式 JSON 格式&#xff08;JavaScript Object Notation 的缩写&#xff09;是一种用于数据交换的文本格式&#xff0c;2001年由 Douglas Crockford 提出&#xff0c;目的是取代繁琐笨重的 XML 格式。 相比 XML 格式&#xff0c;JSON 格式有两个显…

C#设置winform窗体自动适应不同分辨率的电脑

C#设置winform窗体自动适应不同分辨率的电脑 文章已被社区收录 加入社区 问题背景&#xff1a; 用winform开发了一个上位机软件&#xff0c;本机的台式开发电脑是宽屏的&#xff0c;上位机软件的显示效果良好&#xff0c;而在笔记本电脑上使用上位机软件时&#xff0c;出现了界…

计算机网络 (55)流失存储音频/视频

一、定义与特点 定义&#xff1a;流式存储音频/视频是指经过压缩并存储在服务器上的多媒体文件&#xff0c;客户端可以通过互联网边下载边播放这些文件&#xff0c;也称为音频/视频点播。 特点&#xff1a; 边下载边播放&#xff1a;用户无需等待整个文件下载完成即可开始播放…

Oracle存储过程语法详解

简介 存储过程是一系列SQL语句的集合&#xff0c;可以封装复杂的逻辑&#xff0c;实现特定的功能&#xff0c;可以提高执行速度和代码的复用性&#xff0c;预先编译后存储在数据库中&#xff0c;可以通过指定存储过程的名称对其进行调用。 本文主要讲解Oracle存储过程语法&am…

kafka-保姆级配置说明(broker)

一. important ##broker ID&#xff0c;cluster唯一标识&#xff0c;数字类型 ##此值可以不指定&#xff0c;有集群自动创建&#xff08;由当前集群现有的brokerID 1&#xff09;。 ##默认值为-1 broker.id5 #broker.id.generation.enabletrue ##zookeeper连接地址 zookeeper.…

推箱子游戏

java小游戏2 一游戏介绍 二图像准备 墙、箱子、人、箱子目的地&#xff0c;人左边、人右边、人上边、人下边 三结构准备 地图是什么&#xff0c;我们把地图想象成一个网格&#xff0c;每个格子就是工人每次移动的步长&#xff0c;也是箱子移动的距离&#xff0c;设置一个二维数…

如何分辨ddos攻击和cc攻击?

DDoS&#xff08;分布式拒绝服务&#xff09;攻击和 CC&#xff08;Challenge Collapsar&#xff09;攻击都属于网络攻击手段&#xff0c;主要通过消耗目标服务器资源使其无法正常提供服务&#xff0c;但它们在攻击原理、攻击特征等方面存在区别&#xff1a; 攻击原理 DDoS 攻…

期权帮|如何利用股指期货进行对冲套利?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 如何利用股指期货进行对冲套利&#xff1f; 对冲就是通过股指期货来平衡投资组合的风险。它分为正向与反向两种策略&#xff1a; &#xff08;1&#xff09;正向对冲&#xff…

软件质量与测试报告5-压力测试 JMeter 与 Badboy

A&#xff0e;百度搜索引擎压力测试 通过在Badboy下执行如下的测试场景来生成压力测试的脚本&#xff1a; a) 在Badboy的地址栏里面输入www.baidu.com&#xff0c;回车&#xff1b; b) 在右下区域打开的百度的主页上输入搜索关键字JMeter&#xff0c;回车&#xff1b; c) 在…

每日一题 417. 太平洋大西洋水流问题

417. 太平洋大西洋水流问题 代码使用队列进行广度搜索&#xff0c;分别遍历太平洋 和大西洋的河流&#xff0c;取交集。 class Solution { public:vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {set<pair<int,int&…

Java设计模式 九 桥接模式 (Bridge Pattern)

桥接模式 (Bridge Pattern) 桥接模式是一种结构型设计模式&#xff0c;它的核心思想是将抽象部分与实现部分分离&#xff0c;使它们可以独立变化。这种模式通过组合而不是继承的方式来扩展功能&#xff0c;从而减少类之间的耦合度。 1. 模式结构 桥接模式的结构包括以下角色&…

USB——cherry 键盘分析

文章目录 cherry USB 键盘分析描述符结构设备描述符配置描述符集合配置描述符接口 1 描述符HID 描述符端点 IN 描述符接口 2 描述符HID 描述符端点 IN 描述符端点 OUT 描述符字符串描述符语言 ID (字符串索引为 0)厂商字符串(字符串索引为 1)产品字符串(字符串索引为 2)HID 报告…

关于自动控制原理中三阶系统瞬态响应与稳定性实验的研究报告

一、引言 1.1 研究背景与意义 自动控制原理作为现代工业生产、航空航天、智能交通等众多领域的关键理论基础&#xff0c;对提高生产效率、提升产品质量以及保障系统安全稳定运行起着举足轻重的作用。在实际应用中&#xff0c;自动控制系统能够根据预设的目标和反馈信息&#…

Mybatis多条件查询:Map传参与对象传参解析

Mybatis 多条件查询常见且关键&#xff0c;本文探讨两种方法——Map 传参和 Java Bean 对象传参&#xff0c;展示用法及区别&#xff0c;总结应用场景和优缺点。 1. Map传参方式 原理&#xff1a;Mybatis允许我们通过一个Map对象来传递动态SQL中的参数。Map的键对应于SQL语句中…