C语言之动态内存管理实现通讯录(完整版)

编程入门 行业动态 更新时间:2024-10-19 11:59:06

C语言之动态内存管理实现通讯录(<a href=https://www.elefans.com/category/jswz/34/1770030.html style=完整版)"/>

C语言之动态内存管理实现通讯录(完整版)

我们在之前的博客中写过静态版的通讯录,我们今天来写一个动态版的,不需要规定它到底需要多大空间,只要还有内存,我们都可以存放的下!同时,函数实现原理,我在通讯录静态版的博客里做了详细的讲解,这里就不详细分析了,不了解原理的小伙伴们可以去C语言通讯录静态版了解一下!

目录

1.函数各部分功能

1.1初始化通讯录

1.2检测通讯录是否需要增容

1.3增加联系人

1.4删除联系人

1.5显示联系人

1.6按名字查找联系人

1.7查找指定联系人

1.8修改指定联系人的信息

1.9对所有联系人按姓名进行排序

1.10销毁通讯录,进行动态空间内存的释放

2.函数源码

2.1test.c测试代码

2.2contact.c函数各功能实现代码

2.3contact.h实现通讯录所需要的头文件代码

3.运行结果


我们在以前静态 的基础上不仅加入内存动态管理,还加入枚举,增强代码的可读性,同时我在代码难以理解的地方增加了详细的注释,相信大家可以理解!

1.函数各部分功能

1.1初始化通讯录

//初始化这个通讯录,初始化为对应的值
void InitContact(Contact* pc)
{assert(pc);//为通讯录存放人的信息的结构体分配初始空间,并把里面数据直接//初始化为0,calloc函数很合适PeopInfo* str = (PeopInfo*)calloc(DEFAULT_SZ, sizeof(PeopInfo));if (str == NULL){perror("calloc");return;}pc->data = str;pc->sz = 0;pc->capacity = DEFAULT_SZ;
}

1.2检测通讯录是否需要增容

//空间增容函数
void check_capacity(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){//通讯录已满,进行增容PeopInfo* str = (PeopInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeopInfo));if (str == NULL){perror("realloc");return;}pc->data = str;pc->capacity += INC_SZ;//总容量增加printf("空间增容成功,可以继续添加联系人\n");}
}

1.3增加联系人

//增加通讯录联系人
void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);//检查通讯录是否需要增容//增加人的信息printf("请输入联系人姓名:>");scanf("%s", pc->data[pc->sz].Name);printf("请输入联系人年龄:>");scanf("%d", &pc->data[pc->sz].Age);printf("请输入联系人性别:>");scanf("%s", pc->data[pc->sz].Sex);printf("请输入联系人电话号码:>");scanf("%s", pc->data[pc->sz].Tele);printf("请输入联系人家庭住址:>");scanf("%s", pc->data[pc->sz].Addr);pc->sz++;
}

1.4删除联系人

//删除指定联系人
void DelContact(Contact* pc)
{assert(pc);char Name[NAME_MAX] = { 0 };int i = 0;if (pc->sz == 0){printf("通讯录为空,无法删除!\n");return;}printf("请输入要删除的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要删除的联系人不存在!\n");return;}for (i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除联系人成功!\n");
}

1.5显示联系人

//显示所有联系人
void ShowContact(const Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法显示!\n");return;}int i = 0;printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n","姓名","年龄","性别","电话号码","家庭住址");for (i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",pc->data[i].Name,pc->data[i].Age,pc->data[i].Sex,pc->data[i].Tele,pc->data[i].Addr);}
}

1.6按名字查找联系人

//通过名字查找
int FindByName(const Contact* pc, char* Name)
{assert(pc);int i = 0;if (pc->sz == 0){printf("通讯录为空,无法查找!");return;}for (i = 0; i < pc->sz; i++){if (strcmp(Name, pc->data[i].Name) == 0)return i;}return -1;
}

1.7查找指定联系人

//查找指定联系人
void SehContact(const Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法查找!\n");return;}char Name[NAME_MAX] = { 0 };printf("请输入要查找的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要查找的联系人不存在!\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话号码", "家庭住址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",pc->data[pos].Name,pc->data[pos].Age,pc->data[pos].Sex,pc->data[pos].Tele,pc->data[pos].Addr);
}

1.8修改指定联系人的信息

//修改指点联系人的信息
void MofContact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法修改!\n");return;}char Name[NAME_MAX] = { 0 };printf("请输入要修改的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要修改的联系人不存在!\n");return;}printf("请输入联系人姓名:>");scanf("%s", pc->data[pos].Name);printf("请输入联系人年龄:>");scanf("%d", &pc->data[pos].Age);printf("请输入联系人性别:>");scanf("%s", pc->data[pos].Sex);printf("请输入联系人电话号码:>");scanf("%s", pc->data[pos].Tele);printf("请输入联系人家庭住址:>");scanf("%s", pc->data[pos].Addr);
}

1.9对所有联系人按姓名进行排序

//对所有联系人按姓名进行排序
void SortContact(const Contact* pc)
{assert(pc);int i = 0;int j = 0;for (i = 0; i < pc->sz; i++){for (j = i; j < pc->sz; j++){if (strcmp(pc->data[i].Name, pc->data[j].Name) > 0){PeopInfo temp[] = { 0 };temp[0] = pc->data[i];pc->data[i] = pc->data[j];pc->data[j] = temp[0];}}}ShowContact(pc);//显示一下排列结果
}

1.10销毁通讯录,进行动态空间内存的释放

//销毁通讯录,释放动态内存空间
void DestoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->sz = 0;pc->capacity = 0;pc = NULL;printf("通讯录已销毁\n");
}

2.函数源码

2.1test.c测试代码

//创建一个动态空间内存通讯录,里面存放人的信息,包括姓名,年龄,性别
//电话号码和家庭住址
//结合枚举,必要时要增容
//它包括一下功能
//1.增加联系人
//2.删除指定联系人
//3.查找指定联系人
//4.修改指定联系人
//5.显示所有联系人
//6.对所有联系人进行排序(按姓名)
//7.退出通讯录(这时要记得释放动态内存开辟的空间,避免内存泄漏#include"contact.h"//引用自己创建的头文件,用双引号//加入枚举,给下面Switch case语句一个提示,函数写到了通讯录的哪个功能
enum contact
{exitContact,addContact,delContact,showContact,sehContact,mofContact,sortContact,
};
void menu(void)
{printf("*******************************************\n");printf("**********     1.AddContact      **********\n");printf("**********     2.DelContact      **********\n");printf("**********     3.ShowContact     **********\n");printf("**********     4.SehContact      **********\n");printf("**********     5.MofContact      **********\n");printf("**********     6.SortContact     **********\n");printf("**********     0.ExitContact     **********\n");printf("*******************************************\n");
}
int main()
{int input = 0;Contact con;//初始化通讯录InitContact(&con);//打印菜单do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case addContact:AddContact(&con);break;case delContact:DelContact(&con);break;case showContact:ShowContact(&con);break;case sehContact:SehContact(&con);break;case mofContact:MofContact(&con);break;case sortContact:SortContact(&con);break;case exitContact://销毁通讯录,进行动态空间的释放DestoryContact(&con);break;default:printf("输入错误,请重新输入!\n");break;}} while (input);return 0;
}

2.2contact.c函数各功能实现代码

#include"contact.h"//空间增容函数
void check_capacity(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){//通讯录已满,进行增容PeopInfo* str = (PeopInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeopInfo));if (str == NULL){perror("realloc");return;}pc->data = str;pc->capacity += INC_SZ;//总容量增加printf("空间增容成功,可以继续添加联系人\n");}
}//通过名字查找
int FindByName(const Contact* pc, char* Name)
{assert(pc);int i = 0;if (pc->sz == 0){printf("通讯录为空,无法查找!");return;}for (i = 0; i < pc->sz; i++){if (strcmp(Name, pc->data[i].Name) == 0)return i;}return -1;
}
//初始化这个通讯录,初始化为对应的值
void InitContact(Contact* pc)
{assert(pc);//为通讯录存放人的信息的结构体分配初始空间,并把里面数据直接//初始化为0,calloc函数很合适PeopInfo* str = (PeopInfo*)calloc(DEFAULT_SZ, sizeof(PeopInfo));if (str == NULL){perror("calloc");return;}pc->data = str;pc->sz = 0;pc->capacity = DEFAULT_SZ;
}//增加通讯录联系人
void AddContact(Contact* pc)
{assert(pc);check_capacity(pc);//检查通讯录是否需要增容//增加人的信息printf("请输入联系人姓名:>");scanf("%s", pc->data[pc->sz].Name);printf("请输入联系人年龄:>");scanf("%d", &pc->data[pc->sz].Age);printf("请输入联系人性别:>");scanf("%s", pc->data[pc->sz].Sex);printf("请输入联系人电话号码:>");scanf("%s", pc->data[pc->sz].Tele);printf("请输入联系人家庭住址:>");scanf("%s", pc->data[pc->sz].Addr);pc->sz++;
}
//删除指定联系人
void DelContact(Contact* pc)
{assert(pc);char Name[NAME_MAX] = { 0 };int i = 0;if (pc->sz == 0){printf("通讯录为空,无法删除!\n");return;}printf("请输入要删除的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要删除的联系人不存在!\n");return;}for (i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除联系人成功!\n");
}//显示所有联系人
void ShowContact(const Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法显示!\n");return;}int i = 0;printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n","姓名","年龄","性别","电话号码","家庭住址");for (i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",pc->data[i].Name,pc->data[i].Age,pc->data[i].Sex,pc->data[i].Tele,pc->data[i].Addr);}
}//查找指定联系人
void SehContact(const Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法查找!\n");return;}char Name[NAME_MAX] = { 0 };printf("请输入要查找的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要查找的联系人不存在!\n");return;}printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话号码", "家庭住址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",pc->data[pos].Name,pc->data[pos].Age,pc->data[pos].Sex,pc->data[pos].Tele,pc->data[pos].Addr);
}
//修改指点联系人的信息
void MofContact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法修改!\n");return;}char Name[NAME_MAX] = { 0 };printf("请输入要修改的人的姓名:>");scanf("%s", Name);int pos = FindByName(pc, Name);if (pos == -1){printf("要修改的联系人不存在!\n");return;}printf("请输入联系人姓名:>");scanf("%s", pc->data[pos].Name);printf("请输入联系人年龄:>");scanf("%d", &pc->data[pos].Age);printf("请输入联系人性别:>");scanf("%s", pc->data[pos].Sex);printf("请输入联系人电话号码:>");scanf("%s", pc->data[pos].Tele);printf("请输入联系人家庭住址:>");scanf("%s", pc->data[pos].Addr);
}//对所有联系人按姓名进行排序
void SortContact(const Contact* pc)
{assert(pc);int i = 0;int j = 0;for (i = 0; i < pc->sz; i++){for (j = i; j < pc->sz; j++){if (strcmp(pc->data[i].Name, pc->data[j].Name) > 0){PeopInfo temp[] = { 0 };temp[0] = pc->data[i];pc->data[i] = pc->data[j];pc->data[j] = temp[0];}}}ShowContact(pc);//显示一下排列结果
}//销毁通讯录,释放动态内存空间
void DestoryContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->sz = 0;pc->capacity = 0;pc = NULL;printf("通讯录已销毁\n");
}

2.3contact.h实现通讯录所需要的头文件代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<errno.h>#define DEFAULT_SZ 3//初始通讯录内存放的联系人个数
#define INC_SZ 2//每次增容的空间
#define NAME_MAX  20
#define SEX_MAX  5
#define TELE_MAX 12
#define ADDR_MAX 30//创建一个结构体,用来存放人的信息
typedef struct PeopInfo
{char Name[NAME_MAX];int Age;char Sex[SEX_MAX];char Tele[TELE_MAX];char Addr[ADDR_MAX];
}PeopInfo;//创建通讯录,里面包含人的信息,通讯录原本空间大小,以及当前通讯录
//存放了多少人
typedef struct Contact
{PeopInfo* data;//不可以是数组了,如果是数组,这块空间就已经被开辟好了//不能在进行动态开辟,后续使用时变为了不可修改的左值,建议用指针int sz;//当前以存放人的信息的个数int capacity;//目前通讯录空间的容量
}Contact;//空间增容函数
void check_capacity(Contact* pc);//初始化这个通讯录,初始化为对应的值
void InitContact(Contact* pc);
//增加通讯录联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//显示所有联系人
void ShowContact(const Contact* pc);
//通过名字查找
int FindByName(const Contact* pc, char* Name);
//查找指定联系人
void SehContact(const Contact* pc);
//修改指点联系人的信息
void MofContact(Contact* pc);
//对所有联系人按姓名进行排序
void SortContact(const Contact* pc);//销毁通讯录,释放动态内存空间
void DestoryContact(Contact* pc);

3.运行结果


这就是动态通讯录完整版,大家下期再见!!!

更多推荐

C语言之动态内存管理实现通讯录(完整版)

本文发布于:2023-11-16 15:27:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1627229.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:完整版   内存管理   通讯录   语言   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!