目录
本次通讯录采用 结构体数组 存储 联系人 数据. 结构体数组 的每个成员保存着联系人的具体信息特征. 用一个参数 sz 记录当前联系人个数.

1.添加联系人 2.删除联系人 3.修改联系人 4.查询联系人 5.展示通讯录

//宏定义,为了修改时更加方便
#define NAME_MAX 10 //名字的最大长度
#define SEX_MAX 5 //性别的最大长度
#define ADDR_MAX 20 //地址的最大长度
#define N 200 //定义最大存储联系人个数
//创建描述的人结构体类型
typedef struct people
{
char name[NAME_MAX]; //姓名
int age; //年龄
char sex[SEX_MAX]; //性别
float stature; //身高
char addr[ADDR_MAX]; //地址
}peo;
//创建通讯录类型
typedef struct Contact
{
peo data[N];//结构体数组,数组每个成员都是结构体,其中保存着联系人的信息
int sz;//用于记录当前练习人的个数
}Contact;通讯录 的大体框架已经建好,但是那只是通讯录的类型,我们应当利用类型创建变量并进行合理的初始化操作. 定义 通讯录 变量:
Contact cont;//创建通讯录cont对 通讯录 进行合理的 初始化 操作.
InitContact(Contact* cont)//初始化通讯录函数
{
assert(cont);//防止传入空指针
cont->sz = 0;//初始时.通讯录为空,即0个联系人
memset(cont->data, 0, sizeof(cont->data));//将结构体数组所占内存区域全部初始化为0.
}由于这一版本的 通讯录 采用的数组存储信息,数组的大小是 有限的 ,所以在进行添加联系人之前,我们应当考虑此时通讯录是否已经满了,当通讯录已经满了的时候,返回添加失败的错误信息. 否则正常插入,在数组下标sz位置添加联系人信息,最后sz++,表示联系人的个数增加1.
void add(Contact* cont)//添加联系人函数
{
assert(cont);//防止传入空指针
if (cont->sz == N)//如果已有200联系人,则不能添加
{
printf("添加失败,通讯录已满");
return;
}
printf("请输入要添加联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[cont->sz].name);
printf("请输入年龄:");
scanf("%d", &cont->data[cont->sz].age);
printf("请输入的性别:");
scanf("%s", cont->data[cont->sz].sex);
printf("请输入身高:");
scanf("%f", &cont->data[cont->sz].stature);
printf("请输入地址:");
scanf("%s", cont->data[cont->sz].addr);
cont->sz++;//人数加一
printf("添加成功\n");
}为什么先介绍"查询指定联系人函数"呢? 我们知道,后面我们需要实现下列功能
删除联系人 修改联系人
这些功能都需要先找到目标联系人,所以我们先实现这个函数,后续需要在删除联系人和修改联系人时,可以直接调用该函数即可,
为了更好让该函数可以被其他函数复用,我们设计规则是:
该函数如果查找到了指定联系人,则返回该联系人在数组中的下标位置. 如果该联系不存在,则返回一个负数(因为数组的下标不可能是负数).
int FindName(const Contact* cont,const char* name)//查找人函数
{
assert(cont && name);//防止传入空指针
int i = 0;
for (i = 0; i < cont->sz; i++)
{
//注意,字符串的比较不能使用"==",而要借助strcmp函数
if (!strcmp(cont->data[i].name, name))//查找通讯录是否有这个名字
{
return i;//有就返回下标
}
}
return -1;//查找失败,返回一个负数.
}当然,有时候实际我们需要的查询联系人函数实现的功能不是返回下标,而是,如果存在该联系人,则打印该联系人的信息,没有则打印相应的提示信息.
void sel(const Contact* cont)//查询联系人函数
{
char name[NAME_MAX];
printf("请输入要查询的联系人的名字:\n");
scanf("%s", name);
int ret = FindName(cont, name);//利用查询人函数查找指定联系人的下标
if (ret == -1)//如果返回-1,则查找失败
{
printf("通讯录中没有该联系人,查询失败.\n");
return;
}
printf("查询成功,该联系信息如下:\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[ret].name, cont->data[ret].age, cont->data[ret].sex, cont->data[ret].stature, cont->data[ret].addr);
printf(" +---------------------------------------------------------------+\n");
}删除联系人操作:
1.需要知道该联系所在下标. 2.将该元素后的所有元素向前"移动"(说是移动,其实就是向前覆盖)一步. 3.size–,这样后面的元素其实并没有删除,而是访问不到了.

void del(Contact* cont)//删除联系人函数
{
assert(cont);//防止传入空指针
int i = 0;
char name[NAME_MAX];
printf("请输入需要删除的联系人的姓名:\n");
scanf("%s", name);
i=FindName(cont, name);
if (i == -1)
{
printf("通讯录中没有该联系人,删除失败\n");
return;
}
for (; i < cont->sz-1; i++)//注意这里sz要-1,因为下面用到了i+1下标
{
cont->data[i] = cont->data[i + 1];
}
cont->sz--;
printf("删除成功,姓名为%s的联系人已删除\n", name);
}其实讲到这里,修改指定联系人应该是一个很简单的操作.
1.我们先利用查找人函数,将下标找到. 2.获取要修改后联系人的信息. 3.将该下标位置的联系人信息覆盖为为新的信息.
void mod(Contact* cont)//修改联系人函数
{
assert(cont);//防止传入空指针
int ret = 0;
char name[NAME_MAX];
printf("请输入要修改的联系人的姓名:\n");
scanf("%s", name);
ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,修改失败\n");
return;
}
printf("请输入修改后联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[ret].name);
printf("请输入年龄:");
scanf("%d", &cont->data[ret].age);
printf("请输入的性别:");
scanf("%s", cont->data[ret].sex);
printf("请输入身高:");
scanf("%f", &cont->data[ret].stature);
printf("请输入地址:");
scanf("%s", cont->data[ret].addr);
printf("修改成功.\n");
}此版本的通讯录还有很多方面有待提高. 例如:
1.我们能否动态增长该通讯录的存储容量? 2.能否增加排序等新的功能? 3.能否保存以前的通讯录信息,当我们下次打开通讯录后,通讯录还保存以前的信息. …… 这些优化,会涉及到文件等后需要学习的知识,下回牛牛在细细分解.今天就到这里啦!!
#include "声明区.h"
void menu()
{
printf("\n 欢迎使用通讯录:\n");
printf(" +-------------------------------------------------------------+\n");
printf(" | 0.退出通讯录. |\n");
printf(" | 1.添加联系人 2.删除联系人 |\n");
printf(" | 3.修改联系人 4.查询联系人 |\n");
printf(" | 5.展示通讯录 |\n");
printf(" +-------------------------------------------------------------+\n");
printf("请选择:");
}
int main()
{
int input = 0;
Contact cont;//创建通讯录cont
InitContact(&cont);
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 0:
printf("退出通讯录");
break;
case 1:
add(&cont);//添加联系人
break;
case 2:
del(&cont);//删除联系人
break;
case 3:
mod(&cont);//修改联系人
break;
case 4:
sel(&cont);//查询联系人
break;
case 5:
show(&cont);//展示通讯录
break;
default:
printf("输入错误");
break;
}
} while (input);
return 0;
}#include "声明区.h"
InitContact(Contact* cont)//初始化通讯录函数
{
assert(cont);//防止传入空指针
cont->sz = 0;
memset(cont->data, 0, sizeof(cont->data));
}
void add(Contact* cont)//添加联系人函数
{
assert(cont);//防止传入空指针
if (cont->sz == N)//如果已有200联系人,则不能添加
{
printf("添加失败,通讯录已满");
return;
}
printf("请输入要添加联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[cont->sz].name);
printf("请输入年龄:");
scanf("%d", &cont->data[cont->sz].age);
printf("请输入的性别:");
scanf("%s", cont->data[cont->sz].sex);
printf("请输入身高:");
scanf("%f", &cont->data[cont->sz].stature);
printf("请输入地址:");
scanf("%s", cont->data[cont->sz].addr);
cont->sz++;//人数加一
printf("添加成功\n");
}
void show(const Contact* cont)//展示通讯录函数
{
assert(cont);//防止传入空指针
int i = 0;
printf(" 通讯录\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |姓名 年龄 性别 身高 地址 |\n");
for (i = 0; i < cont->sz; i++)
{
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[i].name, cont->data[i].age, cont->data[i].sex, cont->data[i].stature, cont->data[i].addr);
}
printf(" +---------------------------------------------------------------+\n");
}
int FindName(const Contact* cont,const char* name)//查找人函数
{
assert(cont && name);//防止传入空指针
int i = 0;
for (i = 0; i < cont->sz; i++)
{
if (!strcmp(cont->data[i].name, name))//查找通讯录是否有这个名字
{
return i;//有就返回下标
}
}
return -1;//没有返回一个负数.
}
void del(Contact* cont)//删除联系人函数
{
assert(cont);//防止传入空指针
int i = 0;
char name[NAME_MAX];
printf("请输入需要删除的联系人的姓名:\n");
scanf("%s", name);
i=FindName(cont, name);
if (i == -1)
{
printf("通讯录中没有该联系人,删除失败\n");
return;
}
for (; i < cont->sz-1; i++)//注意这里sz要-1,因为下面用到了i+1下标
{
cont->data[i] = cont->data[i + 1];
}
cont->sz--;
printf("删除成功,姓名为%s的联系人已删除\n", name);
}
void mod(Contact* cont)//修改联系人函数
{
assert(cont);//防止传入空指针
int ret = 0;
char name[NAME_MAX];
printf("请输入要修改的联系人的姓名:\n");
scanf("%s", name);
ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,修改失败\n");
return;
}
printf("请输入修改后联系人的信息:\n");
printf("请输入姓名:");
scanf("%s", cont->data[ret].name);
printf("请输入年龄:");
scanf("%d", &cont->data[ret].age);
printf("请输入的性别:");
scanf("%s", cont->data[ret].sex);
printf("请输入身高:");
scanf("%f", &cont->data[ret].stature);
printf("请输入地址:");
scanf("%s", cont->data[ret].addr);
printf("修改成功.\n");
}
void sel(const Contact* cont)//查询联系人函数
{
char name[NAME_MAX];
printf("请输入要查询的联系人的名字:\n");
scanf("%s", name);
int ret = FindName(cont, name);
if (ret == -1)
{
printf("通讯录中没有该联系人,查询失败.\n");
return;
}
printf("查询成功,该联系信息如下:\n");
printf(" +---------------------------------------------------------------+\n");
printf(" |%-10s %-5d %-5s %-7f %-15s |\n", cont->data[ret].name, cont->data[ret].age, cont->data[ret].sex, cont->data[ret].stature, cont->data[ret].addr);
printf(" +---------------------------------------------------------------+\n");
}#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define NAME_MAX 10
#define SEX_MAX 5
#define ADDR_MAX 20
#define N 200//定义最大存储联系人个数
//创建描述的人结构体类型
typedef struct people
{
char name[NAME_MAX]; //姓名
int age; //年龄
char sex[SEX_MAX]; //性别
float stature; //身高
char addr[ADDR_MAX]; //地址
}peo;
//创建通讯录类型
typedef struct Contact
{
peo data[N];
int sz;
}Contact;
InitContact(Contact *cont);//初始化通讯录
void add(Contact *cont);//声明添加联系人函数
void show(const Contact* cont);//展示通讯录函数
int FindName(const Contact* cont,const char* name);//找人函数
void del(Contact* cont);//删除联系人函数
void mod(Contact* cont);//修改联系人函数
void sel(const Contact* cont);//查询联系人函数