通信录的动态版本

news2024/11/28 16:51:31

一. 增加需求

在学习了动态开辟内存之后 我们对于通讯录产生了新的需求

要求我们做出一个动态增长的版本

即 随着我们储存联系人的增加 储存的空间增加

要求 :

1 初始空间为3
2 每次达到上限之后 扩容两个内存

二. 动手实施 

我们首先要创建一个结构体

结构体的代码暂定为这样子

typedef struct Contact
{
	PeoInfo* date;//存放人的信息
	int sz;//当前已经放的信息个数
	int capacity;//当前通信录的最大容量
}Contact;

 既然结构体改变了 那么我们的初始化也需要改变一下

void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo*));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return ;
	}
	pc->date = ptr;
	pc->capacity = DEFAULT_SZ;
}

这样我们就初始化出来了 一块新的空间

那么这个时候我们开始设计增加联系人的功能

主要思路就是 如果联系人到了上线的话 那么realloc增容上线+2

另外 上线也加上2

代码表示如下

void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo* ptr = (PeoInfo*)realloc(pc->date, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
		}
		else
		pc->date = ptr;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}
//动态版本
void AddContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);

	//增加一个人的信息
	printf("请输入名字:>");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->date[pc->sz].age));
	printf("请输入性别:>");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入地址:>");
	scanf("%s", pc->date[pc->sz].addr);
	printf("请输入电话:>");
	scanf("%s", pc->date[pc->sz].tele);
	pc->sz++;

}

代码显示效果如下

三. 回收空间

其他要修改的地方只是一个回收动态开辟的空间 防止内存泄漏

void DestroyContact(Contact* pc)
{
	free(pc->date);
	pc->date = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}

代码很简单 只需要这样子就好啦

四. 所有代码文件

1. 头文件

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#include<stdlib.h>


#define MAX 100
#define MAX_NEME 20
#define MAX_SEX 5
#define MAX_ADDR 30
#define MAX_TELE 12
#define DEFAULT_SZ 3
#define INC_SZ 2



//人的信息
typedef struct PeoInfo
{
	char name[MAX_NEME];
	int age;
	char sex[MAX_SEX];
	char addr[MAX_ADDR];
	char tele[MAX_TELE];
}PeoInfo;
//静态版本
//typedef struct Contact
//{
//	PeoInfo date[MAX];//存放人的信息
//	int sz;//当前已经放的信息个数
//}Contact;
//动态版本
typedef struct Contact
{
	PeoInfo* date;//存放人的信息
	int sz;//当前已经放的信息个数
	int capacity;//当前通信录的最大容量
}Contact;

2. 主函数文件

void memu()
{
	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");
}
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
void test()
{
	int input = 0;
	//创建通信录
	Contact con;
	//初始化通信录
	InitContact(&con);


	do
	{
		memu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModityContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		case SORT:
			//SortContact(&con);
			break;
		case EXIT:
			DestroyContact(&con);
			printf("退出通信录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

3. 测试文件

#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
//静态版本
//void InitContact(Contact* pc)
//{
//	assert(pc);
//	pc->sz = 0;
//	memset(pc->date, 0, sizeof(pc->date));
//}
//动态版本
void InitContact(Contact* pc)
{
	assert(pc);
	pc->sz = 0;
	PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo*));
	if (ptr == NULL)
	{
		perror("InitContact::calloc");
		return ;
	}
	pc->date = ptr;
	pc->capacity = DEFAULT_SZ;
}

//静态版本
//void AddContact(Contact* pc)
//{
//	assert(pc);
//	if (pc->sz == MAX)
//	{
//		printf("通信录已满,无法添加\n");
//		return ;
//	}
//	//增加一个人的信息
//	printf("请输入名字:>");
//	scanf("%s", pc->date[pc->sz].name);
//	printf("请输入年龄:>");
//	scanf("%d", &(pc->date[pc->sz].age));
//	printf("请输入性别:>");
//	scanf("%s", pc->date[pc->sz].sex);
//	printf("请输入地址:>");
//	scanf("%s", pc->date[pc->sz].addr);
//	printf("请输入电话:>");
//	scanf("%s", pc->date[pc->sz].tele);
//	pc->sz++;
//
//}

void check_capacity(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		//增容
		PeoInfo* ptr = (PeoInfo*)realloc(pc->date, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
		if (ptr == NULL)
		{
			perror("check_capacity::realloc");
		}
		else
		pc->date = ptr;
		pc->capacity += INC_SZ;
		printf("增容成功\n");
	}
}
//动态版本
void AddContact(Contact* pc)
{
	assert(pc);
	check_capacity(pc);

	//增加一个人的信息
	printf("请输入名字:>");
	scanf("%s", pc->date[pc->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->date[pc->sz].age));
	printf("请输入性别:>");
	scanf("%s", pc->date[pc->sz].sex);
	printf("请输入地址:>");
	scanf("%s", pc->date[pc->sz].addr);
	printf("请输入电话:>");
	scanf("%s", pc->date[pc->sz].tele);
	pc->sz++;

}

void DestroyContact(Contact* pc)
{
	free(pc->date);
	pc->date = NULL;
	pc->capacity = 0;
	pc->sz = 0;
	pc = NULL;
}





void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->date[i].name,
			pc->date[i].age,
			pc->date[i].sex,
			pc->date[i].addr,
			pc->date[i].tele);
	}
}

int FindByName(Contact* pc, char name[])
{
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->date[i].name, name) == 0)
		{
			return i;
		}
	}
	return -1;
}

void DelContact(Contact* pc)
{
	assert(pc);
	int i = 0;
	char name[MAX_NEME];
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
	}
	printf("请输入要删除人的名字:>");
	scanf("%s", &name);
	int del = 0;
	//找到删除人的名字
	int ret = FindByName(pc, name);
	if (-1 == ret)
	{
		printf("要删除的人不存在\n");
	}

	//删除
	for (i = ret; i < pc->sz - 1; i++)
	{
		pc->date[i] = pc->date[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}


void SearchContact(const Contact* pc)
{
	char name[MAX_NEME] = { 0 };
	printf("请输入查找人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("查找人的信息不存在\n");
		return ;
	}
	//打印信息
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
	printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->date[pos].name,
			pc->date[pos].age,
			pc->date[pos].sex,
			pc->date[pos].addr,
			pc->date[pos].tele);

}

void ModityContact(Contact* pc)
{
	assert(pc);
	char name[MAX_NEME] = { 0 };
	printf("请输入修改人的名字:>");
	scanf("%s", &name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("修改人的信息不存在\n");
		return;
	}
	//录入信息
	printf("请输入名字:>");
	scanf("%s", pc->date[pos].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->date[pos].age));
	printf("请输入性别:>");
	scanf("%s", pc->date[pos].sex);
	printf("请输入地址:>");
	scanf("%s", pc->date[pos].addr);
	printf("请输入电话:>");
	scanf("%s", pc->date[pos].tele);

	printf("修改完成\n");
}

//int cmp(void* a, void* b)
//{
//	Contact* p1 = (Contact*)a;
//	Contact* p2 = (Contact*)b;
//	return strcmp(p1->date->name, p2->date->name);
//}
//
//void SortContact(Contact* pc)
//{
//
//	qsort(pc, pc->sz, sizeof(Contact*), cmp);
//}

以上便是本文所有内容,如有错误请各位大佬不吝赐教,感谢留言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1650121.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算图:深度学习中的链式求导与反向传播引擎

在深度学习的世界中&#xff0c;计算图扮演着至关重要的角色。它不仅是数学计算的图形化表示&#xff0c;更是链式求导与反向传播算法的核心。本文将深入探讨计算图的基本概念、与链式求导的紧密关系及其在反向传播中的应用&#xff0c;旨在为读者提供一个全面而深入的理解。 计…

Springboot项目学习之各组件的用法和逻辑结构

1.Controller层&#xff08;Controller&#xff09;&#xff1a; 也称为前端控制器或请求处理器&#xff0c;它是项目与用户交互的入口。Controller接收HTTP请求&#xff0c;解析请求参数&#xff0c;调用Service层处理业务逻辑&#xff0c;并返回响应给客户端。 Controller通…

Python实现txt转Excel(坐标)

import pandas as pddef txt_to_excel(txt_file, excel_file):# 读取 txt 文件with open(txt_file, r) as f:lines f.readlines()# 将每行数据分割成多个单元格data []for line in lines:row line.strip().split( )data.append(row)# 将数据保存到 Excel 文件df pd.DataFra…

阿里巴巴alibaba国际站API接口:商品详情和关键词搜索商品列表

阿里巴巴国际站&#xff08;Alibaba.com&#xff09;提供了API接口供开发者使用&#xff0c;以实现与平台的数据交互。然而&#xff0c;由于API的详细内容和调用方式可能会随着时间和平台更新而发生变化&#xff0c;以下是一个概述和一般性的指导&#xff0c;关于如何使用阿里巴…

代码随想录第52天|300.最长递增子序列 718. 最长重复子数组

300.最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 代码随想录 (programmercarl.com) 动态规划之子序列问题&#xff0c;元素不连续&#xff01;| LeetCode&#xff1a;300.最长递增子序列_哔哩哔哩_bilibili 给你一个整数数组 nums &#xff0…

xmind的13个快捷方式

1.新建导图 CtrlshiftN 2.编辑文字 空格键 3.插入图片 Ctrli 4. 插入主题 Enter键 5. 插入主题之前 ShiftEnter键 6. 插入子主题 Tab键 7. 放大导图 “Ctrl”“” 8. 缩小导图 “Ctrl”“-” 9. 复制 CtrlInsert 10. 粘贴 Shift Insert 11. 剪切 ShiftDelete 12. 截图 F7 13. 保…

神经网络怎么把隐含层变量融合到损失函数中?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Unity初级---初识生命周期

1. Awake() &#xff1a;唤醒函数&#xff0c;最先执行的函数&#xff0c;只执行一次&#xff0c;当脚本文件挂载的对象被激活时调用 2. OnEnable() &#xff0c;OnDisable()&#xff1a;当脚本启用和禁用时触发&#xff0c;可执行多次&#xff0c;触发的前提是脚本挂载的对象…

SolidWorks进行热力学有限元分析一、模型建立

1.话不多说按照我的操作来 2.这一步鼠标移到中心点直接拉就行 3.这里选单位&#xff0c;继续按照操作来 4.选中这个边&#xff0c;直接拉&#xff0c;输入尺寸后确定&#xff0c;其他边同理 5.鼠标右键设置厚度 6.右键零件&#xff0c;然后编辑材料&#xff0c;给他赋予你需要的…

纯血鸿蒙APP实战开发——折叠屏扫描二维码方案

折叠屏扫描二维码方案 介绍 本示例介绍使用自定义界面扫码能力在折叠屏设备中实现折叠态切换适配。自定义界面扫码使用系统能力customScan&#xff0c;其提供相机流的初始化、启动扫码、识别、停止扫码、释放相机流资源等能力。折叠屏折叠状态通过监听display的foldStatusCha…

【论文阅读】Fuzz4All: Universal Fuzzing with Large Language Models

文章目录 摘要一、介绍二、Fuzz4All的方法2.1、自动提示2.1.1、自动提示算法2.1.2、自动提示的例子2.1.3、与现有自动提示技术的比较 2.2、fuzzing循环2.2.1、模糊循环算法2.2.2、Oracle 三、实验设计3.1、实现3.2、被测系统和baseline3.3、实验设置以及评估指标 四、结果分析4…

Qt | QComboBox(组合框)

01、上节回顾 Qt 基础教程合集02、QComBox 一、QComboBox 类(下拉列表、组合框) 1、QComboBox 类是 QWidget 类的直接子类,该类实现了一个组合框 2、QComboBox 类中的属性 ①、count:const int 访问函数:int count() const; 获取组合框中的项目数量,默认情况下,对于空…

nginx 负载均衡、反向代理实验

nginx 负载均衡、反向代理实验 实验目的 理解概念&#xff1a;明确反向代理和负载均衡的基本概念及其在网络架构中的作用。 掌握技能&#xff1a;学习如何配置Nginx以实现反向代理和负载均衡功能。 实践应用&#xff1a;通过实际操作&#xff0c;体验Nginx如何提升Web服务的可…

246 基于matlab的交流电机动态方程

基于matlab的交流电机动态方程&#xff0c;用于交流电机动态分析。输入电机的额定功率(kW)、电机的额定转速(r/min)、转子外径(m)、铁心长(m)转子槽数、电机极对数 等参数&#xff0c;输出转速变化、力矩变化等结果。程序已调通&#xff0c;可直接运行。 246 交流电机动态 转速…

一堆自定义C#代码片段,让你开发效率飞涨

SharpBoxes 是一款用于 Visual Studio 的扩展&#xff0c;作者为本人&#xff1b; 该扩展旨在提高开发效率。它为开发人员提供了一组日常使用频率较高的代码片段&#xff0c;让你在编写代码时能够更快地插入常用的代码段。通过安装这个扩展&#xff0c;你可以使用快捷键轻松插…

笔记本连接不上远程桌面,笔记本无法连接远程桌面的可能原因及解决方法

在使用远程桌面功能时&#xff0c;笔记本无法成功连接的情况可能由多种原因引起。为了有效地解决这个问题&#xff0c;我们需要逐一排查这些可能的原因&#xff0c;并采取相应的解决措施。 首先&#xff0c;网络连接稳定性是远程桌面连接成功的关键。请确保笔记本和远程计算机之…

【数据结构】链表经典OJ题目练习(2)

面试题 02.02. 返回倒数第 k 个节点 - 力扣&#xff08;LeetCode&#xff09; 思路1&#xff1a;先计算出链表的长度&#xff0c;在将链表中的值存在数组中&#xff0c;在返回第k个节点。 思路2&#xff1a;利用快慢指针&#xff0c;先让快指针走k步&#xff0c;在让快慢指针分…

北京大学-知存科技存算一体联合实验室揭牌,开启知存科技产学研融合战略新升级

5月5日&#xff0c;“北京大学-知存科技存算一体技术联合实验室”在北京大学微纳电子大厦正式揭牌&#xff0c;北京大学集成电路学院院长蔡一茂、北京大学集成电路学院副院长鲁文高及学院相关负责人、知存科技创始人兼CEO王绍迪、知存科技首席科学家郭昕婕博士及企业研发相关负…

谷歌推出10门免费AI课程,无需教科书及费用

谷歌面向小白以及开发者分别推出了不同的AI课程~ 包含初级、中级和高级。课程章节大致包括&#xff1a;&#xff08;含教学视频、参考材料、测验&#xff09; 基础入门&#xff1a;45分钟深入了解生成式AI 简单实操&#xff1a;30分钟掌握大语言模型 了解如何释放生成式 AI S…

02-Fortran基础--Fortran操作符与控制结构

02-Fortran基础--Fortran操作符与控制结构 0 引言1 操作符1.1 数学运算符1.2 逻辑运算符1.3 关系运算符 2 控制流程2.1 条件结构2.2 循环结构2.3 分支结构 0 引言 运算符和控制流程对编程语言是必须的,Fortran的操作符和控制流程涉及到各种数学运算符、逻辑运算符以及控制结构。…