动态内存管理改造简易通讯录(下)

简介: 动态内存管理改造简易通讯录(下)

改造退出通讯录

动态开辟空间在程序结束时都要释放出去,防止有不可预料的结果产生,所以退出通讯录也要稍微 改造一下,静态直接退出即可不需要函数,所以我们直接看动态的退出通讯录。

void DestoryContact(Contact* pc)
{
  free(pc->data);//释放动态内存空间
  pc->data = NULL;//赋为空指针
  pc->sz = 0;//释放完人数当然为0
  pc->capacity = 0;//释放完,通讯录容量也自然为0
}

这个十分简单,释放掉动态空间的地址,然后把该指针赋值为空指针,然后sz为零,capacity为零即可。

改造后的全部代码

为大家奉上完整的代码,方便参考调试。

test.c

#define  _CRT_SECURE_NO_WARNINGS
#include"contact.h"
enum Option
{
  EXIT,
  ADD,
  DEL,
  SEARCH,
  MODIFY,
  SHOW,
  SORT,
  EMPTY
};
void menu();
int main()
{
  int input = 0;
  Contact con;
  InitContact(&con);
  do
  {
    menu();
    printf("请输入你想选择的操作:");
    scanf("%d", &input);
    switch (input)
    {
    case EXIT:
      DestoryContact(&con);
      printf("退出通讯录成功");
      break;
    case ADD:
      ADDContact(&con);
      break;
    case DEL:
      DELContact(&con);
      break;
    case SEARCH:
      SearchContact(&con);;
      break;
    case MODIFY:
      ModifyContact(&con);
      break;
    case SHOW:
      SHOWContact(&con);
      break;
    case SORT:
      SortContact(&con);
      break;
    case EMPTY:
      InitContact(&con);
      printf("清空通讯录成功\n");
      break;
    default:
      printf("输入错误\n");
      break;
    }
  } while (input);
  return 0;
}

contact.c

#define  _CRT_SECURE_NO_WARNINGS
#include "contact.h"
void menu()
{
  printf("*****************************\n");
  printf("*****0.EXIT****1.ADD*********\n");
  printf("*****2.DEL*****3.SEARCH******\n");
  printf("*****4.MODIFY**5.SHOW********\n");
  printf("*****6.SORT****7.EMPTY*******\n");
}
void InitContact(Contact* pc)
{
  assert(pc);
  pc->sz = 0;
  pc->capacity = DEFAULT_SZ;
  pc->data = calloc(pc->capacity,sizeof(PeoInfo));
  if (pc->data == NULL)
  {
    perror("InitContact->calloc");
    return;
  }
}
//void CheckCapacity(Contact* pc)
//{
//  if (pc->sz == pc->capacity)
//  {
//    PeoInfo* ptr = realloc(pc->data, (pc->capacity + DEFAULT_INC) * sizeof(PeoInfo));
//    if (ptr != NULL)
//    {
//      pc->sz = ptr;
//      pc->capacity += DEFAULT_INC;
//      printf("增加联系人空间成功\n");
//    }
//    else
//    {
//      perror("ADDContact->realloc");
//    }
//  }
//}
void ADDContact(Contact* pc)
{
  assert(pc);
  if (pc->sz == pc->capacity)
  {
    PeoInfo* ptr = realloc(pc->data, (pc->capacity + DEFAULT_INC) * sizeof(PeoInfo));
    if (ptr != NULL)
    {
      pc->data = ptr;
      pc->capacity += DEFAULT_INC;
      printf("增加联系人空间成功\n");
    }
    else
    {
      perror("ADDContact->realloc");
    }
  }
  //增加信息
  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++;
  printf("添加联系人成功!\n");
}
void SHOWContact(const Contact* pc)
{
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,无需打印\n");
    return;
  }
  int i = 0;
  //名字  年龄  性别  电话    地址
  //xxx   xxx  xxx  xxx     xxx
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  for (i = 0; i < pc->sz; i++)
  {
    //打印每个人的信息
    printf("%-20s%-10d%-10s%-12s%-30s\n",
      pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
  }
}
int FindByName(Contact* pc, char* name)
{
  assert(pc);
  int i = 0;
  for (i = 0; i < pc->sz; i++)
  {
    if (strcmp(pc->data[i].name, name) == 0)
    {
      return i;
    }
  }
  return -1;
}
void DELContact(Contact* pc)
{
  char name[NAME_MAX];
  assert(pc);
  if (pc->sz == 0)
  {
    printf("通讯录为空,不可删除\n");
    return;
  }
  printf("请输入你想删除的联系人:");
  scanf("%s", name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在,无法删除!\n");
    return;
  }
  int i = 0;
  for (i = ret; i < pc->sz - 1; i++)
  {
    pc->data[i] = pc->data[i + 1];
  }
  pc->sz--;
  printf("删除该联系人成功!\n");
}
void SearchContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想查找的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("%-20s%-10s%-10s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
  printf("%-20s%-10d%-10s%-12s%-30s\n",
    pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele, pc->data[ret].addr);
}
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX];
  printf("请输入想修改的联系人");
  scanf("%s", &name);
  int ret = FindByName(pc, name);
  if (ret == -1)
  {
    printf("该联系人不存在!\n");
    return;
  }
  printf("请输入姓名:");
  scanf("%s", pc->data[ret].name);
  printf("请输入年龄:");
  scanf("%d", &(pc->data[ret].age));
  printf("请输入性别:");
  scanf("%s", pc->data[ret].sex);
  printf("请输入电话号码:");
  scanf("%s", pc->data[ret].tele);
  printf("请输入住址:");
  scanf("%s", pc->data[ret].addr);
  printf("修改联系人成功!\n");
}
int compare_name(const void* base, const void* src)
{
  return strcmp(((PeoInfo*)base)->name, ((PeoInfo*)src)->name);
}
int compare_age(const void* base, const void* src)
{
  return (((PeoInfo*)base)->age - ((PeoInfo*)src)->age);
}
void SortContact(Contact* pc)
{
  int ret = 0;
  printf("1按名字排序,2按年龄排序\n");
  scanf("%d", &ret);
  if (ret == 1)
  {
    qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_name);
    SHOWContact(pc);
    printf("名字排序成功\n");
  }
  else if (ret == 2)
  {
    qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_age);
    SHOWContact(pc);
    printf("年龄排序成功\n");
  }
  else
  {
    printf("选择错误,返回操作");
  }
}
void DestoryContact(Contact* pc)
{
  free(pc->data);
  pc->data = NULL;
  pc->sz = 0;
  pc->capacity = 0;
}

contact.h

#define  _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 10
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100
#define DEFAULT_SZ 3
#define DEFAULT_INC 2
typedef struct PeoInfo
{
  char name[NAME_MAX];
  int age;
  char sex[SEX_MAX];
  char tele[TELE_MAX];
  char addr[ADDR_MAX];
}PeoInfo;
//typedef struct Contact
//{
//  PeoInfo data[MAX];//存放成员数据
//  int sz;//记录当前通讯录人数
//}Contact;
typedef struct Contact
{
  PeoInfo* data;//存放成员数据
  int sz;//记录当前通讯录人数
  int capacity;//记录当前通讯录容量
}Contact;
void menu();
void InitContact(Contact* pc);
void ADDContact(Contact* pc);
void SHOWContact(const Contact* pc);
void DELContact(Contact* pc);
void SearchContact(Contact* pc);
void ModifyContact(Contact* pc);
void SortContact(Contact* pc);
void DestoryContact(Contact* pc);

最后各位看客老爷万福金安。

目录
相关文章
|
3天前
|
C语言
【C语言】动态内存管理基础知识——动态通讯录,如何实现通讯录容量的动态化
动态内存管理的函数有:malloc,calloc,ralloc,free,本文讲解动态内存函数和使用,如何进行动态内存管理,实现通讯录联系人容量的动态化,对常见动态内存错误进行总结。
38 0
|
3天前
|
程序员 C语言 C++
详解动态内存管理!
详解动态内存管理!
|
3天前
动态内存管理
动态内存管理
37 1
|
10月前
动态内存管理(二)
动态内存管理
35 0
|
5月前
|
编译器
动态内存管理(1)
动态内存管理(1)
36 0
|
5月前
|
程序员 编译器 C语言
动态内存管理总结
动态内存管理总结
38 0
|
5月前
|
程序员 C语言 C++
动态内存管理-2
动态内存管理
21 0
|
6月前
|
存储
动态内存管理改造简易通讯录(上)
动态内存管理改造简易通讯录
14 0
|
6月前
|
程序员 编译器 C语言
动态内存管理(上)
动态内存管理(上)
26 0
|
7月前
|
存储 编译器 C语言
C++动态内存管理+模板
C++动态内存管理+模板