通讯录2.0(动态)

简介: 通讯录 动态

目录

前提操作

具体改进

1.初始化

2.扩容空间

3.增加联系人

4.销毁空间

完整代码

utili.h

contact.h

contact.cpp

contactMain.cpp


前言

上篇博客我们已经用简单静态完成了通讯录,但是静态通讯录开辟的空间小了不够用,大了又占空间,机动性比较差。

简易通讯录(C语言)

因此,这里我们用动态开辟空间对通讯录进行一个升级。

前提操作

要改为动态通讯录,我们需要先对通讯录结构进行改进。

旧:

typedef struct Contact
{
  PersonInfo cont[MAX_CONTACT_SIZE];
  size_t     capacity;
  size_t     size;
}Contact;

image.gif

新:

typedef struct Contact
{
  //PersonInfo cont[MAX_CONTACT_SIZE]; //静态开辟
  PersonInfo *cont;   //动态开辟
  size_t     capacity;
  size_t     size;
}Contact;

image.gif

具体改进

1.初始化

既然我们采用动态开辟,那么我们初次开辟就不需要开辟那么大的空间了,开辟两个就够了,后面不够了依次翻倍开辟空间。

#define DEFAULT_CONTACT_SIZE 2

image.gif

void InitContact(Contact *pcont)
{
  assert(pcont != NULL);
  pcont->cont = (PersonInfo*)malloc(sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  memset(pcont->cont, 0, sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  pcont->capacity = DEFAULT_CONTACT_SIZE;
  pcont->size = 0;
}

image.gif

2.扩容空间

这里就是但我们增加联系人的时候空间不够就使用realloc重新扩容空间,当然我们要检测是否扩容成功(本地内存是否够)。

static bool _Inc(Contact *pcont)
{
  PersonInfo *new_cont = (PersonInfo *)realloc(pcont->cont, sizeof(PersonInfo)*(pcont->capacity * 2));
  if (new_cont == NULL)
  {
    printf("内存不足,扩容失败......\n");
    return false;
  }
  pcont->cont = new_cont;
  pcont->capacity *= 2;
  return true;
}

image.gif

3.增加联系人

有了上面内存的扩充,那我们也需要对增加联系人这块进行改进。

void AddContact(Contact *pcont)
{
  assert(pcont != NULL);
  if (IsFullContact(pcont) && !_Inc(pcont))
  {
    printf("通讯录空间已满,不能新增信息.....\n");
    return;
  }
  printf("姓名:>");
  scanf("%s", pcont->cont[pcont->size].name);
  printf("性别:>");
  scanf("%s", pcont->cont[pcont->size].sex);
  printf("年龄:>");
  scanf("%d", &pcont->cont[pcont->size].age);
  printf("电话:>");
  scanf("%s", pcont->cont[pcont->size].tel);
  printf("住址:>");
  scanf("%s", pcont->cont[pcont->size].address);
  pcont->size++;
  printf("增加完成.......\n");
}

image.gif

4.销毁空间

这里我们采用动态开辟,那我们使用完成后就要对开辟的空间进行释放,否则会造成内存泄漏,时间久了,会使我们电脑的空间不足。

void DestroyContact(Contact *pcont)
{
  assert(pcont != NULL);
  free(pcont->cont);
  pcont->cont = NULL;
  pcont->capacity = pcont->size = 0;
}

image.gif

下来我们展示完整代码

完整代码

utili.h

#ifndef _UTILI_H_
#define _UTILI_H_
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdbool.h>
#include<malloc.h>
#endif /* _UTILI_H_ */

image.gif

contact.h

#ifndef _CONTACT_H_
#define _CONTACT_H_
#include"utili.h"
enum { QUIT, ADD, DEL, FIND, MODIFY, SHOW, CLEAR, SORT };
#define MAX_NAME_SIZE 10
#define MAX_SEX_SIZE   3
#define MAX_TEL_SIZE   12
#define MAX_ADDR_SIZE 128
//#define MAX_CONTACT_SIZE 2
#define DEFAULT_CONTACT_SIZE 2
//定义通讯录人员信息
typedef struct PersonInfo
{
  char name[MAX_NAME_SIZE];
  char sex[MAX_SEX_SIZE];
  int age;
  char tel[MAX_TEL_SIZE];
  char address[MAX_ADDR_SIZE];
}PersonInfo;
//定义通讯录结构
typedef struct Contact
{
  //PersonInfo cont[MAX_CONTACT_SIZE]; //静态开辟
  PersonInfo *cont;   //动态开辟
  size_t     capacity;
  size_t     size;
}Contact;
/////////////////////////////////////////////////////////////
bool IsFullContact(Contact *pcont);
void InitContact(Contact *pcont);
void AddContact(Contact *pcont);
void ShowContact(Contact *pcont);
int  FindContact(Contact *pcont);
void DelContact(Contact *pcont);
void ModifyContact(Contact *pcont);
void SortContact(Contact *pcont);
void ClearContact(Contact *pcont);
void DestroyContact(Contact *pcont);
#endif /* _UTILI_H_ */

image.gif

contact.cpp

#include"contact.h"
void InitContact(Contact *pcont)
{
  assert(pcont != NULL);
  pcont->cont = (PersonInfo*)malloc(sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  memset(pcont->cont, 0, sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE);
  pcont->capacity = DEFAULT_CONTACT_SIZE;
  pcont->size = 0;
}
static bool _Inc(Contact *pcont)
{
  PersonInfo *new_cont = (PersonInfo *)realloc(pcont->cont, sizeof(PersonInfo)*(pcont->capacity * 2));
  if (new_cont == NULL)
  {
    printf("内存不足,扩容失败......\n");
    return false;
  }
  pcont->cont = new_cont;
  pcont->capacity *= 2;
  return true;
}
bool IsFullContact(Contact *pcont)
{
  assert(pcont != NULL);
  return pcont->size >= pcont->capacity;
}
void AddContact(Contact *pcont)
{
  assert(pcont != NULL);
  if (IsFullContact(pcont) && !_Inc(pcont))
  {
    printf("通讯录空间已满,不能新增信息.....\n");
    return;
  }
  printf("姓名:>");
  scanf("%s", pcont->cont[pcont->size].name);
  printf("性别:>");
  scanf("%s", pcont->cont[pcont->size].sex);
  printf("年龄:>");
  scanf("%d", &pcont->cont[pcont->size].age);
  printf("电话:>");
  scanf("%s", pcont->cont[pcont->size].tel);
  printf("住址:>");
  scanf("%s", pcont->cont[pcont->size].address);
  pcont->size++;
  printf("增加完成.......\n");
}
void ShowContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i<pcont->size; ++i)
  {
    printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
      pcont->cont[i].sex,
      pcont->cont[i].age,
      pcont->cont[i].tel,
      pcont->cont[i].address);
  }
}
int  FindContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要查找的姓名:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址");
  for (int i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
    {
      printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name,
        pcont->cont[i].sex,
        pcont->cont[i].age,
        pcont->cont[i].tel,
        pcont->cont[i].address);
      return i;
    }
  }
  return -1;
}
void DelContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要删除的名字:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  int i;
  for (i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
      break;
  }
  if (i >= pcont->size)
  {
    printf("要删除的信息不存在.....\n");
    return;
  }
  for (int k = i; k<pcont->size - 1; ++k)
    pcont->cont[k] = pcont->cont[k + 1];
  pcont->size--;
  printf("删除完成.......\n");
}
void ModifyContact(Contact *pcont)
{
  assert(pcont != NULL);
  printf("请输入要修改的名字:>");
  char name[MAX_NAME_SIZE] = { 0 };
  scanf("%s", name);
  int i;
  for (i = 0; i<pcont->size; ++i)
  {
    if (strcmp(name, pcont->cont[i].name) == 0)
      break;
  }
  if (i >= pcont->size)
  {
    printf("要修改的信息不存在.....\n");
    return;
  }
  printf("你想修改什么信息(1-姓名 2-性别 3-年龄 4-电话 5-住址)\n");
  int select;
  scanf("%d", &select);
  if (select == 1)
  {
    printf("请输入要修改姓名:>");
    scanf("%s", pcont->cont[i].name);
  }
  else if (select == 2)
  {
    printf("请输入要修改性别:>");
    scanf("%s", pcont->cont[i].sex);
  }
  else if (select == 3)
  {
    printf("请输入要修改住址:>");
    scanf("%d", &pcont->cont[i].age);
  }
  else if (select == 4)
  {
    printf("请输入要修改电话:>");
    scanf("%s", pcont->cont[i].tel);
  }
  else if (select == 5)
  {
    printf("请输入要修改性别:>");
    scanf("%s", pcont->cont[i].address);
  }
  printf("修改完成.......\n");
}
void SortContact(Contact *pcont)
{
  assert(pcont != NULL);
  for (int i = 0; i<pcont->size - 1; ++i)
  {
    for (int j = 0; j<pcont->size - 1 - i; ++j)
    {
      if (strcmp(pcont->cont[j].name, pcont->cont[j + 1].name) > 0)
      {
        PersonInfo tmp = pcont->cont[j];
        pcont->cont[j] = pcont->cont[j + 1];
        pcont->cont[j + 1] = tmp;
      }
    }
  }
  printf("排序完成.......\n");
}
void ClearContact(Contact *pcont)
{
  assert(pcont != NULL);
  pcont->size = 0;
  printf("清除完成.......\n");
}
void DestroyContact(Contact *pcont)
{
  assert(pcont != NULL);
  free(pcont->cont);
  pcont->cont = NULL;
  pcont->capacity = pcont->size = 0;
}

image.gif

contactMain.cpp

#include"contact.h"
void Menu()
{
  printf("****************通 讯 录****************\n");
  printf("*   [1] Add                 [2] Del    *\n");
  printf("*   [3] Find                [4] Modify *\n");
  printf("*   [5] Show                [6] Clear  *\n");
  printf("*   [7] Sort                [0] Quit   *\n");
  printf("****************************************\n");
}
void main()
{
  Contact cont;
  InitContact(&cont);
  int select = 1;
  while (select)
  {
    Menu();
    printf("请选择:>");
    scanf("%d", &select);
    if (select == QUIT)
      break;
    switch (select)
    {
    case ADD:
      AddContact(&cont);
      break;
    case DEL:
      DelContact(&cont);
      break;
    case FIND:
      FindContact(&cont);
      break;
    case MODIFY:
      ModifyContact(&cont);
      break;
    case SHOW:
      ShowContact(&cont);
      break;
    case CLEAR:
      ClearContact(&cont);
      break;
    case SORT:
      SortContact(&cont);  //qsort
      break;
    }
  }
  DestroyContact(&cont);
}

image.gif

相关文章
|
3月前
|
存储
通讯录(动态实现与文件优化版)
通讯录(动态实现与文件优化版)
40 1
|
10月前
【动态通讯录】
【动态通讯录】
36 0
|
10月前
【文件版&动态版通讯录】
【文件版&动态版通讯录】
26 0
|
10月前
|
存储
【静态通讯录】
【静态通讯录】
22 0
|
10月前
|
存储 C++ iOS开发
|
存储
通讯录(静态版)
通讯录(静态版)
|
C语言
C/【静态通讯录】
C/【静态通讯录】
进阶版通讯录(动态版)
进阶版通讯录(动态版)
动态版通讯录
来了朋友们,今天给大家分享的是动态版本的通讯录。这个动态版本的通讯录较静态版本的通讯录的好处是,动态版本的通讯录对空间的浪费较少,并且可以随时增加空间,使用更加灵活。其实基本逻辑是跟静态版本的通讯录是一样的。