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.rhkb.cn/news/5568.html

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

相关文章

c++ 与 Matlab 程序的数据比对

文章目录 背景环境数据保存数据加载 背景 ***避免数据精度误差&#xff0c;快速对比变量 *** 环境 c下载 https://github.com/BlueBrain/HighFive 以及hdf5库 在vs 中配置库 数据保存 #include <highfive/highfive.hpp> using namespace HighFive;std::string fil…

【2024 博客之星评选】请继续保持Passion

我尝试复盘自己2024年走的路&#xff0c;希望能给诸君一些借鉴。 文章目录 回头望感想与收获成长与教训今年计划感恩一些体己话 回头望 回望我的2024年&#xff0c;年初拿高绩效&#xff0c;但感觉逐渐被公司一点点剥离出中心&#xff1b;年中一直在学习防患于未然&#xff1b…

unity插件Excel转换Proto插件-ExcelToProtobufferTool

unity插件Excel转换Proto插件-ExcelToProtobufferTool **ExcelToProtobufTool 插件文档****1. 插件概述****2. 默认配置类&#xff1a;DefaultIProtoPathConfig****属性说明** **3. 自定义配置类****定义规则****示例代码** **4. 使用方式****4.1 默认路径****4.2 自定义路径**…

总结 uniapp 上不适配iphone的:new Date 时间、border线条、渐变

1、border样式缺了一边 这是错误样式&#xff1a; 需要添加: border: 1rpx solid #57c7bb; transform: rotateZ(0deg);//加入此代码解决iphone 不适配问题2、时间出现NaN 原因是因为ios中使用new Date 的时候出了问题 解决方案: 1.调整时间格式:将时间格式从"yyyy-MM-d…

【深度学习】Java DL4J 2024年度技术总结

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

快速学习GO语言总结

干货分享&#xff0c;感谢您的阅读&#xff01;备注&#xff1a;本博客将自己初步学习GO的总结进行分享&#xff0c;希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力&#xff0c;如有错误请留言指正&#xff0c;谢谢&#xff01; 一、初步了解Go语言 &#xf…

【深度学习】2.视觉问题与得分函数

计算机视觉任务 可以通过神经网络搜索是什么类别的动物。 图像实际就是含有数值的三维矩阵。 像素值从0-255可以表示亮度递增的参数。数字越大&#xff0c;像素点越亮。 最后的3表示三个颜色通道&#xff0c;常见的如JPG、RGB等。 现实场景容易发生各种遮蔽现象。 计算机判断…

本地 AI 模型“不实用”?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【Maui】下拉框的实现,绑定键值对

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&…

AI守护煤矿安全生产:基于视频智能的煤矿管理系统架构解析

前言 本文我将介绍我和我的团队自主研发设计的一款AI产品的成果展示——“基于视频AI识别技术的煤矿安全生产管理系统”。 这款产品是目前我在创业阶段和几位矿业大学的博士共同从架构设计、开发到交付的全过程中首次在博客频道发布, 我之前一直想写但没有机会来整理这套系统的…

.NET开源的处理分布式事务的解决方案

前言 在分布式系统中&#xff0c;由于各个系统服务之间的独立性和网络通信的不确定性&#xff0c;要确保跨系统的事务操作的最终一致性是一项重大的挑战。今天给大家推荐一个.NET开源的处理分布式事务的解决方案基于 .NET Standard 的 C# 库&#xff1a;CAP。 CAP项目介绍 C…

计算机网络 (52)秘钥分配

一、重要性 在计算机网络中&#xff0c;密钥分配是密钥管理中的一个核心问题。由于密码算法通常是公开的&#xff0c;因此网络的安全性主要依赖于密钥的安全保护。密钥分配的目的是确保密钥在传输过程中不被窃取或篡改&#xff0c;同时确保只有合法的用户才能获得密钥。 二、方…

Open3D计算点云粗糙度(方法一)【2025最新版】

目录 一、Roughness二、代码实现三、结果展示博客长期更新,本文最近更新时间为:2025年1月18日。 一、Roughness 通过菜单栏的Tools > Other > Roughness找到该功能。 这个工具可以估计点云的“粗糙度”。 选择一个或几个点云,然后启动这个工具。 CloudCompare只会询问…

DDD - 整洁架构_解决技术设计困局

文章目录 Pre如何落地 DDD底层技术的更迭 整洁架构的设计主动适配器/北向适配器被动适配器/南向适配器 整洁架构的落地总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对象的两种设计思路…

一个软件分发和下载的网站源码,带多套模板

PHP游戏应用市场APP软件下载平台网站源码手机版 可自行打包APP&#xff0c;带下载统计&#xff0c;带多套模板&#xff0c;带图文教程 代码下载&#xff1a;百度网盘

OSPF协议部分解读

多年前所写, 主要是对OSPF的RFC协议标准的解读. 工作中接触网络路由协议OSPF的同学可以参考参考.如有理解错误请谅解, 不过可以肯定的是一定有理解错误的地方的. RFC2328 1.1小节 1. OSPF routes IP packets based solely on the destination IPaddress found in the IP pac…

安装wxFormBuilder

1. 网址&#xff1a;GitHub - wxFormBuilder/wxFormBuilder: A wxWidgets GUI Builder 2. 安装MSYS2 MSYS2可以在GitHub的内容中找到&#xff0c;这个版本是32位64位的 3. 在程序中打开MINGW64 shell 4. 在MSYS2 MINGW64 shell中输入 pacman -Syu pacman -S ${MINGW_PACKAGE…

基于微信小程序高校订餐系统的设计与开发ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

C#中的语句

C#提供了各式各样的语句&#xff0c;大多数是由C和C发展而来&#xff0c;当然&#xff0c;在C#中做了相应修改。语句和表达式一样&#xff0c;都是C#程序的基本组成部分&#xff0c;在本文我们来一起学习C#语句。 1.语句 语句是构造所有C#程序的过程构造块。在语句中可以声明…

微服务学习-Gateway 统一微服务入口

1. 微服务为什么需要 API 网关&#xff1f; 1.1. 在微服务架构中&#xff0c;通常一个系统会被拆分为多个微服务&#xff0c;面对多个微服务客户端应该如何去调用呢&#xff1f; 如果根据每个微服务的地址发起调用&#xff0c;存在如下问题&#xff1a; 客户端多次请求不同的…