当前位置: 首页 > news >正文

C语言—《动态版通讯录》

文章目录

  • 普通版通讯录
  • 动态版通讯录
  • 一、 动态通讯录介绍
    • (1)修改InitPhone函数
    • (2)修改AddPhone函数
    • (3)增加check_cap函数
    • (4)增加DestroyPhone函数
  • 二、动态通讯录实现结果
  • 三、动态通讯录实现源代码
    • (1)phone.h
    • (2)phone.c
    • (3)test.c

普通版通讯录

点击可查看普通版通讯录的实现

动态版通讯录

一、 动态通讯录介绍

当通讯录容量不够的时候,且为了让通讯录更加灵活,在普通版通讯录的基础上需分四步升级为动态版通讯录,除以下函数其他函数不做调整。

(1)修改InitPhone函数

void InitPhone(struct Phone* pc)
{
	assert(pc);
	pc->data = (struct P *)malloc(sizeof(struct P) * De_sz);
	if (pc->data == NULL)
	{
		perror("InitPhone");
		return;
	}
	pc->sz = 0;
	pc ->cap = 3;
}

函数解析:
1、动态通讯录需要用动态内存函数malloc先开辟3个空间,用De_sz宏来表示便于修改。
2、再检查data指针是否为空(此时的data由数组改为指针),如果为空用perror函数来打印InitPhone错误信息,再返回。
3、反之则置sz已经增加的个数初始化为0,cap现有容量置为3。

(2)修改AddPhone函数

void AddPhone(struct Phone* pc)
{
	assert(pc);
	if (check_cap(pc)==0)
	{
		return;
	}
		printf("输入名字:");
		scanf("%s", pc->data[pc->sz].name);
		printf("输入性别:");
		scanf("%s", pc->data[pc->sz].sex);
		printf("输入年龄:");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("输入电话号码:");
		scanf("%s", pc->data[pc->sz].tel);
		printf("输入地址:");
		scanf("%s", pc->data[pc->sz].adress);
		pc->sz++;
		printf("成功添加\n");
	
}

函数解析:
这是修改的主要部分,当现有空间不能满足再增加之后的空间需要动态扩容。
需要用第三步的check_cap函数来判断现有空间情况之后再增加个人信息。
1、如果返回为1说明该空间不足增容成功或者该空间够用,再增加信息。
2、如果范围0,则空间不足,增容失败,直接return。

(3)增加check_cap函数

int check_cap(struct Phone * pc)
{
	if (pc->sz == pc->cap)
	{
		struct P *ptr = (struct P *)realloc(pc->data,sizeof(struct P)*(pc->cap + Add_sz));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->cap += Add_sz;
			printf("增容成功\n");
			return 1;
		}
		else
		{
			perror("AddPhone");
			return 0;
		}
	}
	else
	{
		return 1;
	}
}

函数解析:
1、判断已添加个数sz和容量大小cap,如果相等,则需要增容。
2、用realloc函数在原来的空间基础上再申请Add_sz(为宏表示2)个,指向新的指针ptr。
3、再判断ptr是否为空,如果不为空,把ptr再赋给原来的data,让它指向data。如果为空,增容失败,返回为0。
4、最后如果sz和cap不等,说明不需要增容返回1。

(4)增加DestroyPhone函数

void DestroyPhone(struct Phone*pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->cap = 0;
	pc->sz = 0;
}

函数解析:
用动态函数来开辟空间,用完就要释放开辟的内存。
1、用free释放掉data所指向的空间。再把data职位空。
2、cap和sz置为0。

二、动态通讯录实现结果

在这里插入图片描述

三、动态通讯录实现源代码

(1)phone.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX_name 20
#define MAX_sex 5
#define MAX_tel 13
#define MAX_addr 30
#define De_sz 3
#define Add_sz 2

struct P
{
	char name[MAX_name];
	char sex[MAX_sex];
	int age;
	char tel[MAX_tel];
	char adress[MAX_addr];
};
struct Phone
{
	struct P *data;
	int sz;
	int cap;
};

void InitPhone(struct Phone* pc);

void AddPhone(struct Phone* pc);
void DelPhone(struct Phone* pc);
void SearchPhone(struct Phone* pc);
void ModifyPhone(struct Phone* pc);
void ShowPhone(struct Phone* pc);
void SortPhone(struct Phone* pc);

int Find_name(struct Phone* pc, char name[]);
int cmp_name(const void* e1, const void* e2);
int check_cap(struct Phone * pc);
void DestroyPhone(struct Phone*pc);

(2)phone.c

#include"phone.h"
void InitPhone(struct Phone* pc)
{
	assert(pc);
	pc->data = (struct P *)malloc(sizeof(struct P) * De_sz);
	if (pc->data == NULL)
	{
		perror("InitPhone");
		return;
	}
	pc->sz = 0;
	pc ->cap = 3;
}
int check_cap(struct Phone * pc)
{
	if (pc->sz == pc->cap)
	{
		struct P *ptr = (struct P *)realloc(pc->data,sizeof(struct P)*(pc->cap + Add_sz));
		if (ptr != NULL)
		{
			pc->data = ptr;
			pc->cap += Add_sz;
			printf("增容成功\n");
			return 1;
		}
		else
		{
			perror("AddPhone");
			return 0;
		}
	}
	else
	{
		return 1;
	}
}
void AddPhone(struct Phone* pc)
{
	assert(pc);
	if (check_cap(pc)==0)
	{
		return;
	}
		printf("输入名字:");
		scanf("%s", pc->data[pc->sz].name);
		printf("输入性别:");
		scanf("%s", pc->data[pc->sz].sex);
		printf("输入年龄:");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("输入电话号码:");
		scanf("%s", pc->data[pc->sz].tel);
		printf("输入地址:");
		scanf("%s", pc->data[pc->sz].adress);
		pc->sz++;
		printf("成功添加\n");
	
}
void ShowPhone(struct Phone* pc)
{
	printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名","性别","年龄","电话号码","地址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[i].name, pc->data[i].sex,
			pc->data[i].age, pc->data[i].tel, pc->data[i].adress);
	}
}
int Find_name(struct Phone* pc, char name[])
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void  DelPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入删除的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("删除的人不存在");
	}
	else
	{
		for (int j = ret; j < pc->sz; j++)
		{
			pc->data[j] = pc->data[j + 1];
		}
		pc->sz--;
		printf("已删除改联系人\n");
	}
}
void ModifyPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入修改的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("修改的人不存在");
	}
	else
	{
		printf("输入名字:");
		scanf("%s", pc->data[ret].name);
		printf("输入性别:");
		scanf("%s", pc->data[ret].sex);
		printf("输入年龄:");
		scanf("%d", &(pc->data[ret].age));
		printf("输入电话号码:");
		scanf("%s", pc->data[ret].tel);
		printf("输入地址:");
		scanf("%s", pc->data[ret].adress);
		printf("已修改改联系人\n");
	}
}
int cmp_name(const void* e1,const void* e2)
{
	return strcmp(((struct P*)e1)->name ,((struct P*)e2)->name);
}
void SortPhone(struct Phone* pc)
{
	qsort(pc->data,pc->sz,sizeof(struct P),cmp_name);
}
void SearchPhone(struct Phone* pc)
{
	char name[MAX_name];
	printf("输入搜索的名字:");
	scanf("%s", name);
	int ret = Find_name(pc, name);
	if (ret == -1)
	{
		printf("搜索的人不存在");
	}
	else
	{
		printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");
		printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,
			pc->data[ret].age, pc->data[ret].tel, pc->data[ret].adress);
	}
}
void DestroyPhone(struct Phone*pc)
{
	free(pc->data);
	pc->data = NULL;
	pc->cap = 0;
	pc->sz = 0;
}

(3)test.c

#include"phone.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");
}
int main()
{
	int input = 0;
	struct Phone con;
	InitPhone(&con);
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddPhone(&con);
			break;
		case 2:
			DelPhone(&con);
			break;
		case 3:
			SearchPhone(&con);
			break;
		case 4:
			ModifyPhone(&con);
			break;
		case 5:
			ShowPhone(&con);
			break;
		case 6:
			SortPhone(&con);
			break;
		case 0:
			DestroyPhone(&con);
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
	return 0;
}

相关文章:

  • JSP+Servlet + Tomcat实现用户登录(五)使用listener实现在线(游客)人数统计【JavaWeb、无数据库】
  • 【SpringBoot】抽取公共页面方法
  • 应急响应(个人总结,非专业
  • memcpy内存比较函数;memset内存设置函数
  • 【0基础学习mysql】之DQL-聚合函数、分组查询及排序查询
  • 【Redis】回顾下Redis基础知识点,还记得哪些?
  • redis五种数据类型内部构造
  • 基于Vue+Element UI+SSM+SpringCloud的员工管理系统
  • LeetCode刷题---二分查找巩固
  • 简单概述理解vue的MVVM模型
  • 24、Java——银行存款取款系统(对象+集合)
  • Python 集合
  • 【DS】5.二叉树大总结!
  • 攻防世界 web2
  • 机器人运动学标定:基于公垂线模型的指数积标定——减少标定参数,避免过度约束
  • 【译】理解JavaScript:new 关键字
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • 2017届校招提前批面试回顾
  • ES10 特性的完整指南
  • Hexo+码云+git快速搭建免费的静态Blog
  • HTML5新特性总结
  • markdown编辑器简评
  • REST架构的思考
  • 百度地图API标注+时间轴组件
  • 汉诺塔算法
  • 讲清楚之javascript作用域
  • 双管齐下,VMware的容器新战略
  • 为什么要用IPython/Jupyter?
  • 物联网链路协议
  • 一天一个设计模式之JS实现——适配器模式
  • 优秀架构师必须掌握的架构思维
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​学习一下,什么是预包装食品?​
  • #微信小程序:微信小程序常见的配置传旨
  • (WSI分类)WSI分类文献小综述 2024
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (三分钟)速览传统边缘检测算子
  • (转)jQuery 基础
  • ******之网络***——物理***
  • .net MVC中使用angularJs刷新页面数据列表
  • .NET 表达式计算:Expression Evaluator
  • .NET 中的轻量级线程安全
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net中的Queue和Stack
  • .project文件
  • 。Net下Windows服务程序开发疑惑
  • ::前边啥也没有
  • @RequestMapping处理请求异常
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [2010-8-30]
  • [20190416]完善shared latch测试脚本2.txt
  • [AR Foundation] 人脸检测的流程