前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C语言】通讯录《动态内存版本》

【C语言】通讯录《动态内存版本》

作者头像
謓泽
发布2022-12-12 15:23:45
5170
发布2022-12-12 15:23:45
举报
文章被收录于专栏:【C】系列

🚩write in front🚩    🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTOP创作者~周榜109﹣总榜883⇿全网访问量35w+🏅 🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠ 📝个人主页-謓泽的博客_CSDN博客 📃 🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏-YY_謓泽的博客-CSDN博客🎓 ✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

​​

目录

🚩write in front🚩   

前言

动态内存版本 

代码改动 

模块化代码实现

address_book.c

address_book.h

test.c

最后

前言

这篇博客带大家实现通讯录的一个动态内存增长的一个版本,在上一片博客当中我们介绍了通讯录静态版本的一个实现,如果对静态版本感兴趣的话可以看看ヾ(^▽^*)))

✨链接→【C语言】通讯录《静态内存版本》_謓泽的博客-CSDN博客

动态内存版本 

①:通讯录初始化后,能够存放三个人的信息。当然实际上这里多少都是可以的,只不过这个比较好测试。

②:当我们空间的存放存放满的时候,再次增加两个人的信息。

当然如果你不熟悉什么是动态内存的话,可以看看博主写的这篇博客ヾ(^▽^*)))

✨链接→【C语言】动态内存开辟的使用『malloc』

代码改动 

根据上篇的静态通讯录进行了一点改动,改动如下所示👇

通讯录 ✨ 静态版本 →(改编成) 通讯录 ✨ 动态版本

还改变了点宏定义把原先1000人存放进来的信息删除了,增加了"容器"以及增量。

InitContact()增加人的信息,放在通讯录当中去从静态版本 ✨ →(改编成) ✨ 动态版本。

Destory_Contact()增加了一个销毁通讯录。

说明⇢在这里给大家看看程序增容后的运行界面。在这里我们的"容器值"最大为三每次增量加2的。 

​​

这里是当我们输入第三次添加之后就会出现增加联系人成功(@^0^),表明我们已经动态内存开辟增容成功。

​​

此时,再输入就会显示增加联系人成功,因为我们每次增量加2的。内存空间已满又要向堆区申请内存空间。

模块化代码实现

​​

address_book.c

示例代码如下↓ 

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include"address_book.h"
 
//动态版本
void InitContact(Contact* pc)
{
	pc->date = (information*)malloc(Defsz * sizeof(information));
	//如果返回的为空指针的情况
	if (pc->date == NULL)
	{
		perror("InitContact:");
		return;
	}
	pc->sz = 0;//sz初始化
	pc->capacity = Defsz;//当前最大"容量"
}
 
//动态版本增加
void Add_Contact(Contact* pc)
{
	//当记录当前通讯录有效信息的个数 等于 表示当前通讯录的最大"容量"大小。
	if (pc->sz == pc->capacity)
	{
		//给堆区增加"容量",因为空间不够。
		information* pa = (information*)realloc(pc->date, (pc->capacity + Inc)*(sizeof(information)));
		if (pa != NULL)
		{
			pc->date = pa;//把这块空间移交到date进行维护
			pc->capacity = pc->capacity + Inc;//由于这里我们进行了增容也需要把容量改变成+Inc的值
			color(12);
			printf("增加联系人已成功(@^0^)\n");
		}
		//增容失败
		else
		{
			perror("Add_Contact:");
			printf("增加联系人失败!(ToT)/~~~\n");
			return;
		}
	}
	//增加一个人的信息
	printf("\n");
	printf("请输入增加人的名字->:");
	scanf("%s", pc->date[pc->sz].name);//注意→数组名是首元素地址,所以不用进行取地址.
 
	printf("请输入增加人的年龄->:");
	scanf("%s", pc->date[pc->sz].age);
 
	printf("请输入增加人的性别->:");
	scanf("%s", pc->date[pc->sz].genger);
 
	printf("请输入增加人的电话->:");
	scanf("%s", pc->date[pc->sz].telephone);
 
	printf("请输入增加人的地址->:");
	scanf("%s", pc->date[pc->sz].address);
	//成功~
	pc->sz++;
	printf("★恭喜你~添加信息成功★\n");
	printf("\n");
}
void Print_Contact(const Contact* pc)
{
	int i = 0;
	//打印标题栏的信息
	printf("|-------------------------------------------------------|\n");
	printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");
 
	for (i = 0; i < pc->sz; i++)
	{
		printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,
			pc->date[i].age,
			pc->date[i].genger,
			pc->date[i].telephone,
			pc->date[i].address);
	}
}
 
static int FindByname(Contact* pc, char name[])
{
	int i = 0;
	//用for循环进行遍历
	for (i = 0; i < pc->sz; i++)
	{
		//strcmp()比较字符串
		if (strcmp(pc->date[i].name, name) == 0)
		{
			return i;//返回下标
		}
	}
	return -1;
}
 
void DeLete_Contact(Contact* pc)
{
	char name[Max_name] = { 0 };
	//通讯录为空的时候
	if (pc->sz == 0)
	{
		printf("通讯录当中没有任何信息\n");
		return;
	}
	printf("请输入你要删除的名字->:");
	scanf("%s", name);
	//查找要删除的人:有/没有
	int ret = FindByname(pc, name);
	if (ret == -1)
	{
		printf("没有查找到当前人的信息\n");
		return;
	}
	//删除
	int i = 0;
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->date[i] = pc->date[i + 1];
	}
	pc->sz--;//因为我们删除成功下标要减1
	printf("★恭喜你~删除信息成功★\n");
	printf("\n");
}
 
void Find_Contact(Contact* pc)
{
	char name[Max_name] = { 0 };
	printf("请输入你要查找的名字->:");
	scanf("%s", name);
	int ret = FindByname(pc, name);
	if (ret == -1)
	{
		printf("没有查找到当前人的名字\n");
		return;
	}
	else
	{
		printf("|-------------------------------------------------------|\n");
		printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");
 
		printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", 
			pc->date[ret].name,
			pc->date[ret].age,
			pc->date[ret].genger,
			pc->date[ret].telephone,
			pc->date[ret].address);
		printf("查找%sの信息成功~\n", pc->date[ret].name);
	}
}
 
void Revise_Contact(Contact* pc)
{
	char name[Max_name] = { 0 };
	printf("请输入你要修改通讯录人的名字->:");
	scanf("%s", name);
	int ret = FindByname(pc, name);
	if (ret == -1)
	{
		printf("当前修改人的信息不存在\n");
		return;
	}
	else
	{
		printf("请输入修改人的名字->:");
		scanf("%s", pc->date[ret].name);//注意→数组名是首元素地址,所以不用进行取地址.
 
		printf("请输入修改人的年龄->:");
		scanf("%s", pc->date[ret].age);
 
		printf("请输入修改人的性别->:");
		scanf("%s", pc->date[ret].genger);
 
		printf("请输入修改人的电话->:");
		scanf("%s", pc->date[ret].telephone);
 
		printf("请输入修改人的地址->:");
		scanf("%s", pc->date[ret].address);
		printf("恭喜你,修改成功~\n");
	}
}
 
int sort_name_max(const void* e1, const void* e2)
{
	return (strcmp(((struct Contact*)e1)->date->name, ((struct Contact*)e2)->date->name));
}
 
void Check_Contact(Contact* pc)
{
	//qosrt()函数首字母进行排序
	qsort(pc->date, pc->sz, sizeof(pc->date[0]), sort_name_max);
	printf("|-------------------------------------------------------|\n");
	printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,
			pc->date[i].age,
			pc->date[i].genger,
			pc->date[i].telephone,
			pc->date[i].address);
	}
}
 
void Destory_Contact(Contact* pc)
{
	//销毁通讯录实际上就是把date给释放掉,free()函数进行回收即可。
	free(pc -> date);
	pc->date = NULL;
	pc->sz = 0;
	pc->capacity = 0;
	//记得清0☆⌒(*^-゜)v THX!!
}

address_book.h

示例代码如下↓  

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h> 
#include<stdlib.h>
#include<Windows.h>
#include<string.h>
 
#define Max_name 5
#define Max_age 100
#define Max_genger 3
#define Max_address 20
#define Max_telephone 20
 
#define Defsz 3 //一开始的值
#define Inc 2  //每次的增量
 
//类型的定义
typedef struct information
{
	//名字、年龄、性别、电话、地址。
	char name[Max_name];
	char age[Max_age];
	char genger[Max_genger];
	char telephone[Max_telephone];
	char address[Max_address];
}information;
 
//初始化通讯录
void InitContact(Contact* pc);
//增加通讯录信息
void Add_Contact(Contact* pc);
//打印通讯录的信息
void Print_Contact(const Contact* pc);
//删除通讯人的信息
void DeLete_Contact(Contact* pc);
//查找指定通讯录人的信息
void Find_Contact(Contact* pc);
//修改指定通讯录人的信息
void Revise_Contact(Contact* pc);
//排查通讯录当中人员的信息
void Check_Contact(Contact* pc);
//销毁通讯录
void Destory_Contact(Contact* pc);

test.c

示例代码如下↓  

代码语言:javascript
复制
#include"address_book.h"
#include<Windows.h>
//颜色函数
void color(short x)
{
	if (x >= 0 && x <= 15)
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
	else
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
//创建菜单函数
void menu()
{
	color(0);//黑色
	system("cls");//清屏
 
	color(12);//白色
	printf("¤--------------------------------------------¤\n");
	printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");
	printf("|———————————————————————|\n");
	printf("|★★★★★→1.increase ■ 2.deLete←★★★★★|\n");
	printf("|★★★★★→3.find     ■ 4.Revise←★★★★★|\n");
	printf("|★★★★★→5.Check    ■ 6.Print ←★★★★★|\n");
	printf("|★★★★★→0.Exit     ■         ←★★★★★|\n");
	printf("|———————————————————————|\n");
	printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");
	printf("¤--------------------------------------------¤\n");
}
enum Number
{
	Exit,
	Increase,
	DeLete,
	Find,
	Revise,
	Check,
	Print,
};
int main(void)
{
	menu();
	int input = 0;
	//当然初始化全0:Contact con = {0};也是可以的,当然我们这里的初始化不是这样的原因是可以应对比较复杂的问题。
	Contact con;//初始化通讯录
	//给date申请一块连续的内存空间存放在堆区上。
	InitContact(&con);
	do
	{
		color(5);
		printf("¤----------------¤\n");
		printf("|请输入界面上的数字|:");
		scanf("%d", &input);
		printf("¤----------------¤\n");
		color(1);
		switch (input)
		{
		case Exit:
			//把通讯录里面的内存空间date给释放掉。
			Destory_Contact(&con);//销毁通讯录。
			printf("══════════════@\n");
			printf("退出通讯录v1.0@\n");
			printf("══════════════@\n");
			break;
		case Increase:
			//增加人的信息,放在通讯录当中去。
			Add_Contact(&con);
			break;
		case DeLete:
			//删除通讯人的信息
			DeLete_Contact(&con);
			break;
		case Find:
			//查找指定通讯录人的信息
			Find_Contact(&con);
			break;
		case Revise:
			//修改指定通讯录人的信息
			Revise_Contact(&con);
			break;
		case Check:
			//排查通讯录当中人员的信息
			Check_Contact(&con);
			break;
		case Print:
			//打印通讯录当中人员的信息。
			Print_Contact(&con);
			break;
		default:printf("你输入的数字找不到,请重新输入~\n");
		}
	} while (input);
	return 0;
}

最后

以上就是实现动态内存的实现方法了(^∀^●)ノシ。 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档