上一篇:从0开始学c语言-33-动态内存管理_阿秋的阿秋不是阿秋的博客-优快云博客
我发现,理论的学习文章没几个人看,如果是这种实践类型的文章,看的人很多,偏偏我之前都是扔完代码就走了,也没认真写这种类型文章的思考过程,所以这篇打算好好写下。
先放上网盘链接,(我设置的永久有效)
链接:https://pan.baidu.com/s/1Renm5M2NRlXkbb-IX3r5QA?pwd=1f9i
提取码:1f9i
代码中还有个优化没做,是输入年龄那里判断是否整型并重新输入的问题
我在新的文章里写了解决方法,链接给上
学习小发现 - 03 - 如何判断输入的是不是整型数据并重新输入,纠错(异常)scanf与strcmp,_阿秋的阿秋不是阿秋的博客-优快云博客
目录
4·初始化通讯录函数 contact.h - contact.c
通讯录版本介绍
注:跟着写,只看文章会忘记前面写了什么。
功能:
1·存放信息 2·增加信息
3·删除信息 4·修改信息
5·查找信息 6·排序信息
信息:名字 + 年龄 + 性别 + 电话 + 地址
静态版本:存放1000个人的信息
动态版本:增设容量,根据有效信息拓容
文件版本:程序开始读取文件,程序结束把信息写到文件中。
注:功能实现的过程都放在了静态通讯录版本中进行介绍。
静态通讯录
*大概思路
功能:
1·存放信息 2·增加信息
3·删除信息 4·修改信息
5·查找信息 6·排序信息
信息:名字 + 年龄 + 性别 + 电话 + 地址
首先,我看到这个功能就想到了switch分支语句。
其次,又想到了enum枚举类型,把分支的数字和功能名字对应起来。
最后,因为是通讯录,所以通讯录中有以联系人为单位的集合,那么就应该有对应的结构体来保存联系人的信息。
这是最初的大概思路。
*文件
头文件contact.h是用来声明函数和定义一些变量的。
源文件contact.c是用来写函数实现功能的具体过程的。
test.c可以理解为功能的入口。
1·功能入口书写 test.c
想要进入不同的功能区,要先书写相应的菜单。
void menu()
{
printf(" ***** 0.EXIT 1.ADD 2.DEL *****\n");
printf(" ***** 3.SEARCH 4.MODIFY *****\n");
printf(" ***** 5.SORT 6.PRINT *****\n");
}
其次,把这些 菜单名字与数字 用enum类型对应起来。
enum Option
{
EXIT, //0
ADD, //1
DEL, //2
SEARCH,//3
MODIFY,//4
SORT, //5
PRINT //6
};
在主函数中书写switch分支语句实现不同功能的入口。
int main()
{
int input = 0;
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case EXIT: //EXIT就代表数字0
break;
case ADD: //ADD就代表数字1
break;
case DEL: //后面的以此类推,和enum中的数字对应起来
break;
case SEARCH:
break;
case MODIFY:
break;
case SORT:
break;
case PRINT:
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
2·结构体思路 contact.h
因为通讯录和联系人都会跨文件使用,所以写在头文件中更好一些。
联系人结构体
信息:名字 + 年龄 + 性别 + 电话 + 地址
判断每个信息对应的类型,以及是否需要数组来储存就可以写出来了。
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 12
#define MAX_ADDR 30
//定义一个人的结构体信息
struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tel[MAX_TEL];
char addr[MAX_ADDR];
};
后又因为之后会多次使用这个结构体类型,为了书写方便,把struct PeoInfo重命名为PeoInfo。
//定义一个人的结构体信息
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tel[MAX_TEL];
char addr[MAX_ADDR];
}PeoInfo; //把struct PeoInfo定义为PeoInfo
通讯录结构体
首先通讯录结构体中肯定要有联系人结构体,而我们要实现的是存放1000个人的信息,所以把这个联系人结构体设为数组。
其次,为了方便添加信息,删除信息之类的,我们需要一个变量来记录目前有几个有效信息。
同样,我们也进行了重命名,把struct Contact定义为Contact。
#define MAX 1000
//定义通讯录——静态
typedef struct Contact
{
PeoInfo data[MAX]; //存放过来的个人信息集合(数组
int sz; //记录已经有几个信息,相当于data数组的下标
//比如已经有一个人的信息,那么下一个要增加信息对应下标就是1
}Contact;
3·完善主函数内容 test.c
创建与初始化通讯录
之前我们在test.c中写了switch分支语句来实现不同功能的入口,但我们还没有创建一个通讯录结构体变量以及初始化通讯录。
int main()
{
int input = 0;
do {
//创建通讯录
Contact con;
//初始化通讯录
IniContact(&con);
//这里要取地址传参,因为我们要
//通过这个函数改变通讯录
//单纯传数值没办法改编数据
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
//后面先省略
确定分支语句函数
我们知道不同分支的情况对应不同的功能,这个功能我们通过函数实现。所以这里我们先要确定好函数的命名与参数。参数都是通讯录的地址,因为无论是改变通讯录信息还是不改变,传地址都效率高且节省空间。命名方面我可能不是很规范,第二个单词没大写,太懒了哈哈哈。
int main()
{
//创建通讯录
Contact con;
//初始化通讯录
IniContact(&con);
int input = 0;
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case EXIT:
Destroycontact(&con); //销毁信息,动态版本用
break;
case ADD:
Addcontact(&con); //添加信息
break;
case DEL:
Delcontact(&con); //删除信息
break;
case SEARCH:
Searcontact(&con); //删除信息
break;
case MODIFY:
Modifcontact(&con); //修改信息
break;
case SORT:
Sortcontact(&con); //分类信息
break;
case PRINT:
Princontact(&con); //打印信息
//虽然打印不需要改变通讯录内容
//但是传地址节省空间
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
4·初始化通讯录函数 contact.h - contact.c
我们在头文件中进行这个函数的声明,在contact.c中书写这个函数的