通讯录的实现(优化)【动态开辟+文件管理】

本文讲述了通讯录实现中的问题,如空间利用率低和数据丢失,通过动态内存开辟、文件管理和柔性数组来优化。介绍了动态开辟通讯录大小、初始化、扩容处理及保存信息到磁盘的方法,强调了正确操作和数据安全问题。

一、通讯录(优化后)实现所需知识

 经过上期的通讯录的实现,我们可以发现以下几个很明显的问题,一则:通讯录开辟的空间是静态的,我们不能更合理高效的利用开辟的空间,去存储联系人。二则:通讯录联系人的所有信息,都是写在内存上的,随着内存的关闭,所有联系人的信息,都被清空,再次打开这个程序,也找不回之前的信息。

这些问题,利用---动态内存开辟---文件管理---的知识是很容易解决的。若仍有诸多不解,可由以下链接跳转相关内容的详细归纳,以及简易通讯录的实现思路。

动态内存管理-优快云博客

文件管理【详解归纳】-优快云博客

通讯录项目的实现-优快云博客

二、通讯录——动态开辟通讯录大小的讲解

1.通讯录变量的实现

这里依然是建立两个结构体,第一个结构体类型是联系人类型。第二个结构体则是通讯录类型。这里通讯录结构体的三个参数进行详细说明。第一个参数,代表的是目前通讯录所能存储人的最大容量。第二参数,代表是目前通讯录,已保存联系人的个数。第三个参数,则是利用了一个柔性数组知识(柔性数组【详解】-优快云博客)。进行的动态内存开辟。

2.如何进行初始化

其实吧,通讯录的初始化,倒是挺简单的,只要掌握malloc函数怎么用,以及柔性数组如何开辟空间就能解决了。

这里我们既然运用到了柔性数组的知识,则得谨记用sizeof对结构体类型进行大小测量,是不包括柔性数组的大小的,所有这里的sizeof(contact)的值为8,我们若想达到我们想要开辟联系人大小大空间,则必须超出这个值,这里我为了方便实现通讯录的各个功能,仅仅多开辟了3个联系人大小的空间:3*sizeof(people);

不要忘了,亲自将con->count 亲自赋值当前通讯录的最大容量,其次不要忘了将con-> 亲自赋值为0,因为malloc这函数,只负责开辟空间,不负责初始化。

因为函数里面创建的变量,在离开这个函数的时候,会进行销毁,所以我们得把刚刚在堆区开辟的内存空间地址返回给函数外面的变量。

这里为了达到函数的高内聚低耦合,我选择了返回void* 类型的指针。

(这里被注释掉的语句是从外存(磁盘)中读取联系人信息到内存中)

3.如何进行扩容处理

这是主函数里面的部分代码:

这里的CHANGE_INT 是我用define定义过的,其值为2。

除了要讲解如何进行扩容处理外,需强调下易错的地方,不要看我函数里面的参数也设置的con,此con与外面的那个con,不一样,函数里面的con是外面那个con的临时拷贝。realloc函数返回值有三种情况,其一:若旧内存空间后面的空间足够,则直接在后面追加空间,其二若旧空间后面的空间不够,则重新在堆区找一片空间,并将所有信息拷贝到新空间中,同时销毁之前的空间。所以函数里面con指向的是一片新的空间,在扩容函数结束销毁,但是函数里面的con和函数外面的con不一样,所以函数外面的con仍指向旧空间的地址,不仅会造成通讯录的数据难以访问,而且这样会造成程序出错。所以我们同样返回void*类型的指针。重新赋值给函数外面的con;

三、通讯录——如何保存信息到磁盘上与每次打开通讯录加载信息到内存的讲解 

这里只是涉及到了文件管理的应用。故没有什么注意事项需要强调。其从外存读取数据到内存为何需要返回void*类型的指针,则因为里面嵌套了一个扩容函数。

唯一注意事项是,要谨记文件管理的正确操作,打开文件——使用文件——关闭文件,因为涉及文件缓冲区问题。

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
源码来自:https://pan.quark.cn/s/a4b39357ea24 在VC++开发过程中,对话框(CDialog)作为典型的用户界面组件,承担着与用户进行信息交互的重要角色。 在VS2008SP1的开发环境中,常常需要满足为对话框配置个性化背景图片的需求,以此来优化用户的操作体验。 本案例将系统性地阐述在CDialog框架下如何达成这一功能。 首先,需要在资源设计工具中构建一个新的对话框资源。 具体操作是在Visual Studio平台中,进入资源视图(Resource View)界面,定位到对话框(Dialog)分支,通过右键选择“插入对话框”(Insert Dialog)选项。 完成对话框内控件的布局设计后,对对话框资源进行保存。 随后,将着手进行背景图片的载入工作。 通常有两种主要的技术路径:1. **运用位图控件(CStatic)**:在对话框界面中嵌入一个CStatic控件,并将其属性设置为BST_OWNERDRAW,从而具备自主控制绘制过程的权限。 在对话框的类定义中,需要重写OnPaint()函数,负责调用图片资源并借助CDC对象将其渲染到对话框表面。 此外,必须合理处理WM_CTLCOLORSTATIC消息,确保背景图片的展示不会受到其他界面元素的干扰。 ```cppvoid CMyDialog::OnPaint(){ CPaintDC dc(this); // 生成设备上下文对象 CBitmap bitmap; bitmap.LoadBitmap(IDC_BITMAP_BACKGROUND); // 获取背景图片资源 CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap* pOldBitmap = m...
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值