C语言之通讯录的实现(静态版,动态版,文件版)

个人主页(找往期文章包括但不限于本期文章中不懂的知识点): 我要学编程(ಥ_ಥ)-CSDN博客

目录

静态通讯录的实现逻辑 

test.c:通讯录的逻辑实现

Contact.h:函数的声明与头文件的包含

Contact.c:函数的实现 

通讯录源码: 

test.c:

Contact.c:

Contect.h:

动态版通讯录 

test.c:

Contact.h:

Contact.c: 

动态通讯录(文件版)

test.c: 

Contact.h: 

Contact.c: 


静态通讯录的实现逻辑 

test.c:通讯录的逻辑实现

我们今天就一起来用c语言写一个通讯录的小程序。

这个通讯录可以实现存储100个联系人。

首先,我们进去这个通讯录,肯定得有一些基本的功能。如下图:

这个就和我们在前面写游戏的时候是一样的。

void menu()
{printf("******************************************\n");printf("****  1.增加联系人      2.删除联系人  ****\n");printf("****  3.查找联系人      4.修改联系人  ****\n");printf("****  5.显示联系人     6.排序联系人   ****\n");printf("****           0.退出通讯录           ****\n");printf("******************************************\n");
}

打印出界面之后,我们就得根据需求来进行选择。

void test()
{int input = 0;//下面是对通讯录进行的各种操作,所以我们得先有一个通讯录//创建一个通讯录,包含一个人的各种信息,是一个复杂对象,用结构体来描述Contact con;InitContact(&con);//初始化通讯录do{menu();//打印基本功能printf("请选择:");scanf("%d", &input);switch (input){case 1:AddContact(&con);//增加联系人的信息break;case 2:DelContact(&con);//删除联系人的信息break;case 3:SearchContact(&con);//查找联系人的信息break;case 4:ModifyContact(&con);//修改联系人的信息break;case 5:ShowContact(&con);//显示联系人的信息break;case 6:SortContact(&con);//排序联系人break;case 0:printf("退出通讯录\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);}

为了让别人能够更清楚我们代码的功能,我们最好能把那些case后面的数字,改成ADD这些能够让别人一下就能够看懂。我们就可以联想到联合体。自定义类型:联合和枚举-CSDN博客

上面这篇博客,有关于联合体的知识。

void test()
{int input = 0;//下面是对通讯录进行的各种操作,所以我们得先有一个通讯录Contact con;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);}

可以把test函数在main函数里调用。

#include "Contact.h"
int main()
{test();return 0;
}

写完这些基本的功能之后,就可以开始实现这些编辑通讯录的函数了。上面这些都是放在test.c函数(实现通讯录的基本逻辑)。

Contact.h:函数的声明与头文件的包含

这些函数的声明和头文件的声明,我们都可以放在一个Contact.h的头文件中。 

头文件的声明:

//头文件的声明
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

联合体的创建: 

//把选项一 一列举出来
enum OPPION
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};

通讯录准备: 

//为后期增加联系人做准备
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30//类型的声明
typedef struct people
{char name[MAX_NAME];//姓名int age;//年龄char sex[MAX_SEX];//性别//电话(我们正常的电话是11位,超过了int的范围,所以用字符串比较合适)char tele[MAX_TELE];char addr[MAX_ADDR];//住址
}people;//通讯录的创建
typedef struct Contact
{people data[MAX];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 SortContact(const Contact* pc);

Contact.c:函数的实现 

初始化通讯录函数: 

#include "Contact.h"//声明头文件//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);//把pc->data的空间全部初始化为0memset(pc->data, 0, sizeof(pc->data));//循环也可以,但是太麻烦。pc->sz = 0;
}

增加联系人信息的函数: 

//增加联系人信息的函数
void AddContact(Contact* pc)
{assert(pc);//首先得判断这个通讯录是否已经满了if (pc->sz == MAX){printf("通讯录已满,无法增加\n");//通讯录满了,就无需执行下面的语句了return;//因为是void。所以无需返回任何值}else{printf("请输入姓名:");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));//age是int类型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++;printf("成功增加联系人\n");}
}

显示联系人的信息的函数: 

//显示联系人的信息的函数
void ShowContact(const Contact* pc)
{assert(pc);//要有一定的排版(采用左对齐)printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}
}

 删除联系人信息的函数的声明:

//删除联系人信息的函数的声明
void DelContact(Contact* pc)
{assert(pc);//判断是否能删除if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//创建一个name数组来存放我们要寻找的联系人char name[MAX_NAME] = { 0 };//知道要删除谁printf("请输入要删除的人的名字:");scanf("%s", name);//找到要删除的人(字符串)int del = 0;int flag = 0;//遍历数组,一个一个的比较字符串for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;//记录当前的位置flag = 1;break;}}//开始删除(删除的方法就是把后面一个往前覆盖)if (flag == 0){printf("要删除的联系人不存在\n");return;//后面的代码无需执行}else{for (int i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}}//删除最后一个元素时,虽然不能在循环中删除,但是pc->sz--了,致使访问不到最后一个元素了//因此,我们在打印时也不会打印出来pc->sz--;printf("删除成功\n");
}

其实我们会发现在这里寻找名字的时候,在后面查找联系人也会用到,不如我们直接分装成一个寻找名字的函数。

//查找联系人名字的函数
//这个函数我们只想在内部使用,没必要暴露给别人
static int FindByName(const Contact* pc, char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}

那么上面的删除函数就可以改造成:

//删除联系人信息的函数的声明
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);if (del == -1){printf("要删除的人不存在\n");return;}for (int i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}//删除最后一个元素时,虽然不能在循环中删除,但是pc->sz--了,致使访问不到最后一个元素了//因此,我们在打印时也不会打印出来pc->sz--;printf("删除成功\n");
}

查找指定联系人信息的函数: 

//查找指定联系人信息的函数
void SearchContact(const Contact* pc)
{assert(pc);//存放名字的数组char name[MAX_NAME];printf("请输入要查找的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}

修改指定联系人的信息: 

void menu1()
{printf("*******************************\n");printf("****  1.姓名     2.年龄    ****\n");printf("****  3.性别     4.电话    ****\n");printf("****        5.住址         ****\n");printf("*******************************\n");
}
//修改指定联系人的信息
void ModifyContact(Contact* pc)
{assert(pc);//存放名字的数组char name[MAX_NAME];printf("请输入要修改的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的联系人不存在\n");return;}menu1();printf("请选择要修改的选项:");int n = 0;scanf("%d", &n);switch (n){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;}printf("修改成功\n");//看看是否修改成功printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}
int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp(((people*)e1)->name, ((people*)e2)->name);
}int cmp_peo_by_age(const void* e1, const void* e2)
{return ((people*)e1)->age - ((people*)e2)->age;
}
//排序联系人
void SortContact(const Contact* pc)
{printf("请选择想要排的序:\n");printf("********************************\n");printf("*****   1.按照名字排序    ******\n");printf("*****   2.按照年龄排序    ******\n");printf("********************************\n");int n = 0;printf("请选择:");scanf("%d", &n);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_name);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_age);//看看是否排序成功for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}printf("排序成功\n");
}

通讯录源码: 

test.c:

#include "Contact.h"void menu()
{printf("******************************************\n");printf("****  1.增加联系人      2.删除联系人  ****\n");printf("****  3.查找联系人      4.修改联系人  ****\n");printf("****  5.显示联系人     6.排序联系人   ****\n");printf("****           0.退出通讯录           ****\n");printf("******************************************\n");
}void test()
{int input = 0;//下面是对通讯录进行的各种操作,所以我们得先有一个通讯录Contact con;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);}int main()
{test();return 0;
}

Contact.c:

#include "Contact.h"//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);memset(pc->data, 0, sizeof(pc->data));//循环也可以pc->sz = 0;
}//增加联系人信息的函数
void AddContact(Contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满,无法增加\n");//通讯录满了,就无需执行下面的语句了return;//因为是void。所以无需返回任何值}else{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++;printf("成功增加联系人\n");}
}//显示联系人的信息的函数
void ShowContact(const Contact* pc)
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}
}//查找联系人名字的函数
static int FindByName(const Contact* pc, char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//删除联系人信息的函数的声明
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);if (del == -1){printf("要删除的人不存在\n");return;}for (int i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}//删除最后一个元素时,虽然不能在循环中删除,但是pc->sz--了,致使访问不到最后一个元素了//因此,我们在打印时也不会打印出来pc->sz--;printf("删除成功\n");
}//查找指定联系人信息的函数
void SearchContact(const Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要查找的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}void menu1()
{printf("*******************************\n");printf("****  1.姓名     2.年龄    ****\n");printf("****  3.性别     4.电话    ****\n");printf("****        5.住址         ****\n");printf("*******************************\n");
}
//修改指定联系人的信息
void ModifyContact(Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要修改的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的联系人不存在\n");return;}menu1();printf("请选择要修改的选项:");int n = 0;scanf("%d", &n);switch (n){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;}printf("修改成功\n");printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp(((people*)e1)->name, ((people*)e2)->name);
}int cmp_peo_by_age(const void* e1, const void* e2)
{return ((people*)e1)->age - ((people*)e2)->age;
}void SortContact(const Contact* pc)
{printf("请选择想要排的序:\n");printf("********************************\n");printf("*****   1.按照名字排序    ******\n");printf("*****   2.按照年龄排序    ******\n");printf("********************************\n");int n = 0;printf("请选择:");scanf("%d", &n);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_name);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_age);for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}printf("排序成功\n");
}

Contect.h:

//头文件的声明
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>//为后期增加联系人做准备
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30//把选项一 一列举出来
enum OPPION
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};//类型的声明
typedef struct people
{char name[MAX_NAME];//姓名int age;//年龄char sex[MAX_SEX];//性别//电话(我们正常的电话是11位,超过了int的长度,所以用字符串比较合适)char tele[MAX_TELE];char addr[MAX_ADDR];//住址
}people;//通讯录
typedef struct Contact
{people data[MAX];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 SortContact(const Contact* pc);

动态版通讯录 

有关动态内存开辟的知识点:动态内存管理-CSDN博客

上述是静态版的通讯录。

下面我们来实现一下动态版的通讯录。

目标:1. 可以实现储存通讯录人数不限。2. 默认可以放3个人的信息,如果不够,就每次增加2个人的信息(这样方便我们测试,也可以默认别的数,但数据太大,不好测试)。

首先,存放人信息的空间大小是不需要改变的,但是我们用的那个联系人数组要变成一个由malloc函数开辟的空间。其次,我们想要知道这个空间当前用了几个,还剩几个。记录用了几个,就可以用sz来记录,而还剩几个空间,就可以用count来记录一下。

//通讯录
typedef struct Contact
{people* data;//指向通讯录的那块空间int sz;//记录当前的联系人个数int count;//记录总共开辟了多少空间
}Contact;

既然通讯录里的数据变了,那么我们的初始化函数也得变化。

//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);//开辟一块空间给通讯录pc->data = (people*)malloc(3 * sizeof(people));if (pc->data == NULL)//空间开辟失败{perror("InitContact");return;}pc->sz = 0;pc->count = DEFAULT_SZ;//在头文件中定义一个宏,默认数据表示初始数据
}

容量变了,那我们增加联系人的函数也得发生变化。 

static int CheckCount(Contact* pc)//判断是否需要增加空间
{if (pc->sz == pc->count){people *ptr = (people*)realloc(pc->data, (pc->count + INC_SZ) * sizeof(people));if (ptr == NULL){perror("CheckCount");return 0;}pc->data = ptr;pc->count += INC_SZ;printf("增容成功\n");return 1;}return 1;
}//增加联系人信息的函数
void AddContact(Contact* pc)
{assert(pc);if (CheckCount(&pc) == 0)//增加失败就不需要往下走了{return;}else{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++;printf("成功增加联系人\n");}
}

删除,查找,显示,修改,排序这些就不需要更改了。

但我们还得在退出通讯录的时候,把动态开辟的内存给释放掉。 

void DestroyContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->count = 0;pc->sz = 0;
}

test.c:

#include "Contact.h"void menu()
{printf("******************************************\n");printf("****  1.增加联系人      2.删除联系人  ****\n");printf("****  3.查找联系人      4.修改联系人  ****\n");printf("****  5.显示联系人     6.排序联系人   ****\n");printf("****           0.退出通讯录           ****\n");printf("******************************************\n");
}void test()
{int input = 0;//下面是对通讯录进行的各种操作,所以我们得先有一个通讯录Contact con;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:DestroyContact(&con);//销毁通讯录printf("退出通讯录\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);}int main()
{test();return 0;
}

Contact.h:

//头文件的声明
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>//为后期增加联系人做准备
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30#define DEFAULT_SZ 3
#define INC_SZ 2//把选项一 一列举出来
enum OPPION
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};//类型的声明
typedef struct people
{char name[MAX_NAME];//姓名int age;//年龄char sex[MAX_SEX];//性别//电话(我们正常的电话是11位,超过了int的长度,所以用字符串比较合适)char tele[MAX_TELE];char addr[MAX_ADDR];//住址
}people;//通讯录
typedef struct Contact
{people* data;int sz;int count;
}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 SortContact(const Contact* pc);//销毁通讯录的函数
void DestroyContact(Contact* pc);

Contact.c: 

#include "Contact.h"//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);//开辟一块空间给通讯录pc->data = (people*)malloc(3 * sizeof(people));if (pc->data == NULL)//空间开辟失败{perror("InitContact");return;}pc->sz = 0;pc->count = DEFAULT_SZ;
}static int CheckCount(Contact* pc)//判断是否需要增加空间
{if (pc->sz == pc->count){people *ptr = (people*)realloc(pc->data, (pc->count + INC_SZ) * sizeof(people));if (ptr == NULL){perror("CheckCount");return 0;}pc->data = ptr;pc->count += INC_SZ;printf("增容成功\n");return 1;}return 1;
}//增加联系人信息的函数
void AddContact(Contact* pc)
{assert(pc);if (CheckCount(pc) == 0)//增加失败就不需要往下走了{return;}else{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++;printf("成功增加联系人\n");}
}//显示联系人的信息的函数
void ShowContact(const Contact* pc)
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}
}//查找联系人名字的函数
static int FindByName(const Contact* pc, char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//删除联系人信息的函数的声明
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);if (del == -1){printf("要删除的人不存在\n");return;}for (int i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}//删除最后一个元素时,虽然不能在循环中删除,但是pc->sz--了,致使访问不到最后一个元素了//因此,我们在打印时也不会打印出来pc->sz--;printf("删除成功\n");
}//查找指定联系人信息的函数
void SearchContact(const Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要查找的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}void menu1()
{printf("*******************************\n");printf("****  1.姓名     2.年龄    ****\n");printf("****  3.性别     4.电话    ****\n");printf("****        5.住址         ****\n");printf("*******************************\n");
}
//修改指定联系人的信息
void ModifyContact(Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要修改的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的联系人不存在\n");return;}menu1();printf("请选择要修改的选项:");int n = 0;scanf("%d", &n);switch (n){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;}printf("修改成功\n");printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp(((people*)e1)->name, ((people*)e2)->name);
}int cmp_peo_by_age(const void* e1, const void* e2)
{return ((people*)e1)->age - ((people*)e2)->age;
}void SortContact(const Contact* pc)
{printf("请选择想要排的序:\n");printf("********************************\n");printf("*****   1.按照名字排序    ******\n");printf("*****   2.按照年龄排序    ******\n");printf("********************************\n");int n = 0;printf("请选择:");scanf("%d", &n);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_name);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_age);for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}printf("排序成功\n");
}void DestroyContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->count = 0;pc->sz = 0;
}

动态通讯录(文件版)

 有关文件的读写的知识点:C语言之文件操作(万字详解)-CSDN博客

上面是动态版的通讯录,可以实现空间不受限制。但是如果我们想要知道我们上一次是存放什么呢?那就得用文件来保存上一次的信息。我们应该是在销毁前保存。

void SaveContact(Contact* pc)
{//打开文件FILE* pf = fopen("data.txt", "wb");if (pf == NULL){perror("SaveContact");return;}//写数据for (int i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(people), 1, pf);}//关闭文件fclose(pf);pf = NULL;
}

我们保存的信息是为了下一次打开的时候,可以直接查看到这些数据。那么我们在初始化通讯录的时候,就应该把数据放到通讯录里,如果我们要查看的话,就可以选择显示通讯录的信息即可。

void LoadContact(Contact* pc)
{//把文件中的信息加载到通讯录中FILE* pf = fopen("data.txt", "rb");if (pf == NULL){perror("LoadContact");return;}//读文件people tmp = {0};while (fread(&tmp, sizeof(people), 1, pf))//读一个判断一个,当返回为0时,就说明已经读完了{if (CheckCount(pc) == 0)//存放的时候,判断是否需要增加空间{return;}pc->data[pc->sz] = tmp;pc->sz++;}//关闭文件fclose(pf);pf = NULL;
}//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);//开辟一块空间给通讯录pc->data = (people*)malloc(3 * sizeof(people));if (pc->data == NULL)//空间开辟失败{perror("InitContact");return;}pc->sz = 0;pc->count = DEFAULT_SZ;//把文件中的信息加载到通讯录中LoadContact(pc);
}

test.c: 

#include "Contact.h"void menu()
{printf("******************************************\n");printf("****  1.增加联系人      2.删除联系人  ****\n");printf("****  3.查找联系人      4.修改联系人  ****\n");printf("****  5.显示联系人     6.排序联系人   ****\n");printf("****           0.退出通讯录           ****\n");printf("******************************************\n");
}void test()
{int input = 0;//下面是对通讯录进行的各种操作,所以我们得先有一个通讯录Contact con;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:SaveContact(&con);//把信息保存在文件里DestroyContact(&con);//销毁通讯录printf("退出通讯录\n");break;default:printf("选择错误,请重新选择\n");break;}} while (input);}int main()
{test();return 0;
}

Contact.h: 

//头文件的声明
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>//为后期增加联系人做准备
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30#define DEFAULT_SZ 3
#define INC_SZ 2//把选项一 一列举出来
enum OPPION
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};//类型的声明
typedef struct people
{char name[MAX_NAME];//姓名int age;//年龄char sex[MAX_SEX];//性别//电话(我们正常的电话是11位,超过了int的长度,所以用字符串比较合适)char tele[MAX_TELE];char addr[MAX_ADDR];//住址
}people;//通讯录
typedef struct Contact
{people* data;int sz;int count;
}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 SortContact(const Contact* pc);//销毁通讯录的函数
void DestroyContact(Contact* pc);//加载通讯录的函数
void SaveContact(Contact* pc);

Contact.c: 

#include "Contact.h"int CheckCount(Contact* pc);void LoadContact(Contact* pc)
{//把文件中的信息加载到通讯录中FILE* pf = fopen("data.txt", "rb");if (pf == NULL){perror("LoadContact");return;}//读文件people tmp = {0};while (fread(&tmp, sizeof(people), 1, pf)){if (CheckCount(pc) == 0){return;}pc->data[pc->sz] = tmp;pc->sz++;}//关闭文件fclose(pf);pf = NULL;
}//初始化通讯录的函数
void InitContact(Contact* pc)
{assert(pc);//开辟一块空间给通讯录pc->data = (people*)malloc(3 * sizeof(people));if (pc->data == NULL)//空间开辟失败{perror("InitContact");return;}pc->sz = 0;pc->count = DEFAULT_SZ;//把文件中的信息加载到通讯录中LoadContact(pc);
}static int CheckCount(Contact* pc)//判断是否需要增加空间
{if (pc->sz == pc->count){people *ptr = (people*)realloc(pc->data, (pc->count + INC_SZ) * sizeof(people));if (ptr == NULL){perror("CheckCount");return 0;}pc->data = ptr;pc->count += INC_SZ;printf("增容成功\n");return 1;}return 1;
}//增加联系人信息的函数
void AddContact(Contact* pc)
{assert(pc);if (CheckCount(pc) == 0)//增加失败就不需要往下走了{return;}else{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++;printf("成功增加联系人\n");}
}//显示联系人的信息的函数
void ShowContact(const Contact* pc)
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}
}//查找联系人名字的函数
static int FindByName(const Contact* pc, char name[])
{assert(pc);for (int i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//删除联系人信息的函数的声明
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);if (del == -1){printf("要删除的人不存在\n");return;}for (int i = del; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}//删除最后一个元素时,虽然不能在循环中删除,但是pc->sz--了,致使访问不到最后一个元素了//因此,我们在打印时也不会打印出来pc->sz--;printf("删除成功\n");
}//查找指定联系人信息的函数
void SearchContact(const Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要查找的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}void menu1()
{printf("*******************************\n");printf("****  1.姓名     2.年龄    ****\n");printf("****  3.性别     4.电话    ****\n");printf("****        5.住址         ****\n");printf("*******************************\n");
}
//修改指定联系人的信息
void ModifyContact(Contact* pc)
{assert(pc);char name[MAX_NAME];printf("请输入要修改的联系人:");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的联系人不存在\n");return;}menu1();printf("请选择要修改的选项:");int n = 0;scanf("%d", &n);switch (n){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;}printf("修改成功\n");printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\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);
}int cmp_peo_by_name(const void* e1, const void* e2)
{return strcmp(((people*)e1)->name, ((people*)e2)->name);
}int cmp_peo_by_age(const void* e1, const void* e2)
{return ((people*)e1)->age - ((people*)e2)->age;
}void SortContact(const Contact* pc)
{printf("请选择想要排的序:\n");printf("********************************\n");printf("*****   1.按照名字排序    ******\n");printf("*****   2.按照年龄排序    ******\n");printf("********************************\n");int n = 0;printf("请选择:");scanf("%d", &n);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_name);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_peo_by_age);for (int i = 0; i < pc->sz; i++){printf("%-20s\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);}printf("排序成功\n");
}void DestroyContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->count = 0;pc->sz = 0;
}void SaveContact(Contact* pc)
{//打开文件FILE* pf = fopen("data.txt", "wb");if (pf == NULL){perror("SaveContact");return;}//写数据for (int i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(people), 1, pf);}//关闭文件fclose(pf);pf = NULL;
}

好啦!本期的通讯录的实现就到此结束啦!下一期,我们再一起学习吧! 

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

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

相关文章

MySQL数据库实现增删改查基础操作

准备工作 安装mysql8.0 (安装时一定要记住用户名和密码)安装数据库可视化视图工具Navicat 请注意⚠️⚠️⚠️⚠️ a. 编程类所有软件不要安装在中文目录下 b. Navicat破解版下载安装教程&#xff1a;&#xff08;由于文章审核提示版权问题&#xff0c;链接不方便给出&#xff…

Spring Web MVC入门(3)

学习Spring MVC 请求 传递JSON数据 JSON概念 JSON: JavaScript Object Natation JSON是一种轻量的数据交互格式, 采用完全独立于编程语言的文本格式来存储和标识数据. 简单来说, JSON是一种数据格式, 有自己的格式和语法, 使用文本来表示对象或数组的信息, 因此JSON的本质…

C++——类和对象(3)

目录 1. 拷贝构造 1.1 概念 1.2 特性 ​编辑 2. 赋值重载 和 运算符重载 2.1 运算符重载 2.2 赋值重载 此篇文章讲解六个默认成员函数中的 拷贝构造和赋值重载 。 1. 拷贝构造 1.1 概念 拷贝构造&#xff1a; 在创建对象的时候用已经创建好的对象去初始化一个新对象&am…

C# 打开文件对话框(OpenFileDialog)

OpenFileDialog&#xff1a;可以打开指定后缀名的文件&#xff0c;既能单个打开文件也能批量打开文件 /// <summary>/// 批量打开文档/// 引用&#xff1a;System.Window.Fomrs.OpenFileDialog/// </summary>public void OpenFile(){OpenFileDialog dialog new Op…

操作系统(OS)

文章目录 前言一、操作系统是什么&#xff1f;二、用户对资源的访问三、操作系统是怎么做到管理的&#xff1f; 前言 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。冯诺依曼体系结构中的硬件单元提供的功能&#xff0c;这些硬件由操作系统来控制与管…

整数和浮点数在内存中存储及题目

一、整数在内存中存储 整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码。三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤1表⽰“负”&#xff0c;⽽数值位最⾼位的⼀位是被当做符号位&#xff0c;剩余的都是数值位 正整数…

UglifyJS 压缩工具

要使用 UglifyJS 进行 JavaScript 代码的压缩和混淆&#xff0c;你可以按照以下步骤进行&#xff1a; 安装 Node.js&#xff1a; 首先确保你的计算机上安装了 Node.js。如果没有安装&#xff0c;你可以从 Node.js 官方网站 下载并安装。 安装 UglifyJS&#xff1a; 在安装 Nod…

2024腾讯云免费服务器2核8G配置申请流程,亲测有效

腾讯云免费服务器申请入口 https://curl.qcloud.com/FJhqoVDP 免费服务器可选轻量应用服务器和云服务器CVM&#xff0c;轻量配置可选2核2G3M、2核8G7M和4核8G12M&#xff0c;CVM云服务器可选2核2G3M和2核4G3M配置&#xff0c;腾讯云服务器网txyfwq.com分享2024年最新腾讯云免费…

C++for语句(2)

11.乘方计算 给出一个整数a和一个正整数n&#xff08;-1000000<a<1000000,1<n<100000&#xff09;&#xff0c;求乘方&#xff0c;即乘方的结果。最终结果的绝对值不超过1000000。 输入 一行&#xff0c;包含两个整数a和n&#xff08;-1000000<a<1000000,1…

第四十四周:文献阅读 + SG滤波+基于LSTM的编码器-解码器

目录 摘要 Abstract 文献阅读&#xff1a;基于集成深度神经网络的大规模水质预测 现有问题 提出方法 方法论 Savitsky-Golay过滤器 SE-LSTM&#xff08;基于LSTM的编码器-解码器神经网络&#xff09; 研究实验 数据集 实验设置 评估指标 基准模型 实验结果 发展…

搜维尔科技:使用SenseGlove Nova手套操纵其“CAVE”投影室中的虚拟对象

创造了一种基于 PC 的创新型多边沉浸式环境&#xff0c;让参与者完全被虚拟图像和声音包围。 需要解决的挑战&#xff1a; 传统的 VR 系统往往缺乏真实的触摸反馈&#xff0c;限制了用户的沉浸感。AVR Japan 旨在通过将触觉技术融入到他们的 CAVE 系统中来应对这一挑战&#x…

操作系统(AndroidIOS)图像绘图的基本原理

屏幕显示图像的过程 我们知道&#xff0c;屏幕是由一个个物理显示单元组成&#xff0c;每一个单元我们可以称之为一个物理像素点&#xff0c;而每一个像素点可以发出多种颜色。 而图像&#xff0c;就是在不同的物理像素点上显示不同的颜色构成的。 像素点的颜色 像素的颜色是…

HTML静态网页成品作业(HTML+CSS)——游戏战地介绍设计制作(4个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有4个页面。 二、作品演示 三、代…

3.4 bp,si,di寄存器,寻址方式,寄存器总结

汇编语言 1. [bxidata] 我们可以用[bx]来指明一个内存单元我们也可以用[bxidata]来表示一个内存单元&#xff0c;它的偏移地址为bx中的数值加上idata mount c d:masm c: debug r d 2000:1000 e 2000:1000 12 34 56 78 a mov ax,2000 mov ds,ax mov bx,1000 mov ax,[bx] mov c…

C++之deque与vector、list对比分析

一.deque讲解 对于vector和list&#xff0c;前一个是顺序表&#xff0c;后一个是带头双向循环链表&#xff0c;前面我们已经实现过&#xff0c;这里就不再讲解了&#xff0c;直接上deque了。 deque&#xff1a;双端队列 常见接口大家可以查看下面链接&#xff1a; deque - …

Redis - String 字符串

前言 下表中包含本博客提到的所有命令 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 1&#xff09;⾸先 Redis 中所有的键&#xff08;key&#xff09;的类型都是字符串类型&#xff0c;⽽且其他⼏种数据结构也都是在字符串类似基础上…

Figure 01掀起了具身智能的崭新篇章

在人工智能的发展历程中&#xff0c;OpenAI始终扮演着创新的先锋角色。最近&#xff0c;他们与Figure公司的合作成果尤为引人注目&#xff0c;这一合作将多模态大模型技术成功应用于Figure 01机器人的开发中&#xff0c;为人类与机器的互动开辟了全新的时代。该机器人不仅能够与…

Matlab|【免费】基于半不变量的概率潮流计算

目录 主要内容 部分代码 结果一览 下载链接 主要内容 该程序主要内容是基于半不变量法的概率潮流&#xff0c;包含蒙特卡洛模拟法、半不变量法&#xff0b;Gram-Charlier级数展开以及半不变量法Cornish-Fisher级数展开三种方法以及效果对比&#xff0c;模型考虑了…

Python 查找并高亮PDF中的指定文本

在处理大量PDF文档时&#xff0c;有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…

cesium.js加载模型后,重新设置旋转角度属性值

// 加载模型var position Cesium.Cartesian3.fromDegrees(longitude, latitude, height);// 计算矩阵var rollAngleDegrees 15; // 设置翻滚角度var rollAngleRadians Cesium.Math.toRadians(rollAngleDegrees); // 将角度转换为弧度var orientation Cesium.Transforms.eas…