【C语言】静态通讯录 -- 详解

一、实现目标

1、功能

  • 保存 1000 个联系人的信息
  • 添加联系人
  • 删除联系人
  • 修改联系人
  • 查找联系人
  • 排序

2、个人信息(结构体)

  • 名字
  • 年龄
  • 性别
  • 电话
  • 地址

二、创建文件

  1. test.c(专门测试通讯录的功能)
  2. contact.c(接口的实现)
  3. contact.h(接口的声明)

三、初始页面的实现

1、实现主菜单页面

// test.c

(1)menu()
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");
}

效果图如下:


(2)main()
int main()
{int input = 0;// 创建通讯录struct Contact con; // con就是通讯录,里边包含:1000的元素的数和size// 初始化通讯录InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误!\n");break;}} while (input);return 0;
}

2、在contact.h 中引用所需要的文件和必要的定义

首先我们要声明一个结构体,其中包含了我们想要保存的信息(可以自己设置):

struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
};

但是接下来我们可能会想到一个问题,如何表示该结构体中已经存入的有效数据有多少?所以我们还得定义一个变量 size,通过某些函数功能的实现(例如增加联系人),size 的值也必须要发生改变,我们可以通过传入 size 的地址来改变它自身。但是还有一个简单的办法:再声明一个结构体,并用该结构体创建一个 struct PeoInfo 的数组以及 size,这样就解决了这个问题且方便管理。

struct Contact
{struct PeoInfo data[MAX];// 可以存放1000个人的信息int size;// 记录通讯录中已经保存的信息个数
};

 整体逻辑:

// contact.h
#pragma once // 避免头文件被重复引用#include <stdio.h>
#include <string.h> // memset strcmp
#include <stdlib.h> //qsort// 宏定义
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12 // 电话号码11位,以%s打印输出,所以要留下足够的空间放结束标志'\0'
#define MAX_ADDR 30enum Option
{EXIT,//0ADD,//1DEL,//2SEARCH,//3MODIFY,//4SHOW,//5SORT//6
};struct PeoInfo
{char name[MAX_NAME]; //姓名int age;             //年龄char sex[MAX_SEX];   //性别char tele[MAX_TELE]; //电话char addr[MAX_ADDR]; //地址
};//通讯录类型
struct Contact
{struct PeoInfo data[MAX];// 可以存放1000个人的信息int size;// 记录通讯录中已经保存的信息个数
};// 函数的声明
// 初始化通讯录的函数
void InitContact(struct Contact* ps);
// 添加联系人信息
void AddContact(struct Contact* ps);
// 展示通讯录中的信息(只是打印信息,不会去修改,加上const更加安全)
void ShowContact(const struct Contact* ps);
// 删除指定的联系人
void DelContact(struct Contact* ps);
// 通过姓名查找指定联系人所在下标
int FindByName(const struct Contact* ps, char name[]);
// 查找指定的人的信息(只是查找信息,不会去修改,加上const更加安全)
void SearchContact(const struct Contact* ps);
// 修改指定联系人
void ModifyContact(struct Contact* ps);
// 排序通讯录内容
void SortContact(struct Contact* ps);

:给电话数组需要定义 12 个 char 大小,如果只定义了 11 个char大小,字符数组没有结束标志,会导致打印时出现问题 。

在整体逻辑的实现上,我们用了很多 #define 的标识符常量使修改一些数据变得更加容易。为了让代码的可读性更高,在 switch 语句中运用了枚举常量。为了减少时间以及空间上的开销,所有功能函数中传入的都是结构体的地址。 


三、在 contact.c 上实现各个接口函数

1、初始化通讯录

使用 memset 函数初始化存放联系人信息的结构体数组 data。

// 初始化通讯录
void InitContact(struct Contact* ps) // 结构体指针
{ps->size = 0; // 设置通讯录最初只有0个元素memset(ps->data, 0, sizeof(ps->data));
}

2、添加联系人信息

先判断通讯录人数是否已满,如果未满,则添加联系人信息。 

// 增加一个信息到通讯录
void AddContact(struct Contact* ps)
{// 判断通讯录人数是否已满if (ps->size == MAX){printf("通讯录已满,无法增加!\n");return;}// 添加一个联系人的信息// 录入信息printf("请输入名字:>");scanf("%s", ps->data[ps->size].name);printf("请输入年龄:>");scanf("%d", &(ps->data[ps->size].age)); // 年龄是一个整型变量 需要取地址printf("请输入性别:>");scanf("%s", ps->data[ps->size].sex);printf("请输入电话:>");scanf("%s", ps->data[ps->size].tele);printf("请输入地址:>");scanf("%s", ps->data[ps->size].addr);ps->size++;printf("添加成功!\n");
}

注意由于 age 在这里是一个整型变量,所以要加上 &。


3、展示通讯录中所有联系人的信息

// 展示通讯录中的信息
void ShowContact(const struct Contact* ps)
{if (ps->size == 0) // 判断通讯录人数是否为0{printf("通讯录为空!\n");}else{int i = 0;// 打印标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");// 打印数据for (i = 0; i < ps->size; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",ps->data[i].name,ps->data[i].age,ps->data[i].sex,ps->data[i].tele,ps->data[i].addr);}}
}

注意:因为只是打印信息,不会修改内容,所以加上 const 更加安全。 

为了让结果更美观,采用了左对齐的方式。printf 中 %-20s 中的 20 是指输出字段的宽度负号表示左对齐,如省略表示右对齐,如果输出的数据位数小于 20,则在数据右端补齐空格。


4、通过姓名查找指定联系人所在的下标 

// 通过姓名查找指定联系人所在下标
static int FindByName(const struct Contact* ps, char name[MAX_NAME])
{int i = 0;for (i = 0; i < ps->size; i++){if (0 == strcmp(ps->data[i].name, name)){return i; // 查找到返回联系人的下标}}return -1;// 找不到返回-1
}

为了解决代码的冗余,我们不妨分装一个函数来完成查找功能。该函数会在删除 / 修改 / 查找指定联系人信息的函数中被调用到,这些函数刚好又在同一源文件中,所以用 static 修饰函数,只能在所在此文件内使用。 


5、删除指定联系人

先判断通讯录是否为空,如果不为空,再通过 FindByName() 函数查找通讯录中是否有你要删除的联系人,如果有则删除。

原理:把要删除的联系人后面一个人的信息依次从前向后往前移动一位,覆盖掉其信息,然后再将人数 -1。

// 删除指定的联系人
void DelContact(struct Contact* ps)
{char name[MAX_NAME];printf("请输入要删除人的名字:>");scanf("%s", name);// 1、查找要删除的人在什么位置int pos = FindByName(ps, name);// 2、删除if (pos == -1){printf("要删除的人不存在!\n");}else{// 删除数据int j = 0;for (j = pos; j < ps->size-1; j++){// 把要删除的人后面一个人的信息依次从前向后往前移动一位,覆盖掉其信息ps->data[j] = ps->data[j + 1];}ps->size--;printf("删除成功!\n");}
}

6、查找指定联系人的信息

通过 FindByName() 函数查找通讯录中是否有你要查找的联系人,如果查找到,则打印该联系人的信息。 

// 查找指定的人的信息
void SearchContact(const struct Contact* ps)
{char name[MAX_NAME];printf("请输入要查找人的名字:>");scanf("%s", name);int pos = FindByName(ps, name); // 查找if(pos == -1){printf("要查找的人不存在!\n");}else{printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");// 打印数据printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",ps->data[pos].name,ps->data[pos].age,ps->data[pos].sex,ps->data[pos].tele,ps->data[pos].addr);}
}

注意:因为只是查找信息,不会修改内容,所以加上 const 更加安全 


7、修改指定联系人

通过 FindByName() 函数查找通讯录中是否有你要修改信息的联系人,如果有则修改。 

// 修改指定联系人
void ModifyContact(struct Contact* ps)
{char name[MAX_NAME];printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(ps, name);if (pos == -1){printf("要修改人的信息不存在!\n");}else{printf("请输入名字:>");scanf("%s", ps->data[pos].name);printf("请输入年龄:>");scanf("%d", &ps->data[pos].age);printf("请输入性别:>");scanf("%s", ps->data[pos].sex);printf("请输入电话:>");scanf("%s", ps->data[pos].tele);printf("请输入地址:>");scanf("%s", ps->data[pos].addr);printf("修改完成!\n");}
}

8、排序通讯录内容

// 排序通讯录内容
// 比较结构体数组中两个元素的姓名成员
int compareStructType_name(const void* elem1, const void* elem2)
{// 姓名成员是字符串,用strcmp比较return strcmp(((struct PeoInfo*)elem1)->name, ((struct PeoInfo*)elem2)->name);
}// 以名字排序所有联系人
void SortContact(struct Contact* ps)
{// 判断通讯录是否为空if (ps->size == 0){printf("通讯录为空,无法排序!\n");return;}else{// 根据姓名成员对结构体数组升序排列qsort(ps->data, ps->size, sizeof(ps->data[0]), compareStructType_name);printf("以名字排序联系人成功!\n");}
}

该函数排序用的是姓名作为标准,也可以自己更换其他的排序方式。 


四、代码整合

1、test.c

// test.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()
{int input = 0;// 创建通讯录struct Contact con; // con就是通讯录,里边包含:1000的元素的数和size// 初始化通讯录InitContact(&con);do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误!\n");break;}} while (input);return 0;
}

2、contact.h

// contact.h
#pragma once // 避免头文件被重复引用#include <stdio.h>
#include <string.h> // memset strcmp
#include <stdlib.h> //qsort// 宏定义
#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12 // 电话号码11位,以%s打印输出,所以要留下足够的空间放结束标志'\0'
#define MAX_ADDR 30enum Option
{EXIT,//0ADD,//1DEL,//2SEARCH,//3MODIFY,//4SHOW,//5SORT//6
};struct PeoInfo
{char name[MAX_NAME]; //姓名int age;             //年龄char sex[MAX_SEX];   //性别char tele[MAX_TELE]; //电话char addr[MAX_ADDR]; //地址
};//通讯录类型
struct Contact
{struct PeoInfo data[MAX];// 可以存放1000个人的信息int size;// 记录通讯录中已经保存的信息个数
};// 函数的声明
// 初始化通讯录的函数
void InitContact(struct Contact* ps);
// 添加联系人信息
void AddContact(struct Contact* ps);
// 展示通讯录中的信息(只是打印信息,不会去修改,加上const更加安全)
void ShowContact(const struct Contact* ps);
// 删除指定的联系人
void DelContact(struct Contact* ps);
// 通过姓名查找指定联系人所在下标
int FindByName(const struct Contacts* ps, char name[]);
// 查找指定的人的信息(只是查找信息,不会去修改,加上const更加安全)
void SearchContact(const struct Contact* ps);
// 修改指定联系人
void ModifyContact(struct Contact* ps);
// 排序通讯录内容
void SortContact(struct Contact* ps);

3、contact.c

// contact.c
#include "contact.h"// 初始化通讯录
void InitContact(struct Contact* ps) // 结构体指针
{ps->size = 0; // 设置通讯录最初只有0个元素memset(ps->data, 0, sizeof(ps->data));
}// 添加联系人信息
void AddContact(struct Contact* ps)
{// 判断通讯录人数是否已满if (ps->size == MAX){printf("通讯录已满,无法增加!\n");return;}// 添加一个联系人的信息// 录入信息printf("请输入名字:>");scanf("%s", ps->data[ps->size].name);printf("请输入年龄:>");scanf("%d", &(ps->data[ps->size].age)); // 年龄是一个整型变量 需要取地址printf("请输入性别:>");scanf("%s", ps->data[ps->size].sex);printf("请输入电话:>");scanf("%s", ps->data[ps->size].tele);printf("请输入地址:>");scanf("%s", ps->data[ps->size].addr);ps->size++;printf("添加成功!\n");
}// 展示通讯录中的信息
void ShowContact(const struct Contact* ps)
{if (ps->size == 0) // 判断通讯录人数是否为0{printf("通讯录为空!\n");}else{int i = 0;// 打印标题printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");// 打印数据for (i = 0; i < ps->size; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",ps->data[i].name,ps->data[i].age,ps->data[i].sex,ps->data[i].tele,ps->data[i].addr);}}
}// 通过姓名查找指定联系人所在下标
static int FindByName(const struct Contact* ps, char name[MAX_NAME])
{int i = 0;for (i = 0; i < ps->size; i++){if (0 == strcmp(ps->data[i].name, name)){return i; // 查找到返回联系人的下标}}return -1;// 找不到返回-1
}// 删除指定的联系人
void DelContact(struct Contact* ps)
{char name[MAX_NAME];printf("请输入要删除人的名字:>");scanf("%s", name);// 1、查找要删除的人在什么位置int pos = FindByName(ps, name);// 2、删除if (pos == -1){printf("要删除的人不存在!\n");}else{// 删除数据int j = 0;for (j = pos; j < ps->size-1; j++){// 把要删除的人后面一个人的信息依次从前向后往前移动一位,覆盖掉其信息ps->data[j] = ps->data[j + 1];}ps->size--;printf("删除成功!\n");}
}// 查找指定的人的信息
void SearchContact(const struct Contact* ps)
{char name[MAX_NAME];printf("请输入要查找人的名字:>");scanf("%s", name);int pos = FindByName(ps, name); // 查找if(pos == -1){printf("要查找的人不存在!\n");}else{printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");// 打印数据printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n",ps->data[pos].name,ps->data[pos].age,ps->data[pos].sex,ps->data[pos].tele,ps->data[pos].addr);}
}// 修改指定联系人
void ModifyContact(struct Contact* ps)
{char name[MAX_NAME];printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(ps, name);if (pos == -1){printf("要修改人的信息不存在!\n");}else{printf("请输入名字:>");scanf("%s", ps->data[pos].name);printf("请输入年龄:>");scanf("%d", &ps->data[pos].age);printf("请输入性别:>");scanf("%s", ps->data[pos].sex);printf("请输入电话:>");scanf("%s", ps->data[pos].tele);printf("请输入地址:>");scanf("%s", ps->data[pos].addr);printf("修改完成!\n");}
}// 排序通讯录内容
// 比较结构体数组中两个元素的姓名成员
int compareStructType_name(const void* elem1, const void* elem2)
{// 姓名成员是字符串,用strcmp比较return strcmp(((struct PeoInfo*)elem1)->name, ((struct PeoInfo*)elem2)->name);
}// 以名字排序所有联系人
void SortContact(struct Contact* ps)
{// 判断通讯录是否为空if (ps->size == 0){printf("通讯录为空,无法排序!\n");return;}else{// 根据姓名成员对结构体数组升序排列qsort(ps->data, ps->size, sizeof(ps->data[0]), compareStructType_name);printf("以名字排序联系人成功!\n");}
}

五、程序运行效果 


六、思考

目前这个通讯录程序能够存放 1000 个联系人的信息,我们在栈区开辟了能够存放 1000 人信息的内存空间。可是如果我只有 200 个联系人,后面的空间岂不是浪费了;如果随着我的使用,存的联系人信息越来越多,超过了 1000 个,那又该怎么办呢?

是否有一种方法,能够让我们动态开辟空间,想开辟多大就开辟多大,空间不够用了可以增加,这样我们的空间利用率不就大大提高了吗。这一问题涉及到了动态内存开辟,在后面的文章中会详细介绍,并对当前通讯录进行改进和完善。

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

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

相关文章

C语言实现三子棋游戏

大家好&#xff0c;欢迎观看Mr.kanglong的CSDN博客&#xff0c;今天和大家讨论的是如何使用C语言来实现三子棋游戏。相信大家儿时或多或少玩过三子棋游戏&#xff0c;那么怎么用C语言实现这样一个游戏呢&#xff1f;且听亢龙娓娓道来~ 目录 三子棋介绍 游戏效果 实现代码 gam…

大语言模型之二 GPT发展史简介

得益于数据、模型结构以及并行算力的发展&#xff0c;大语言模型应用现今呈井喷式发展态势&#xff0c;大语言神经网络模型成为了不可忽视的一项技术。 GPT在自然语言处理NLP任务上取得了突破性的进展&#xff0c;扩散模型已经拥有了成为下一代图像生成模型的代表的潜力&#x…

第三届“赣政杯”网络安全大赛 | 赛宁筑牢安全应急防线

​​为持续强化江西省党政机关网络安全风险防范意识&#xff0c;提高信息化岗位从业人员基础技能&#xff0c;提升应对网络安全风险处置能力。由江西省委网信办、江西省发展改革委主办&#xff0c;江西省大数据中心、国家计算机网络与信息安全管理中心江西分中心承办&#xff0…

Vue在页面输出JSON对象,测试接口可复制使用

效果图&#xff1a; 数据处理前&#xff1a; 数据处理后&#xff1a; 代码实现&#xff1a; HTML: <el-table height"600" :data"tableData" border style"width: 100%" tooltip-effect"dark" size"mini"><el-…

考研 408 | 【计算机网络】 应用层

导图 网络应用模型 客户/服务器&#xff08;c/s&#xff09;模型 P2P模型 DNS 域名 域名服务器 域名解析过程 文件传输协议FTP FTP服务器和用户端 FTP工作原理 电子邮件 电子邮件的信息格式 组成结构 邮件服务器的功能&#xff1a; 1.发送&接收邮件 2.给发件人报告邮…

【JavaEE进阶】Bean 作用域和生命周期

文章目录 一. 关于Bean作用域的实例1. lombok2. 实例代码 二. 作用域定义1. Bean的六种作用域2. 设置作用域 三. Spring 执行流程和 Bean 的生命周期1. Spring 执行流程2. Bean生命周期 一. 关于Bean作用域的实例 注意在此例子中需要用到lombok 1. lombok lombok是什么? Lo…

Coremail AI实验室:利用高级语境和视觉智能进行钓鱼邮件检测

在这个日益数字化的时代&#xff0c;对电子邮件安全需求是至关重要的。新兴的高级威胁邮件&#xff1a;应用社工技术的钓鱼邮件&#xff0c;仿冒公检法的钓鱼邮件等等&#xff0c;都需要更高级的防御策略。 Coremail邮件安全人工智能实验室&#xff0c;整合了高级文本语境理解和…

使用 Visual Studio GoogleTest编写 C/C++ 单元测试——入门篇

入门教程 Visual Studio 新建 GoogleTest项目&#xff0c;一路选默认参数 pch.h #pragma once#include "gtest/gtest.h"int add(int a, int b);pch.cpp #include "pch.h"int add(int a, int b) {return a b; }test.cpp #include "pch.h"TES…

HTML详解连载(3)

HTML详解连载&#xff08;3&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽表单作用使用场景 input标签基本使用示例type属性值以及说明 input标签占位文本示例注意 单选框 radio代码示例 多选框-checkbox注意代码示例 文本域作用标签&#xff1…

抖音关键词搜索小程序排名怎么做

抖音关键词搜索小程序排名怎么做 1 分钟教你制作一个抖音小程序。 抖音小程序就是我的视频&#xff0c;左下方这个蓝色的链接&#xff0c;点进去就是抖音小程序。 如果你有了这个小程序&#xff0c;发布视频的时候可以挂载这个小程序&#xff0c;直播的时候也可以挂载这个小…

快速使用Linux系统中SSH

在Linux系统中&#xff0c;使用SSH代理跳板机是一种有效的方式&#xff0c;可以实现安全连接和访问远程服务器。本文将详细介绍SSH代理跳板机的设置和使用方法。 什么是SSH代理跳板机&#xff1f; SSH代理跳板机是一种在Linux系统中使用SSH协议实现的代理服务器。通过配置相关…

bytesec靶场

靶场下载 https://www.vulnhub.com/entry/hacknos-os-bytesec,393/ 下载完成后进入配置修改网卡 教程 配置 第一步&#xff1a;启动靶机时按下 shift 键&#xff0c; 进入以下界面 第二步&#xff1a;选择第二个选项&#xff0c;然后按下 e 键&#xff0c;进入编辑界面 将…

DRF的filter组件

DRF的Filter组件 如果某个API需要传递一些条件进行搜索&#xff0c;其实就在是URL后面通过GET传参即可&#xff0c;例如&#xff1a; /api/users?age19&category12在drf中filter组件可以支持条件搜索。 1. 自定义filter # models.py from django.db import modelsclas…

[NLP]LLM 训练时GPU显存耗用量估计

以LLM中最常见的Adam fp16混合精度训练为例&#xff0c;分析其显存占用有以下四个部分&#xff1a; GPT-2含有1.5B个参数&#xff0c;如果用fp16格式&#xff0c;只需要1.5G*2Byte3GB显存, 但是模型状态实际上需要耗费1.5B*1624GB. 比如说有一个模型参数量是1M&#xff0c;在…

[GAN] 使用GAN网络进行图片生成的“调参人”入门指南——生成向日葵图片

[GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片 文章目录 [GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片1. 写在前面&#xff1a;1.1 应用场景&#xff1a;1.2 数据集情况&#xff1a;1.3 实验原理讲解和分析&#xff08;简化版&#x…

Flink CDC系列之:TiDB CDC 导入 Elasticsearch

Flink CDC系列之&#xff1a;TiDB CDC 导入 Elasticsearch 一、通过docker 来启动 TiDB 集群二、下载 Flink 和所需要的依赖包三、在TiDB数据库中创建表和准备数据四、启动Flink 集群&#xff0c;再启动 SQL CLI五、在 Flink SQL CLI 中使用 Flink DDL 创建表六、Kibana查看Ela…

H3C QoS打标签和限速配置案例

EF&#xff1a;快速转发 AF&#xff1a;确保转发 CS&#xff1a;给各种协议用的 BE&#xff1a;默认标记(尽力而为) VSR-88-2 出口路由配置&#xff1a; [H3C]dis current-configuration version 7.1.075, ESS 8305 vlan 1 traffic classifier vlan10 operator and if-match a…

关于consul的下载方法

linux下 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install consulwindow下 https://developer.hashicorp.com/consul/downloads 然后把里面的exe文件放在gopath下就行了 验证…

苍穹外卖day11笔记

今日首先介绍前端技术Apache ECharts&#xff0c;说明后端需要准备的数据&#xff0c;然后讲解具体统计功能的实现&#xff0c;包括营业额统计、用户统计、订单统计、销量排名。 一、ECharts 是什么 ECharts是一款基于 Javascript 的数据可视化图表库。我们用它来展示图表数…

说一下什么是tcp的2MSL,为什么客户端在 TIME-WAIT 状态必须等待 2MSL 的时间?

1.TCP之2MSL 1.1 MSL MSL:Maximum Segment Lifetime报文段最大生存时间&#xff0c;它是任何报文段被丢弃前在网络内的最长时间 1.2为什么存在MSL TCP报文段以IP数据报在网络内传输&#xff0c;而IP数据报则有限制其生存时间的TTL字段&#xff0c;并且TTL的限制是基于跳数 1.3…