单链表实现通讯录

通讯录

用单链表实现通讯录需要五个文件
但其实三个文件也可以实现
test.c 测试通讯录函数
Contact.h 声明通讯录函数,定义结构体
Contact.c 实现通讯录函数

为了方便,就调用单链表的部分函数来实现通讯录
在这里插入图片描述

通讯录的结构

通讯录的结构体中要有:
姓名,性别,年龄,电话,地址

#pragma once
#define NAME_MAX 100 //姓名不超过100字节
#define SEX_MAX 20  //性别不超过20字节
#define TEL_MAX 11  //电话号码都是11位的
#define ADDR_MAX 100 //地址不超过100字节
//名字,性别,电话,地址都为char类型
//都设置最大存储大小
//前置声明
typedef struct SListNode contact;
//通讯录是基于单链表实现的,所以把链表的名字重命名为contact
//前置声明了这个单链表后续就可以使用了

//用户数据
typedef struct PersonInfo
{
    char name[NAME_MAX];//姓名
    char sex[SEX_MAX];//性别
    int age;//年龄
    char tel[TEL_MAX];//电话
    char addr[ADDR_MAX];//地址
}PeoInfo;
//将通讯录重命名为PeoInfo

初始化通讯录

//初始化通讯录
//为头结点开辟空间
void InitContact(contact** con)
{
	//直接调用单链表的初始化
	SLInit(*con);
	//初始化可以看我的上一篇博客
}

添加通讯录数据

//添加通讯录数据
void AddContact(contact** con)
{
	PeoInfo info;
	//定义一个通讯录结构体变量
	printf("请输入联系人姓名\n");
	scanf("%s", info.name);

	printf("请输入联系人性别\n");
	scanf("%s", info.sex);

	printf("请输入联系人年龄\n");
	scanf("%d", &info.age);

	printf("请输入联系人电话\n");
	scanf("%s", info.tel);

	printf("请输入联系人地址\n");
	scanf("%s", info.addr);

	SLPushBack(con, info);
	//尾插的实现也可以看我之前的博客
	//用尾插把输入的数据插入到通讯录中
    
	printf("插入成功\n");
}

查找联系人信息

//查找联系人信息
contact* FindByName(contact* con, char name[])
{
	contact* pcur = con;
	while (pcur)
	{
		if ((strcmp(pcur->data.name, name)) == 0)
		// pcur->data.name 和 name 一样大就找到联系人的姓         名了
		//strcmp要包含的头文件是 string.h
		{
			return pcur;
			//返回存储联系人数据的节点
		}
		pcur = pcur->next;
		//没有找到节点往下走,知道节点走到NULL,退出循环
	}
	
	return NULL;
	//找不到name,返回空指针
}

删除联系人数据

//删除通讯录数据
void DelContact(contact** con)
// 传二级指针,为了改变指针的指向,改变一级指针的值
{
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名\n");
	scanf("%s", name);
	contact* pos = FindByName(*con, name);
	//查找联系人姓名,找到返回联系人节点指针,找不到返回NULL
	if (pos == NULL)
	{
		//找不到联系人姓名
		printf("要删除联系人姓名不存在\n");
		return;
		//提前返回
	}
	//找到了联系人姓名
	
	SLErase(con, pos);
	//调用删除函数,删除pos节点
	printf("删除成功\n");
}

展示通讯录信息

//展示通讯录数据
void ShowContact(contact* con)
//不改变指针的指向,用一级指针就可以找到节点中的数据
{
	printf("姓名 性别 年龄 电话 地址\n");

	contact* pcur = con;
	while (pcur)
	{
		printf("%s %s %d %s %s\n",
			pcur->data.name,
			pcur->data.sex,
			pcur->data.age,
			pcur->data.tel,
			pcur->data.addr);
          //打印 姓名,性别,年龄,电话,地址
		pcur = pcur->next;
		//直到链表节点指针指向空,就打印完成
	}

}

查找通讯录数据

//查找通讯录数据
void FindContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名\n");
	scanf("%s", name);

	contact* pos = FindByName(con, name);
	//查找联系人姓名,找到返回联系人节点指针,找不到返回NULL
	if (pos == NULL)
	{
		perror("FindByName");
		return;
		//提前返回
	}
	//要查找的联系人信息存在
	printf("联系人数据存在\n");
	//打印出来
	printf("%s %s %d %s %s\n",
		pos->data.name,
		pos->data.sex,
		pos->data.age,
		pos->data.tel,
		pos->data.addr);
}

修改通讯录数据

//修改通讯录数据
void ModifyContact(contact** con)
//用二级指针可以改变指针的指向(指针的值)
{
	char name[NAME_MAX];
	printf("请输入要修改的联系人姓名\n");
	scanf("%s",name);

	contact* pos = FindByName(*con, name);
	//查找联系人姓名,找到返回联系人节点指针,找不到返回NULL
	//找不到联系人信息
	if (pos == NULL)
	{
		perror("FindByName");
		return;
		//提前返回
	}
	//找到了联系人信息
	//修改联系人信息
	//打印表头
	//printf("姓名 性别 年龄 电话 地址\n");

	printf("请输入改变后的联系人的姓名\n");
	scanf("%s", pos->data.name);

	printf("请输入改变后的联系人的性别\n");
	scanf("%s", pos->data.sex);

	printf("请输入改变后的联系人的年龄\n");
	scanf("%d", &(pos->data.age));

	printf("请输入改变后的联系人的电话\n");
	scanf("%s", pos->data.tel);

	printf("请输入改变后的联系人的地址\n");
	scanf("%s", pos->data.addr);
}

销毁通讯录数据

传二级指针是为了改变指针的指向(指针的值),比如 * con = NULL,那么指向头结点的指针的值为NULL,传回主函数中con就是NULL,因为传址调用形参会改变实参的值,二级指针解引用,找到一级指针的内容,把一级指针的内容改变了,一级指针的内容是一个地址,一级指针通过本身被改变的地址内容,一级指针的指向就被改变了

而传一级指针,比如 con = NULL,这个函数结束后,传回主函数时,传值调用形参不会改变实参,所以到主函数里con并没有被置为NULL

//销毁通讯录数据
void DestroyContact(contact** con)
{

	//直接调用SList.c中实现的销毁方法
	SLDestroy(con);
	//可以看我之前写的博客
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值