玉环建设规划局网站,湘潭网页定制,wordpress防御插件,网站优化排名提升数据结构的顺序表和链表是一个比较困难的点#xff0c;初见会让我们觉得有点困难#xff0c;正巧C语言中有一个类似于顺序表和链表的小程序——通讯录。我们今天就来讲一讲通讯录的实现#xff0c;也有利于之后顺序表和链表的学习。
目录
0.通讯录的初始化
1.菜单的创建…数据结构的顺序表和链表是一个比较困难的点初见会让我们觉得有点困难正巧C语言中有一个类似于顺序表和链表的小程序——通讯录。我们今天就来讲一讲通讯录的实现也有利于之后顺序表和链表的学习。
目录
0.通讯录的初始化
1.菜单的创建
2.主函数的创建
3.定义联系人内容结构体
4.定义通讯录内容结构体
5.避免代码冗余而定义的查找函数
6.删除联系人信息
7.修改通讯录信息
8.显示某一个人的信息
9.整个通讯录的打印
10.将通讯录按名字排序
11.全部代码 我们需要用C语言模拟一个通讯录可以用来存储100个人的信息 每个人的信息包括 姓名、电话、性别、住址、年龄 功能包括 新增联系人查找联系人删除联系人修改联系人查看所有联系人以名字排序所有联系人 0.通讯录的初始化
尽管我们这是一个基础的通讯录它并不具备保存功能但是我们应该让它拥有一个初始化功能。
void InitContact(Contact* pc)
{pc-sz 0;memset(pc-data, 0, sizeof(pc-data));
}
1.菜单的创建
首先要有一个一目了然的菜单。
要实现这么多的功能我们首先想到了switch语句用case表示不同的情况。
不过考虑到case 1case 2这样的写法不容易读懂代码的可维护性也不高。
我们在这里定义一个枚举类型。
enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
}; 如图所示枚举类型在我们没有额外操作的情况下里面的元素是从零开始。
这样一来我们就可以从case 1这样的写法变成 case ADD一目了然一看就能看懂。
我们也需要打印选项另外定义一个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.主函数的创建
当要实现某一个函数功能时我们直接在case语句后调用此函数便可。
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 EXIT:printf(退出);break;default:break;}} while (input);return 0;
}
缺少的东西我们待会再补上。
3.定义联系人内容结构体
一个人的信息包括很多方面要录入的话还是用结构体比较方便。
我们定义姓名年龄性别电话和地址五个变量并将其重命名为PeoInfo。
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;
4.定义通讯录内容结构体
typedef struct Contact
{PeoInfo data[MAX];int sz;
}Contact; 我们要在什么位置插入一个元素呢
我们知道下标是从0开始的。
当我们插入一个数据时我们实际上是插入在我们所定义的sz的位置。
举个例子。
当sz为5时我们已经插入了下标为0,1,2,3,4的五个元素。
这时如果要插入新元素的话就是在下标为5的地方插入也就是插入到sz的位置。
但是我们并没有在sz的位置分配空间所以我们在输入之后需要将sz加一来分配空间。
void AddContact(Contact* pc)
{if (pc-sz 100){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;printf(添加成功\n);
}
需要注意的是当空间已满时要返回这时就不要往里面硬加了。
5.避免代码冗余而定义的查找函数
在接下来的修改或者删除函数里面我们将会需要查找所要删除或者修改的人的名字这样的一个功能为了避免冗余我们不是在用到时再写一遍而是定义一个函数在用到它的时候直接调用这就方便了许多。
int FindByName(Contact* pc, char name[])
{int i 0;for (i 0; i pc-sz; i){if (strcmp(pc-data[i].name, name) 0){return i;break;}}return -1;
}
当查找到要查找到名字时返回这个位置的下标没有找到则返回-1。
6.删除联系人信息
要删除一个人的信息首先需要输入这个人的名字并查找它的位置这时上面的代码就派上用场了。
我们先调用函数找到这个人的信息然后调用它的返回值也就是目标联系人的下标并用这个下标来修改。
修改的方式是经典的后一个覆盖前一个不过由于下标是元素个数再减一为了避免溢出我们需要是将sz减一。
void DelContact(Contact* pc)
{char name[MAX_NAME];if (pc-sz 0){printf(通讯录已满\n);return;}printf(输入要删除的人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1){printf(要删除的人不存在\n);return;}for (int i pos; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n);}
同样的在通讯录元素已满时返回。
7.修改通讯录信息
首先查找当查找到时我们只需利用它的下标来将此位置的信息进行重新录入即可。
void ModifyContact(Contact* pc)
{printf(输入要修改的人的名字:);char name[12] { 0 };scanf(%s, name);int pos FindByName(pc, name);if (pos -1){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].tele);printf(请输入地址:);scanf(%s, pc-data[pos].addr);printf(修改成功\n);
}
8.显示某一个人的信息
我们调用上面的查找函数 找到就用返回值下标打印出来就行。
int SearchContact(Contact* pc)
{char name[12] { 0 };printf(请输入要查找的人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1){printf(此人信息不存在\n);} printf(此人信息如下:\n);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);return pos;
}
9.整个通讯录的打印
我们调用sz来将每一个人的信息打印出来。
void ShowContact(Contact* pc)
{int i 0;printf(%-10s %-4s %-5s %-12s %-30s\n, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){printf(%-10s %-4d %-5s %-12s %-30s\n, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);}
}
10.将通讯录按名字排序
qsort函数可以很好的实现这个问题。 1.首元素地址base我们要排序一组数据首先我们需要找到这组数据在哪因此我们直接将首元素的地址传给qsort函数来确定从哪开始排序。 2.元素个数num我们知道了从哪开始也要知道在哪结束才能确定一组需要排序的数据但是我们不方便直接将结尾元素的地址传入函数因此我们将需要排序的元素的个数传给qsort函数来确定一组数据。 3.元素大小size我们知道qsort函数能排序任意数据类型的一组数据因此我们用void*类型的指针来接收元素但是我们知道void*类型的指针不能进行加减操作也就无法移动那么在函数内部我们究竟用什么类型的指针来操作变量呢我们可以将void*类型的指针强制类型转换成char*类型的指针后来操作元素因为char*类型的指针移动的单位字节长度是1个字节我们只需要再知道我们需要操作的数据是几个字节就可以操作指针从一个元素移动到下一个元素因此我们需要将元素大小传入qsort函数。 4.自定义比较函数compare 我们需要告诉qsort函数我们希望数据按照怎么的方式进行比较比如对于几个字符串我们可以比较字符串的大小。代码如下我们想要传入什么类型的参数就要将其强制类型转换成什么类型并且返回一个int值。 int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name);
}
然后就是qsort函数的调用了
void SortContact(Contact* pc)
{qsort(pc-data, pc-sz, sizeof(PeoInfo), cmp_by_name);
}11.全部代码
下面是全部的代码定义两个源文件和一个头文件。
//contact.h部分
#pragma once
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30
#includestdio.h
#includestring.h
#includestdlib.h
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];int sz;
}Contact;
void InitContact(Contact* pc);
void AddContact(Contact* pc);
void DelContact(Contact* pc);
void SortContact(Contact* pc);
int SearchContact(Contact* pc);
void ModifyContact(Contact* pc);
void ShowContact(Contact* pc);
int FindByName(Contact* pc, char name[]);
//contact.c
#includecontact.h
void InitContact(Contact* pc)
{pc-sz 0;memset(pc-data, 0, sizeof(pc-data));
}
void AddContact(Contact* pc)
{if (pc-sz 100){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;printf(添加成功\n);
}
void DelContact(Contact* pc)
{char name[MAX_NAME];if (pc-sz 0){printf(通讯录已满\n);return;}printf(输入要删除的人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1){printf(要删除的人不存在\n);return;}for (int i pos; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}pc-sz--;printf(删除成功\n);}
int FindByName(Contact* pc, char name[])
{int i 0;for (i 0; i pc-sz; i){if (strcmp(pc-data[i].name, name) 0){return i;break;}}return -1;
}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)-name, ((PeoInfo*)e2)-name);
}
int SearchContact(Contact* pc)
{char name[12] { 0 };printf(请输入要查找的人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1){printf(此人信息不存在\n);} printf(此人信息如下:\n);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);return pos;
}
void ShowContact(Contact* pc)
{int i 0;printf(%-10s %-4s %-5s %-12s %-30s\n, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i pc-sz; i){printf(%-10s %-4d %-5s %-12s %-30s\n, pc-data[i].name, pc-data[i].age, pc-data[i].sex, pc-data[i].tele, pc-data[i].addr);}
}
void ModifyContact(Contact* pc)
{printf(输入要修改的人的名字:);char name[12] { 0 };scanf(%s, name);int pos FindByName(pc, name);if (pos -1){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].tele);printf(请输入地址:);scanf(%s, pc-data[pos].addr);printf(修改成功\n);
}
void SortContact(Contact* pc)
{qsort(pc-data, pc-sz, sizeof(PeoInfo), cmp_by_name);
}
//test.c
#includecontact.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);
}
enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{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(退出);break;default:printf(输入错误\n);break;}} while (input);return 0;
}这篇博客旨在总结我自己阶段性的学习要是能帮助到大家那可真是三生有幸如果觉得我写的不错的话还请点个赞和关注哦~我会持续输出编程的知识的