C语言小程序:通讯录(静态版)

article/2025/9/3 17:31:18
哈喽各位老铁们,今天给大家带来一期通讯录的静态版本的实现,何为静态版本后面会做解释,话不多说,直接开始!
关于通讯录,其实也就是类似于我们手机上的通讯录一样,有着各种各样的功能,小编来带大家实现一部分功能就好啦(1.添加联系人 2. 删除指定联系人 3.查找指定联系人 4.修改指定联系人 5.显示全部联系人 6.排序通讯录 7.清空通讯录)要实现这些功能,首先得要有一个可以存放联系人的一块空间,而要存放的联系人的个人信息有:名字、性别、年龄、电话、家庭地址。这些个人信息类型不同,大小也不同,那该如何去存放,如何查找,又该如何去修改?我们一步一步来通过代码的方式实现这些功能

1.文件的划分

在前面发布的博客中就提到过划分文件进行编写,在之前的三子棋、扫雷的代码中就是通过划分文件,每一个文件实现相对应的功能,互不干扰,那么通讯录也要使用同样的方法

头文件:Contact.h

在头文件里面主要实现函数的声明,变量的定义、头文件的包含

源文件:Contact.c

在这个源文件里面实现通讯录的实现模块

源文件:test.c

这个源文件里面实现测试通讯录相关的功能

2.通讯录

实现一个通讯录:
1.这个通讯录可以存放100个人的信息
2.每个人的信息:
名字、性别、年龄、电话、地址
3.通讯录所包含的功能
添加联系人、删除联系人、查找联系人、修改联系人、显示通讯录、排序通讯录、清空通讯录

首先我们先搭出通讯录的基本框架:

头文件:Contact.h

//头文件的包含#include <stdio.h>

源文件: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("****  7.Clear   *****    0.Exit   ****\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 7://清空break;case 0:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}

但是如果这样字写,在代码可读性不高,为什么呢?当代码走到switch case 语句中,这里的case1、case2...里面的1、2..都代表什么呢?就得返回到最上面重新查看,因此这里需要完善一下,我们可以使用枚举,将我们选择的全部可能型都一一列举出来,然后进行选择,就比较方便。

优化代码:

enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT,CLEAR
};
//枚举的可能取值默认是从0开始,在这里刚好对应菜单里面的选项
int main()
{int input = 0;do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人break;case DEL://删除联系人break;case SEARCH://查找联系人break;case MODIFY://修改联系人break;case SHOW://展示break;case SORT://排序联系人break;case CLEAR://清空break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}

基本框架搭建好了之后,就得有一个块空间来存放我们的联系人了,而联系人的信息又有多种,因此就需要一个结构体来存放联系人的信息,这里还存在一个问题,我们存放的联系人从哪里开始存放呢?所以我们还需要一个变量来确定联系人该存放在哪里,而且每当我们存放一个联系人,这个变量就要+1,以便下一个联系人存放在上一个联系人的后面。

注:如果我们将这个结构体创建在源文件中,就得在两个源文件中都要创建,因此为了节省空间,可以直接将结构体变量创建在头文件中

头文件:Contact.h

//表示一个联系人的各种信息
typedef struct PeoInfo
{char name[20];int age;char sex[5];char tele[12];char addr[20];
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[100];   //用来存放100个人的信息int sz;              //记录通讯录中有效信息的个数
}Contact;
如果这样子写还是有一个弊端,如果后期要修改通讯录中存放联系人的个数和每一个联系人信息中存放的大小,所有有关的数组都得一一修改,因此我们可以直接用#define来定义大小

代码优化:

//大小的定义
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20//表示一个联系人的各种信息
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[MAX];   //用来存放100个人的信息int sz;              //记录通讯录中有效信息的个数
}Contact;

这样子写在后期需要修改的时候就比较方便


存放联系人的空间也搭建好了,但是创建好的空间里面刚刚开始放的是什么东西呢?我们也不知道,因此我们先得给通讯录进行初始化,让里面一个联系人也没有,让标记的变量也变为0

2.1初始化通讯录

初始化通讯录我们分装一个函数:InitContact

源文件:test.c

int main()
{int input = 0;Contact con;   //创建通讯录变量//初始化通讯录InitContact(&con);  //要修改通讯录里面的内容要传递指针do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人break;case DEL://删除联系人break;case SEARCH://查找联系人break;case MODIFY://修改联系人break;case SHOW://展示break;case SORT://排序联系人break;case CLEAR://清空break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}

头文件Contact.h

#include <string.h>
//函数的声明
//初始化通讯录
void InitContact(Contact* pc);

源文件:Contact.c

//初始化通讯录
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));//memset函数在使用时要包含头文件<string.h>
}

2.2添加联系人

初始化好通讯录的内容之后,接下来就到了我们进行通讯录功能的实现了,首先我们实现添加联系人功能,要添加联系人,我们要确定sz的大小,如果sz等于MAX了,那不就证明通讯录以及满了嘛,就再不能添加联系人了,只有sz小于MAX的时候才可以添加联系人

源文件:test.c

case ADD://添加联系人printf("添加联系人\n");AddContact(&con); //传址调用break;

头文件: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("%d", &(pc->data[pc->sz].age));printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;  //每一次添加完之后sz都要++printf("添加成功\n");
}

2.3展示通讯录

要展示通讯录,可以先打印一行标题,有助于展示,打印整个通讯录就可以使用循环,设置一个循环,循环条件只要小于sz的大小就可以

源文件:test.c

case SHOW://展示ShowContact(&con);//显示通讯录不需要修改通讯录其实传值调用也可以,但是为了节省空间使用传值调用break;

头文件:Contact.h

//显示通讯录
void ShowContact(Contact* pc);

源文件:Contact.c

//显示通讯录
void ShowContact(Contact* pc)
{//先打印标题printf("%-10s %-2d %-5s %-10s %-15s\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-10s %-2d %-5s %-10s %-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}

2.4删除联系人

要删除联系人,首先得判断这个通讯录里面有没有联系人呀,所以要先判断sz是否为0,如果为0就证明没有联系人,判断完之后,需要删除联系人,那么首先得找到所想删除的联系人的位置,然后将这个位置记录下来,通过下标的形式访问,然后进行删除,这里还要注意,如果找完了整个通讯录,没有找到与之匹配的名字,那么就没有这个人,在删除的时候就是将记录的那个位置上的人,用后面一个人的信息进行覆盖,依次类推,然后整个通讯录的总人数减1就行了

源文件:test.c

case DEL://删除联系人printf("删除联系人\n");DelContact(&con);

头文件:Contact.h

//删除联系人
void DelContact(Contact* pc);

源文件:Contact.c

//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要删除的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){pos = i;break;}}if (i == pc->sz){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}//删除完之后sz减一pc->sz--;printf("删除成功\n");
}

2.5查找联系人

查找联系人和删除练习人的基本步骤一样,先判断是否为空通讯录,然后进行查找,记录位置,然后打印

源文件:test.c

case SEARCH://查找联系人printf("查找联系人\n");SearchContact(&con);break;

头文件:Contact.h

//查找联系人
void SearchContact(Contact* pc);

源文件:Contact.c

//查找联系人
void SearchContact(Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要查找的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){pos = i;break;}}if (i == pc->sz){printf("找不到所要查找的联系人\n");return;}//打印导航栏printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}

写到这里,我们不难发现这个查找联系人的过程重复了两次,在删除联系人和查找的时候都出现了,因此我们可以简化一下代码,直接将查找的过程分装一个查找函数,然后在使用的时候代码就不显得那么冗余,每次使用查找就直接调用这个函数

代码优化:

static int FindByName(const Contact* pc, char name[]) //使用static修饰,        //只在本源文件中使用
{int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要删除的联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}//查找联系人
void SearchContact(const Contact* pc) //使用const修饰更安全
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//打印导航栏printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}

2.6修改联系人

要修改联系人,首先的找到联系人的位置,然后输入信息将其修改

源文件:test.c

case MODIFY://修改联系人printf("修改联系人\n");ModifyContact(&con);break;

头文件:Contact.h

//修改联系人
void ModifyContact(Contact* pc);

源文件:Contact.c

//修改联系人
void menu1()
{printf("**********************************\n");printf("******1.姓名*********2.年龄*******\n");printf("******3.性别*********4.电话*******\n");printf("*************5.地址***************\n");printf("**********************************\n");
}
void ModifyContact(Contact* pc)
{int input = 0;char name[MAX_NAME] = { 0 };printf("请输入你要修改的联系人姓名:>");scanf("%s", name);//查找int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//修改printf("请输入要修改的具体信息:>\n");menu1();scanf("%d", &input);switch (input){case 1:printf("请输入新的姓名:>");scanf("%s", pc->data[pos].name);break;case 2:printf("请输入新的年龄:>");scanf("%d", &pc->data[pos].age);break;case 3:printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);break;case 4:printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);break;case 5:printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);break;default:printf("输入有误,修改失败\n");return;}printf("修改成功\n");
}

2.7排序联系人

要排序联系人,也就意味着要排序结构体成员,就需要用到qsort排序,如果不清楚可以点击查看-> qsort排序详解

源文件:test.c

case SORT://排序联系人SortContact(&con);break;

头文件:Contcat.h

#include <stdlib.h>
//排序联系人
void SortContact(Contact* pc);

源文件:Contact.c

void menu2()
{printf("***************************\n");printf("******** 1.NAME  **********\n");printf("******** 2.AGE   **********\n");printf("***************************\n");
}//按照名字排序
int cmp_byname(const void* p1, const void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}//按照年龄来排序
int cmp_byage(const void* p1, const void* p2)
{return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}//排序联系人
void SqrtContact(Contact* pc)
{int input = 0;if (pc->sz == 0){printf("通讯录没有联系人,无法排序!\n");return;}menu2();printf("请选择排序的对象:>");scanf("%d", &input);switch (input){case 1:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byname);break;case 2:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byage);break;}printf("排序成功\n");//排序成功之后打印一下ShowContact(pc);
}

2.8清空联系人

清空联系人本质上就是再将通讯录初始化,我们只需要再进行调用初始化函数就可以了

源文件:test.c

case CLEAR://清空联系人ClearContact(&con);break;

头文件:Contact.h

//清空联系人
void ClearContact(Contact* pc);

源文件:Contact.c

//清空联系人
void ClearContact(Contact* pc)
{//初始化通讯录InitContact(pc);printf("清空成功\n");//初始完之后再打印ShowContact(pc);
}

3.完整代码

头文件:Contact.h

#pragma once//头文件的包含#include <stdio.h>
#include <string.h>
#include <stdlib.h>//大小的定义
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 20//表示一个联系人的各种信息
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//通讯录
typedef struct Contact
{PeoInfo data[MAX];   //用来存放100个人的信息int sz;              //记录通讯录中有效信息的个数
}Contact;//函数的声明
//初始化通讯录
void InitContact(Contact* pc);//添加联系人
void AddContact(Contact* pc);//显示通讯录
void ShowContact(const Contact* pc);//删除联系人
void DelContact(Contact* pc);//查找联系人
void SearchContact(const Contact* pc);//修改联系人
void ModifyContact(Contact* pc);//排序联系人
void SqrtContact(Contact* pc);//清空联系人
void ClearContact(Contact* pc);

源文件:test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h"//测试通讯录相关的功能void menu()
{printf("**************************************\n");printf("****  1.Add     *****    2.Del    ****\n");printf("****  3.Search  *****    4.Modify ****\n");printf("****  5.Show    *****    6.Sqrt   ****\n");printf("****  7.Clear   *****    0.Exit   ****\n");printf("**************************************\n");
}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SQRT,CLEAR
};int main()
{int input = 0;Contact con;   //创建通讯录变量//初始化通讯录InitContact(&con);  //要修改通讯录里面的内容要传递指针do{menu();printf("请选择通讯录的功能:>");scanf("%d", &input);switch (input){case ADD://添加联系人printf("添加联系人\n");AddContact(&con); //传址调用break;case DEL://删除联系人printf("删除联系人\n");DelContact(&con);break;case SEARCH://查找联系人printf("查找联系人\n");SearchContact(&con);break;case MODIFY://修改联系人printf("修改联系人\n");ModifyContact(&con);break;case SHOW://展示ShowContact(&con);//显示通讯录不需要修改通讯录其实传值调用也可以,但是为了节省空间使用传值调用break;case SQRT://排序联系人SqrtContact(&con);break;case CLEAR://清空联系人ClearContact(&con);break;case EXIT:printf("退出通讯录!\n");break;default:printf("选择错误,请重新选择:>\n");break;}} while (input);return 0;
}

源文件:Contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h"
//通讯录的实现模块//初始化通讯录
void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}//添加联系人
void AddContact(Contact* pc)
{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].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;  //每一次添加完之后sz都要++printf("添加成功\n");
}//显示通讯录
void ShowContact(const Contact* pc)
{printf("%-10s %-4s %-5s %-12s %-15s\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-15s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}//查找
static int FindByName(const Contact* pc, char name[])
{int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){//找到所要联系人所在的位置if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}
//删除联系人
void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };//判断通讯录是否为空if (0 == pc->sz){printf("通讯录为空,无法删除!\n");return;}printf("请输入你要删除联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要删除的联系人\n");return;}//进行删除for (i = pos; i < pc->sz - 1; i++) //判断条件这里所要交换的比总数少一个{pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}//查找联系人
void SearchContact(const Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,查找不到!");return;}printf("请输入你要查找联系人的姓名:>");scanf("%s", name);int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//打印导航栏printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}//修改联系人
void menu1()
{printf("*********************************\n");printf("******1.姓名*********2.年龄*******\n");printf("******3.性别*********4.电话*******\n");printf("*************5.地址**************\n");printf("*********************************\n");
}
void ModifyContact(Contact* pc)
{int input = 0;char name[MAX_NAME] = { 0 };printf("请输入你要修改的联系人姓名:>");scanf("%s", name);//查找int pos = FindByName(pc, name);int i = 0;if (pos == -1){printf("找不到所要查找的联系人\n");return;}//修改printf("请输入要修改的具体信息:>\n");menu1();scanf("%d", &input);switch (input){case 1:printf("请输入新的姓名:>");scanf("%s", pc->data[pos].name);break;case 2:printf("请输入新的年龄:>");scanf("%d", &pc->data[pos].age);break;case 3:printf("请输入新的性别:>");scanf("%s", pc->data[pos].sex);break;case 4:printf("请输入新的电话:>");scanf("%s", pc->data[pos].tele);break;case 5:printf("请输入新的地址:>");scanf("%s", pc->data[pos].addr);break;default:printf("输入有误,修改失败\n");return;}printf("修改成功\n");
}void menu2()
{printf("***************************\n");printf("******** 1.NAME  **********\n");printf("******** 2.AGE   **********\n");printf("***************************\n");
}//按照名字排序
int cmp_byname(const void* p1, const void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}//按照年龄来排序
int cmp_byage(const void* p1, const void* p2)
{return ((PeoInfo*)p1)->age - ((PeoInfo*)p2)->age;
}//排序联系人
void SqrtContact(Contact* pc)
{int input = 0;if (pc->sz == 0){printf("通讯录没有联系人,无法排序!\n");return;}menu2();printf("请选择排序的对象:>");scanf("%d", &input);switch (input){case 1:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byname);break;case 2:qsort(pc, pc->sz, sizeof(PeoInfo), cmp_byage);break;}printf("排序成功\n");//排序成功之后打印一下ShowContact(pc);
}//清空联系人
void ClearContact(Contact* pc)
{//初始化通讯录InitContact(pc);printf("清空成功\n");//初始完之后再打印ShowContact(pc);
}

关于通讯录的代码就展现在这里了,但是这只是静态版本,还有很多的不足,当退出程序后下一次再进入程序我们之前的信息就回收了,还有各个数组的大小都是固定的,没办法随时随地的变化,在后面也会补发上关于通讯录的动态版本的代码,最后感谢大家的支持!谢谢


http://chatgpt.dhexx.cn/article/rcBNGwpT.shtml

相关文章

C语言小程序分享

本文为大一时所写的文章&#xff08;2017/4/23&#xff09;&#xff0c;文笔还很生疏&#xff0c;在很多问题上认识不深&#xff0c;算是在学校的微信公众号上的一个编程探究模块上的投稿&#xff0c;本人当时也参与了本模块的维护和管理。补档。 上个周末的一个下午&#xff0…

C语言小程序-学生成绩统计系统

C语言小程序-学生成绩统计系统 参考了 另一位博主的代码(https://blog.csdn.net/qq_36503589/article/details/53106983) 我后来写的成绩排序版本链接&#xff1a;https://blog.csdn.net/qq_43617268/article/details/103491760 功能介绍&#xff1a;本程序可以输入50人以内的…

C语言10个经典小程序——小白必备!

网上有很多的人说编程有多么多么无聊。。。。So Boring ! 。。。其实小编想说:不要管别人怎么说,别人说什么,做你自己喜欢做的事就好。坚持下来,你会发现编程的乐趣的。。。。当然,如果你觉得学习编程语言很痛苦,坚持了一段时间后无果,南无果断放弃未必不是一个好的选择…

C语言小程序:如何用代码“画”出一个爱心

利用ASCII编码第三个字符&#xff0c;作为基础&#xff0c;然后利用三个多重循环画出一个爱心出来。要使用控制台改变运行框大小和文字的颜色&#xff0c;黑白的爱心不免有些诡异。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> #inclu…

我的第一个c语言小程序

标题&#xff1a;判断题答题小程序 Author: plc6666 软工专业 工科男 格言&#xff1a;总有人间一两风&#xff0c;填我十万八千梦。 文章目录 标题&#xff1a;判断题答题小程序 一.程序的由来二.程序的状况1.程序实现了颜色转换的功能2.程序能随机抽20题&#xff0c;不重复3.…

C语言10个经典小程序

【程序1】 题目&#xff1a;有1、2、3、4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f; 1.程序分析&#xff1a;可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去       掉不满足条件的排列。 2.程序源…

用 C语言的写出几个小程序

系列文章目录 前言 1、第一章&#xff1a;求出一个整型数组中的最大值 2、第二章&#xff1a;打印出100~999之间所有的水仙花数 3、第三章&#xff1a;输入一个数&#xff0c;打印出n行杨辉三角 4、第四章&#xff1a;小只因跳楼梯问题 5、第五章&#xff1a;创建一个含是…

C语言小程序

1、猜数字游戏 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <time.h>//猜数字游戏 int main() {int guess 0;//生成随机数//0~99 --> 1~100int ret rand() % 100 1;//生成随机数的函数printf("请猜数字 …

服务器登录原理,单点登陆(单点登录原理)

单点登录简介 SSO&CAS是什么 单点登录适合什么场景 单点登录的三种实现方式 CAS的几个重要知识点 CAS的实现过程 单点登录简介 单点登录(SingleSignOn&#xff0c;SSO)&#xff0c;就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后&#xff0c;即可获得…

单点登陆 SSO

参考文章 同域下的单点登录 &#xff08;sso.a.com、app1.a.com、app2.a.com&#xff09; 统一通过sso.a.com 登录&#xff0c;但有以下两个问题&#xff1a; 1、Cookie是不能跨域的&#xff0c;我们Cookie的domain属性是sso.a.com&#xff0c;在给app1.a.com和app2.a.com发送…

五、微服务版单点登陆系统(SSO)

微服务版单点登陆系统(SSO)实践 文章目录 微服务版单点登陆系统(SSO)实践一、单点登陆系统简介1. 背景分析2. 单点登陆系统概述3. 单点登陆系统解决方案设计 二、单点登陆系统初步设计1. 服务设计2. 工程结构设计 三、系统基础服务工程设计及实现1. 业务描述2. 表结构设计3. 工…

单点登陆(SSO)

一、背景 在企业发展初期&#xff0c;企业使用的系统很少&#xff0c;通常一个或者两个&#xff0c;每个系统都有自己的登录模块&#xff0c;运营人员每天用自己的账号登录&#xff0c;很方便。但随着企业的发展&#xff0c;用到的系统随之增多&#xff0c;运营人员在操作不同的…

08单点登陆+Oauth2

详情&#xff1a;如看不懂跳转此地 1.1单点登录系统 每个站点都实现了专用登录模块。各站点的登录状态相互不认可&#xff0c;各站点需要逐一手工登录 这样的系统&#xff0c;我们又称之为多点登陆系统。应用起来相对繁琐&#xff08;每次访问资源服务都需要重新登录认证和授…

微服务版单点登陆系统(SSO)

单体架构中的用户的状态的存储是如何实现的? 单点登陆系统概述 单点登录&#xff0c;英文是 Single Sign On&#xff08;缩写为 SSO&#xff09;。即多个站点共用一台认证授权服务器&#xff0c;用户在其中任何一个站点登录后&#xff0c;可以免登录访问其他所有站点。而且&a…

SpringBoot跨系统单点登陆的实现

什么是单点登陆 单点登录&#xff08;英语&#xff1a;Single sign-on&#xff0c;缩写为 SSO&#xff09;&#xff0c;又译为单一签入&#xff0c;一种对于许多相互关连&#xff0c;但是又是各自独立的软件系统&#xff0c;提供访问控制的属性。当拥有这项属性时&#xff0c;…

单点登陆的实现

王昱 yuwang881gmail.com 博客地址 http://yuwang881.blog.sohu.com 摘要 &#xff1a;单点登录&#xff08; SSO &#xff09;的技术被越来越广泛地运用到各个领域的软件系统当中。本文从业务的角度分析了单点登录的需求和应用领域&#xff1b;从技术本身的角度分析了单点…

CAS 单点登陆

一、Tomcat配置SSL 1. 生成 server key 以命令方式换到目录%TOMCAT_HOME%,在command命令行输入如下命令&#xff1a; keytool -genkey -alias tomcat_key -keyalg RSA -storepass changeit -keystore server.keystore -validity 3600 用户名输入域名&#xff0c;如localhos…

单点登陆的测试

今天做了个单点登陆 。 但是怎么测试呢&#xff1f; 下面请看详解&#xff1a; 源码中是这样的&#xff1a; /*** 单点登录改造* * param request* param response* return* throws IOException* throws HttpException* throws IOException*/RequestMapping(value "/rcbS…

LINUX单点登陆

1.在grub引导界面(如下图)按e进入编辑模式 2.按↓键&#xff0c;找到以linux16开头的行&#xff0c;在最后加上 rd.break(如下图&#xff0c;注意前面有一个空格) 3.按Ctrlx进入救援模式 4.重新挂载/sysroot为可读写模式&#xff0c;并切换根目录为/sysroot # mount -o remou…

java实现单点登陆(SSO)

java实现单点登陆&#xff08;SSO&#xff09; 网络域名必须完全一致&#xff0c;才代表同一站点。 域名映射 &#xff1a;访问后面的 会跳转到前面 单点登陆概念&#xff1a; 多系统&#xff0c;单一位置登录&#xff0c;实现多系统同时登陆。常出现在互联网和企业级平台中。…