C语言—基于realloc函数实现的通讯录

news/2024/11/18 20:20:58/

专栏:C语言
个人主页:HaiFan.
专栏简介:本专栏主要更新一些C语言的基础知识,也会实现一些小游戏和通讯录,学时管理系统之类的,有兴趣的朋友可以关注一下。

动态通讯录

  • 前言
  • 一、ContactInit初始化
  • 二、ContactCheckCapacity检查通讯录内存是否够用
  • 三、ContactDistory释放动态开辟的空间
  • 四、源码

前言

什么是动态通讯录,就是在静态的基础上改进了一下,不在使用数组,而是使用指针和动态内存开辟的函数,当空间不够的时候,便进行增容。

一、ContactInit初始化

void ContactInit(Contact* ps)//初始化
{ps->size = 0;ps->capacity = 0;ps->data = NULL;
}

初始化的时候,就不再使用memset函数了,因为是指针,所以要先把size,capacity置为0,data置为空。

二、ContactCheckCapacity检查通讯录内存是否够用

void ContactCheckCapacity(Contact* pc)//检查通讯录内存是否够用
{if (pc->size == pc->capacity){int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2;Cont* tmp = (Cont*)realloc(pc->data, newcapacity * sizeof(Cont) * 4);if (tmp == NULL){perror("realloc");exit(-1);}pc->data = tmp;pc->capacity = newcapacity;printf("增容成功\n");}
}

当size == capacity的时候,就证明通讯录的内存不够了,需要增容,在这里直接用的realloc函数进行增容。

三、ContactDistory释放动态开辟的空间

void ContactDistory(Contact* pc)//释放动态开辟的空间
{free(pc->data);pc->data = NULL;pc->capacity = pc->size = 0;
}

使用动态内存分配的函数了之后,在退出通讯录的时候,不要忘记把开辟的空间给销毁,不然会造成内存泄漏。

四、源码

.h文件


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>#define MAX_SIZE 1000
#define MAX_NAME 5
#define MAX_TELE 100
#define MAX_SEX 5
#define MAX_ADDRESS 50typedef struct Contact
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char address[MAX_ADDRESS];
}Cont;typedef struct C
{Cont *data;int size;int capacity;
}Contact;void ContactInit(Contact* ps);//初始化void ContactAdd(Contact* ps);//添加联系人void ContactDel(Contact* ps);//删除联系人void ContactShow(Contact* ps);//展示联系人void ContactFind(Contact* ps);//查找联系人void ContactSort(Contact* ps);//给联系人排序void ContactModify(Contact* ps);//修改联系人void ContactCheckCapacity(Contact* pc);//检查通讯录内存是否够用void ContactDistory(Contact* pc);//释放动态开辟的空间

.c文件

#include "contact.h"void ContactInit(Contact* ps)//初始化
{ps->size = 0;ps->capacity = 0;ps->data = NULL;
}void ContactCheckCapacity(Contact* pc)//检查通讯录内存是否够用
{if (pc->size == pc->capacity){int newcapacity = pc->capacity == 0 ? 4 : pc->capacity * 2;Cont* tmp = (Cont*)realloc(pc->data, newcapacity * sizeof(Cont) * 4);if (tmp == NULL){perror("realloc");exit(-1);}pc->data = tmp;pc->capacity = newcapacity;printf("增容成功\n");}
}void ContactDistory(Contact* pc)//释放动态开辟的空间
{free(pc->data);pc->data = NULL;pc->capacity = pc->size = 0;
}void ContactAdd(Contact* ps)//添加联系人
{assert(ps);ContactCheckCapacity(ps);//增加一个人的信息printf("请输入名字:>");scanf("%s", ps->data[ps->size].name);printf("请输入年龄:>");scanf("%d", &(ps->data[ps->size].age));printf("请输入性别:>");scanf("%s", ps->data[ps->size].sex);printf("请输入地址:>");scanf("%s", ps->data[ps->size].address);printf("请输入电话:>");scanf("%s", ps->data[ps->size].tele);ps->size++;
}int FindByName(Contact* ps,const char *str)
{int pos = 0;while (pos < ps->size){if (strcmp(ps->data[pos].name, str) == 0){return pos;}pos++;}return -1;
}void ContactFind(Contact* ps)//查找联系人
{assert(ps);printf("请输入要查找的联系人的姓名:");char na[MAX_NAME];scanf("%s", na);int ret = FindByName(ps, na);if (ret == -1){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", ps->data[ret].name,ps->data[ret].age,ps->data[ret].sex,ps->data[ret].tele,ps->data[ret].address);return ;
}void ContactDel(Contact* ps)//删除联系人
{assert(ps);printf("请输入要删除的联系人的姓名:");char na[MAX_NAME];scanf("%s", na);int ret = FindByName(ps, na);if (ret == -1){printf("信息错误,列表无该联系人\n");return;}else{for (int i = ret; i < ps->size - 1; i++){ps->data[i] = ps->data[i + 1];}}ps->size--;return;
}void ContactShow(Contact* ps)//展示联系人
{int i = 0;printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < ps->size; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ps->data[i].name,ps->data[i].age,ps->data[i].sex,ps->data[i].tele,ps->data[i].address);}
}int CmpByName(const void* a,const void* b)
{return strcmp(((Contact*)a)->data->name, ((Contact*)b)->data->name);
}
//return strcmp(((S*)a)->name, ((S*)b)->name);
void ContactSort(Contact* ps)//给联系人排序
{assert(ps);qsort(ps->data[0].name, ps->size, sizeof ps->data[0], CmpByName);printf("排序成功\n");return;
}void ContactModify(Contact* ps)//修改联系人
{assert(ps);printf("请输入要修改的联系人的姓名:");char na[MAX_NAME];scanf("%s", na);int ret = FindByName(ps, na);if (ret == -1){printf("查无此人,无法修改\n");return;}printf("请输入名字:>");scanf("%s", ps->data[ret].name);printf("请输入年龄:>");scanf("%d", &(ps->data[ret].age));printf("请输入性别:>");scanf("%s", ps->data[ret].sex);printf("请输入地址:>");scanf("%s", ps->data[ret].address);printf("请输入电话:>");scanf("%s", ps->data[ret].tele);printf("修改成功\n");return;
}

test.c文件

#include "contact.h"void menu()
{printf("************************************\n");printf("******  1. 添加    2. 删除    ******\n");printf("******  3. 查找    4. 修改    ******\n");printf("******  5. 展示    6. 排序    ******\n");printf("******  7.退出                ******\n");printf("************************************\n");
}enum Function
{ADD = 1,DEL,FIND,MODIFY,SHOW,SORT,EXIT
};int main()
{int input = 0;Contact con;ContactInit(&con);do{menu();printf("请输入选项:");scanf("%d", &input);switch (input){case ADD:ContactAdd(&con);break;case DEL:ContactDel(&con);break;case FIND:ContactFind(&con);break;case MODIFY:ContactModify(&con);break;case SHOW:ContactShow(&con);break;case SORT:ContactSort(&con);break;case EXIT:ContactDistory(&con);printf("退出\n");break;default:printf("输入错误,请重新出入\n");break;}} while (input != 7);return 0;
}

http://www.ppmy.cn/news/12804.html

相关文章

JavaScript高级 ES6类

ES6类1. 认识class定义类2. 类和构造函数的异同3. 类的构造函数4. 类的实例方法5. 类的访问器方法6. 类的静态方法7. ES6类的继承8. super关键字9. 继承内置类10. 类的混入11. ES5 ES6 class 代码转换12. ES5 ES6 extends 代码转换13. JavaScript中的多态1. 认识class定义类 我…

Java中的LinkedList

文章目录前言一、LinkedList的使用1.1 什么是LinkedList1.2 LinkedList的使用1.2.1 LinkedList的构造1.2.2 LinkedList的其他常用方法介绍1.2.3 LinkedList的遍历二、LinkedList的模拟实现三、ArrayList和LinkedList的区别总结前言 上一节中我们讲解了Java中的链表&#xff0c…

Vue生命周期,总也学不会,所以我详细整理了一下

今天&#xff0c;我和大家一起来对vue生命周期做一个整理和思考&#xff0c;希望有缘人看到我的年度整理和思考&#xff0c;如果觉得靠谱呢&#xff0c;就交个朋友&#xff0c;如果觉得我整理的不足&#xff0c;就请指出&#xff0c;让我们一起进步&#xff0c;让我们2023年能共…

【5】KubeSphere部署应用 | MySQL

目录 1、部署的架构 2、KubeSphere几个主要的模块 3、部署MySQL 【1】先创建MySQL的配置文件 【2】创建存储卷 【3】部署有状态服务 【4】查看创建的服务 【5】创建一个服务可以在集群外可以访问 1、部署的架构 2、KubeSphere几个主要的模块 KubeSphere的工作负载相当于k8s里…

无线倾角报警仪测试键、设置键、调整键的作用

按键&#xff1a;测试键、设置键、调整键测试键&#xff1a;a. 在除了进行设置之外的任何时候&#xff0c;长按此键可以模仿报警时的状态&#xff08;灯闪、机内蜂鸣音、继电器吸合&#xff09;&#xff0c;松开按键则恢复到初始状态。可以作为用户在安装报警仪之后的功能测试&…

(十)汇编语言——CALL和RET指令

&#xff08;十&#xff09;汇编语言——CALL和RET指令 文章目录&#xff08;十&#xff09;汇编语言——CALL和RET指令CALL指令功能寄存器内存段间转移返回指令retretf实例MUL指令模块化程序设计寄存器内存单元栈寄存器冲突问题方法相信大家肯定在C语言里面接触过函数这个概念…

【7】SCI易中期刊推荐——计算机 | 人工智能(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

DRG在医保支付中的应用

DRG在医保支付中的应用 前言 DRG全称是“按疾病诊断相关分组”&#xff0c;它根据病人的年龄、性别、住院天数、临床诊断、病症、手术、疾病严重程度、合并症与并发症、转归等因素把病人分入不同的诊断相关组。DRG与医保支付结合&#xff0c;形成DRGs-PPS制度&#xff08;Diag…