c语言小课设--通讯录(动态内存管理)

前言:

在没学动态内存管理之前,我们用的结构体,数组等都是静态分配内存的,也就是说数组的长度是固定的,但是这并不满足我们的实际需求,所以在通讯录项目里面我就用到了动态内存分布。简单来说,就是当需要储存的联系人数据太多了的时候,我们就可以扩大一点空间用来存放新的数据,也就是说实现了要多少,就开辟多少的空间。

项目介绍:

该项目实现一个通讯录功能,除了能根据具体需求扩大空间之外,也实现了最基本基本的增删查改等功能,并在退出通讯录时销毁创造的空间,从而不造成内存泄露。

另外,这个项目由三部分组成,函数功能的实现在Contact.c源文件中,各种头文件、函数等声明则由文件Contact.h来实现,最后测试在源文件test.c文件中进行。

一、teat.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"enum Option {Exit,add,modify,del,search,show,sort
};void menu() {printf("************************\n");printf("**1.添加    2.修改******\n");printf("**3.删除    4.搜索******\n");printf("**5.展示    6.排序******\n");printf("**0.退出          ******\n");printf("************************\n");
}int main() {int input = 0;Contacts Con;Init(&Con);do {menu();printf("请输入你的选择--》\n");scanf("%d", &input);switch (input) {case add://添加Add_Peo(&Con);break;case modify://修改Modify_Peo(&Con);break;case del:Del_Peo(&Con);break;case search:Sear_Peo(&Con); break;case show:Show_Peo(&Con);break;case sort:Sort_Peo(&Con);break;case Exit:Destory_Contacts(&Con);printf("退出通讯录\n");break;default:printf("你的输入有误!\n");break;}} while (input != 0);return 0;
}

二、Contact.h头文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define name_max 20
#define sex_max 5
#define tele_max 12
#define addr_max 20
#define num_max 100
#define default_cap 3typedef struct PeoInfo {char name[name_max];char sex[sex_max];char tele[tele_max];int age;
}PeoInfo;
//静态通讯录版本
//typedef struct Contacts {
//	PeoInfo data[num_max];
//	int sz;
//}Contacts;
//动态版本
typedef struct Contacts {PeoInfo *data;//存放数据int sz;//记录当前联系人的数量int cap;//当前通讯录的容量
}Contacts;//初始化通讯录
void Init(Contacts* Con);
//添加功能
void Add_Peo(Contacts* Con);
//修改功能
void Modify_Peo(Contacts* Con);
//删除联系人
void Del_Peo(Contacts* Con);
//展示联系人
void Show_Peo(Contacts* Con);
//查询联系人
void Sear_Peo(Contacts* Con);
//排序
void Sort_Peo(Contacts* Con);

三、Contact.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"// 自定义比较剂,按名字字典序排序int cmp(void* e1,void *e2) {//printf("%s %s\n", (, ((struct PeoInfo*)e2)->name);return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}//初始化通讯录
void Init(Contacts* Con) {assert(Con);Con->sz = 0;Con->cap = default_cap;Con->data = calloc(Con->cap, sizeof(PeoInfo));if (Con->data == NULL) {printf("初始化失败\n");return;}
}//void Init(Contacts* Con) {
//	assert(Con);
//	Con->sz = 0;
//	memset(Con->data, 0, sizeof(Con->data));
//}//增加容量
void check_cap(Contacts* Con) {PeoInfo* ptr = realloc(Con->data, (Con->cap + 2) * sizeof(PeoInfo));if (ptr != NULL) {Con->data = ptr;Con->cap += 2;printf("增容成功\n");}else {perror("AddContacts->realloc");return;}}
//添加功能
//动态版本
void Add_Peo(Contacts* Con) {assert(Con);if (Con->sz == Con->cap) {check_cap(Con);}printf("请输入添加人的姓名\n");scanf("%s", Con->data[Con->sz].name);printf("请输入添加人的年龄\n");scanf("%d", &Con->data[Con->sz].age);printf("请输入添加人的性别\n");scanf("%s", Con->data[Con->sz].sex);printf("请输入添加人的号码\n");scanf("%s", Con->data[Con->sz].tele);Con->sz++;return;
}
//静态版本
//void Add_Peo(Contacts* Con) {
//	assert(Con);
//	if (Con->sz == num_max) {
//		printf("通讯录已满\n");
//		return;
//	}
//	else {
//		printf("请输入添加人的姓名\n");
//		scanf("%s", Con->data[Con->sz].name);
//		printf("请输入添加人的年龄\n");
//		scanf("%d", &Con->data[Con->sz].age);
//		printf("请输入添加人的性别\n");
//		scanf("%s", Con->data[Con->sz].sex);
//		printf("请输入添加人的号码\n");
//		scanf("%s", Con->data[Con->sz].tele);
//		Con->sz++;
//		return;
//	}
//}
//按名字查找
int find_name(Contacts* Con,char *tager) {assert(Con);for (int i = 0; i < Con->sz; i++) {if (strcmp(Con->data[i].name, tager)==0) {return i;}}return -1;}
//修改功能
void Modify_Peo(Contacts* Con) {assert(Con);char name[name_max] = {0};while (1) {printf("请输入你要修改联系人的名字\n");scanf("%s", name);int k = find_name(Con, name);if ( k!= -1&&k>=0&&k<Con->sz) {printf("请重新输入修改的姓名\n");scanf("%s", Con->data[k].name);printf("请重新输入修改的的年龄\n");scanf("%d",&Con->data[k].age);printf("请重新输入修改的的性别\n");scanf("%s", Con->data[k].sex);printf("请重新输入修改的的号码\n");scanf("%s", Con->data[k].tele);printf("修改成功!\n");break;}else {printf("查无此人\n");break;}}}
//删除联系人
void Del_Peo(Contacts* Con) {assert(Con);if (Con->sz == 0) {printf("该通讯录还没有联系人\n");return;}printf("请输入你要删除联系人的姓名\n");char name1[name_max] = { 0 };scanf("%s", name1);int k = find_name(Con, name1);if (k != -1&&k>=0&&k<Con->sz) {for (int i = k; i < Con->sz - 1; i++) {Con->data[i] = Con->data[i + 1];}Con->sz--;printf("删除成功\n");}else {printf("查无此人\n");return;}
}
//展示联系人
void Show_Peo(Contacts* Con) {assert(Con);if (Con->sz == 0) {printf("没有联系人\n");return;}printf("-------------------------------------------------\n");printf("|%-20s |%-5s |%-5s |%-12s| \n","姓名","年龄","性别","号码");printf("-------------------------------------------------\n");for (int i = 0; i < Con->sz; i++) {printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[i].name, Con->data[i].age, Con->data[i].sex, Con->data[i].tele);if (i != (Con->sz - 1)) {printf("-------------------------------------------------\n");}}printf("-------------------------------------------------\n");
}
//查询联系人
void Sear_Peo(Contacts* Con) {assert(Con);char tager[name_max] = { 0 };if (Con->sz == 0) {printf("没有联系人\n");return;}printf("请输入你要查找的名字\n");scanf("%s", tager);int k = find_name(Con, tager);if (k != -1 && k >= 0 && k < Con->sz) {printf("-------------------------------------------------\n");printf("|%-20s |%-5s |%-5s |%-12s| \n", "姓名", "年龄", "性别", "号码");printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[k].name, Con->data[k].age, Con->data[k].sex, Con->data[k].tele);printf("-------------------------------------------------\n");}else {printf("查无此人\n");return;}
}
//排序
void Sort_Peo(Contacts* Con) {assert(Con);qsort(Con->data, Con->sz, sizeof(struct PeoInfo), cmp);printf("排序成功\n");return;
}
//销毁通讯录
void Destory_Contacts(Contacts* Con) {free(Con->data);Con->data = NULL;Con->cap = 0;Con->sz = 0;
}

好了以上就是整个项目的源代码了,是不是很简单呢?感兴趣的可以自己去试试哦!

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

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

相关文章

第3章-指标体系与数据可视化-3.1.1-Matplotlib绘图库

目录 3.1 Python可视化 3.1.1 Matplotlib绘图库 1. 线图 2. 饼图 3. 条形图 4. 直方图 5.散点图

【最多提取子串数目】python实现-附ChatGPT解析

1.题目 最多提取子串数目 知识点字符串统计Q 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 给定由[a-z] 26个英文小写字母组成的字符串A和B,其中A中可能存在重复字母,B中不会存在重复字母 现从字符串A中按规则挑选一些字母,可以组成字符串B 挑选规则如下: 同一个位置…

Python|OpenCV-如何给目标图像添加边框(7)

前言 本文是该专栏的第7篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在使用opencv处理图像的时候,会不可避免的对图像的一些具体区域进行一些操作。比如说,想要给目标图像创建一个围绕图像的边框。简单的来说,就是在图片的周围再填充一个粗线框。具体效果,…

k8s-实战——kubeadm二进制编译

文章目录 源码编译获取源码修改证书有效期修改 CA 有效期为 100 年(默认为 10 年)修改证书有效期为 100 年(默认为 1 年)CentOS7.9环境准备centos脚本安装执行脚本脚本内容手动安装验证编译查看编译后的版本信息参考链接脚本修改源码编译 源码编译kubeadm文件、修改证书的默…

【FPGA项目】图像采集及显示(3)总结

前言 最基础的FPGA图像采集及显示的项目做完,这里小小的总结一下,也顺便聊聊项目中常用的一些调试手段。 一、项目重点 1.1 系统框架的理解 我们先说下数据流,接收——>缓存——>处理——>发送,可以发现很多项目都存在这么一个过程,不同的只是接口而已。而系统…

快速开发微信小程序之一登录认证

一、背景 记得11、12年的时候大家一窝蜂的开始做客户端Android、IOS开发&#xff0c;我是14年才开始做Andoird开发&#xff0c;干了两年多&#xff0c;然后18年左右微信小程序火了&#xff0c;我也做了两个小程序&#xff0c;一个是将原有牛奶公众号的功能迁移到小程序&#x…

HashMap面试题

1.hashMap底层实现 hashMap的实现我们是要分jdk 1.7及以下版本&#xff0c;jdk1.8及以上版本 jdk 1.7 实现是用数组链表 jdk1.8 实现是用数组链表红黑树&#xff0c; 链表长度大于8&#xff08;TREEIFY_THRESHOLD&#xff09;时&#xff0c;会把链表转换为红黑树&#xff0c…

centos7卸载docker

菜鸟教程-常见命令&#xff1a;https://www.runoob.com/docker/docker-command-manual.html 1. 准备工作&#xff1a; 1.1 杀死docker有关的容器&#xff1a; docker kill $(docker ps -a -q)1.2 删除所有docker容器&#xff1a; docker rm $(docker ps -a -q)1.3 删除所有d…

简单走近ChatGPT

目录 一、ChatGPT整体背景认知 &#xff08;一&#xff09;ChatGPT引起关注的原因 &#xff08;二&#xff09;与其他公司的竞争情况 二、NLP学习范式的发展 &#xff08;一&#xff09;规则和机器学习时期 &#xff08;二&#xff09;基于神经网络的监督学习时期 &…

房产政策松绑,VR看房助力市场回春

近日房贷利率、房产限购开始松绑&#xff0c;房地产市场逐渐被激活&#xff0c;房产行业的线上服务能力&#xff0c;也愈发的受到了重视。随着房贷利率、首付比例变化的消息逐渐推出&#xff0c;部分用户开始入手房产市场&#xff0c;因此房产行业的线上服务也需要不断升级&…

leetCode 122.买卖股票的最佳时机 II 贪心算法

122. 买卖股票的最佳时机 II - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。 在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买&…

gitlab配置webhook限制提交注释

一、打开gitlab相关配置项 vim /etc/gitlab/gitlab.rb gitlab_shell[custom_hooks_dir] "/etc/gitlab/custom_hooks" 二、创建相关文件夹 mkdir -p /etc/gitlab/custom_hooks mkdir -p /etc/gitlab/custom_hooks/post-receive.d mkdir -p /etc/gitlab/custom_h…

Python教程:PyQt5需要学习,哪些知识点??

PyQt5是基于图形程序框架Qt5的Python语言实现&#xff0c;由一组Python模块构成。它可用于Python 2和3&#xff0c;拥有超过620个类和6000个函数和方法。这是一个跨平台的工具包&#xff0c;可以运行在所有主要的操作系统&#xff0c;包括UNIX、Windows、Mac OS、Linux等。 #我…

vue3学习实战

vue3新增变化 diff算法变化 vue3的diff算法没有vue2的头尾、尾头之间的diff&#xff0c;对diff算法进行了优化&#xff0c;最长递归子序列。 ref VS reactive ref 支持所有的类型&#xff0c;reactive 支持引用类型&#xff0c;array object Map Setref取值、赋值&#xff…

步力宝科技爆款产品定位,开创智能物联网新商业

数据显示&#xff0c;中国处于 “亚健康”状态人口数量约占总人口的70%&#xff0c;亚健康是一种临界状态&#xff0c;指介于健康和疾病之间的状态。亚健康是一个动态演变的过程&#xff0c;既有向慢病发展的趋势&#xff0c;也能通过合理的干预使人体重返健康状态&#xff0c;…

奥斯卡·王尔德

奥斯卡王尔德 奥斯卡王尔德&#xff08;Oscar Wilde&#xff0c;1854年10月16日—1900年11月30日&#xff09;&#xff0c;出生于爱尔兰都柏林&#xff0c;19世纪英国&#xff08;准确来讲是爱尔兰&#xff0c;但是当时由英国统治&#xff09;最伟大的作家与艺术家之一&#xf…

【RuoYi项目分析】在RuoYi网关实现验证码功能

文章目录 1. 验证码功能的类清单2. 验证码的实现2.1. 验证码的获取2.2. 验证码的校验 3. 总结4. 资料参考 本文主要介绍了用户如何实现验证码&#xff0c;以及该功能如何与 Spring Gateway 联系起来。 1. 验证码功能的类清单 类功能CaptchaProperties验证码的 yml 配置Captcha…

25-多线程

多线程 线程(Thread)是一个程序内部的一条执行流程。 程序中如果有一条执行流程&#xff0c;那这个程序就是单线程的程序 多线程是指从软硬件上实现的多条执行流程的技术&#xff08;多条线程由CPU负责调度执行&#xff09;。 再例如&#xff1a;消息通信、淘宝、京东系统都离…

适配器模式详解和实现(设计模式 四)

适配器模式将一个类的接口转换成客户端所期望的另一个接口&#xff0c;解决由于接口不兼容而无法进行合作的问题。 设计基本步骤 1. 创建目标接口&#xff08;Target Interface&#xff09;&#xff0c;该接口定义了客户端所期望的方法。 2.创建被适配类&#xff08;Adaptee…

【Flink】

事件驱动型应用 核心目标&#xff1a;数据流上的有状态计算 Apache Flink是一个框架和分布式处理引擎&#xff0c;用于对无界或有界数据流进行有状态计算。 运行逻辑 状态 把流处理需要的额外数据保存成一个“状态”,然后针对这条数据进行处理,并且更新状态。这就是所谓的“…