目录

前言

程序设计

1. 通讯录的创建

2. 初始化通讯录

3. 动态增加容量

4. 销毁通讯录


前言

前面已经讲述了静态版本的通讯录,为了能够有更友好的使用通讯录,这次我将讲述以下如何将静态版本的通讯录更新为同动态版本。

在观看本篇文章之前,建议先观看上一篇《通讯录的实现(静态版本)--C语言》

程序设计

动态版本的通讯录运用到了动态内存管理,首先我们需要对通讯录的结构体进行更改。

1. 通讯录的创建

静态版本:

struct Contact
{struct PeoInfo data[MAX];//静态int sz;
};

我们知道静态版本的通讯录数据的开辟需要修改data数组的大小,而data数组的大小是固定的,当通讯录达到额定的大小之后就无法再添加联系人。

动态版本:

struct Contact
{struct PeoInfo* data;//动态int sz;int Capacity;//容量
};

动态版本引用了顺序表来存放数据,简单来说就是在结构体中再添加一个Capacity变量来表示现在data指针可以存放多少数据。例如,我们在一开始开辟了3个数据内存的大小的指针给了data,当sz等于0时,为第一个数据;当sz等于1时,可以通过下标找到data的第二块空间,以此类推。

如上图所示,data[0]为第一个数据,因为放入了一个数据,因此sz加一。

2. 初始化通讯录

由于通讯录一开始创建的data为指针,所以我们需要为指针开辟空间才能够对其进行使用。

动态内存函数: 

malloc:开辟一块空间,未初始化;

calloc:开辟一块空间并且将空间的内存初始化为0;

realloc:为一块申请到的空间进行扩容\缩小,假如传入的指针为NULL,函数则与malloc函                   数的功能一致;

free:释放申请到的内存,若传入的指针为NULL,函数则不做事。

//初始化通讯录
void InitContact(struct Contact* pc)
{assert(pc);//动态int* ptr = (int*)calloc(DEFAULT_SZ, sizeof(struct PeoInfo));if (ptr == NULL){perror("InitContact()");return;}pc->data = ptr;pc->Capacity = DEFAULT_SZ;pc->sz = 0;
}
#define DEFAULT_SZ 3

在这里,我们可以使用calloc函数进行开辟内存空间,因为函数会顺带初始化空间。函数返回指针时,我们应该要先检查指针是否可用,因为有时候内存开辟失败会返回空指针,所以需要在使用内存空间之前对指针进行检查。确定可用之后才赋值给data

3. 动态增加容量

当通讯录满了以后,我们想要继续增加该如何处理?

我们需要在增加联系人之前先检查容量是否充足。

//检查容量
const int check_capacity(struct Contact* pc)
{if (pc->Capacity == pc->sz){int NewCapacity = INC_SZ + pc->Capacity;struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->data, NewCapacity * sizeof(struct PeoInfo));if (ptr == NULL){perror("AddContact()");return -1;}pc->data = ptr;pc->Capacity = NewCapacity;//printf("扩容成功\n");return 1;}else{return 1;}
}
#define INC_SZ 2

当容量不足时,我们需要对内存空间进行扩容,因此需要使用到realloc函数注意:realloc函数第二个参数为扩容后的内存大小。

调用函数时,若容量已经满了,则对data进行扩容,成功扩容返回1(这里的值可以是任意,但在这我取1作返回值);失败则返回-1,打印错误信息并结束函数。

还有一种情况就是数据小于容量的大小,则返回1,正常增加联系人。

void AddContact(struct Contact* pc)
{assert(pc);if (check_capacity(pc) == 1){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].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("成功添加联系人\n");}else{return;}
}

4. 销毁通讯录

在程序结束之前,我们还需要对申请到的内存空间进行释放,否则可能会造成内存泄漏。

//回收内存
void DestroyContact(struct Contact* pc)
{assert(pc);free(pc->data);pc->data = NULL;pc->Capacity = 0;pc->sz = 0;
}

将内存释放后,我们可以再将指针data制成空指针。注意:在程序结束之前需要引用一次该函数。

至此,通讯录的静态版本已经更新为动态版本。

通讯录(动态版本)--C语言相关推荐

  1. 用C语言实现 静态通讯录+动态通讯录+文件实现“退出保存信息版本”(附上思路+项目展示+源代码)

    前言 : 在生活中我们经常会遇到通讯录的使用,比如存进一个新的联系人的信息,或者对其删除,修改,查找:那这些神奇的功能是如何实现的?我们不禁好奇.今天,这篇博文将教会大家实现一个静态的或者动态的通讯录 ...

  2. C语言实现通讯录(静态版本+动态版本)

    当前使用VS2019编译器 首先建立2个源文件test.c和contect.c以及1个头文件contect.h 一.通讯录操作菜单 void menu() {printf("******** ...

  3. C语言课设作业《通讯录》全程记录 ps:动态版本

    写在前面: 通讯录算是前面对学过知识的一个综合运用,涉及到的知识点有 :枚举类型,结构体.结构体指针.动态内存分配(malloc,calloc,realloc,free).typedef关键字.多文件 ...

  4. 通讯录的实现(静态版本,动态版本,文件版本)(后附完整源代码)

    通讯录的实现 一.静态版本 1.所需要的功能 2.大致菜单 3.创建通讯录 4.增加联系人 5.显示联系人 6.查找联系人 7.删除联系人 8.修改联系人 9.按名字排序 10.源代码 二.动态版本 ...

  5. 通讯录管理系统(c语言版本)

    通讯录管理系统 (c语言版本) 一:通讯录基本功能 二:实现代码分析 1:建立文件 2:test.c test.c完整代码 3:contact.c contact.c完整代码 3:contact.h ...

  6. RDIFramework.NET V2.9版本多语言的实现

    RDIFramework.NET V2.9版本多语言的实现 现在是国际化时代,软件也不能落后.一个公司里很可能会有老外,也可能有台湾的朋友,他们用软件的习惯都不一样,若同样一个软件同时能适应多种语言文 ...

  7. QML程序实现动态切换多语言

    原文地址::https://zhuanlan.zhihu.com/p/40815590 Qt程序中实现多语言有Qt自己的一套机制,然而目前在5.9版本下该机制无法在程序运行期间动态切换语言.本文向大家 ...

  8. 静态类型和动态类型的语言有什么区别?

    我听到很多新的编程语言是动态类型的,但是当我们说一种语言是动态类型还是静态类型时,这实际上意味着什么? #1楼 http://en.wikipedia.org/wiki/Type_system 静态打 ...

  9. 二进制包如何知道go 版本_你有同时使用多版本 Go 语言的需求吗,那就快使用多版本管理利器 GVM 吧!...

    公众号关注 「奇妙的 Linux 世界」设为「星标」,每天带你玩转 Linux ! Golang 发展迅速,代码迭代非常快,想要在同一环境调试和梳理不同项目进程就成了一件相对棘手的事情.二进制文件的管 ...

最新文章

  1. rman备份脚本shell版
  2. angular5 ng-content使用方法
  3. 2.利用计算机进行信息加工的一般过程是:,[信息技术教案]《计算机信息加工的一般过程》教案...
  4. 【Linux】一步一步学Linux——arp命令(163)
  5. ECCV 2020 论文大盘点-自动驾驶篇
  6. Matplotlib作业一
  7. android 线性布局
  8. shell手册--笨鸟杰作
  9. Linux下搭建CACTI的时候总结的一些小知识
  10. android 进制转换的方法
  11. k8s 亲和 反亲和介绍
  12. 10347 忙碌又贪心的泥瓦匠
  13. jquery animate 数字动态变化达不到指定的值
  14. 基于改进区域生长算法的图像分割方法及实现
  15. 嘟噜噜的难受伴快乐的一天。
  16. 计算机基础---学习笔记
  17. 服务器操作系统查询命令,服务器操作系统查询命令
  18. QQ2012Beta1登录协议(异地需要验证码,且密码错误的情况)
  19. Python实现线性回归和梯度下降算法
  20. 车内看车头正不正技巧_【交通安全提示】科二曲线行驶技巧图解,蜀黍手把手教你过关!...

热门文章

  1. 企业如何实现高效的协作办公?
  2. 3D打印塑料钢网全流程介绍(文件输出、PCB刷锡浆、PTC焊接)
  3. 新浪实时股票信息查询(JavaScript代码)
  4. 寻迹小车驱动模块电路设计
  5. 【iOS】iphone 短信标记未读 bug/ 永远清不干净的红点未读提示 /总结四大解决方案,总有N个适合你
  6. 手机号码段简介以及最新手机号段归属地数据库(2017年6月28日)
  7. 朗强科技:HDMI信号分配传输器的功能与使用
  8. QQ个人信息保护 | 攻的对面叫防
  9. 显示器连接vdc服务器,基于数字化校园的图像分析型VDC服务器的设计与实现
  10. cartographer源码分析(4)sensor_bridge.cc以及sensor_bridge.h