【C语言】通讯录2.0 (动态增长版)

简介: 通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。文章的一二三章均于上一篇相同,可以直接看第四章改造内容。此通讯录是基于通讯录1.0(静态版)的基础上进行改进,请先看系列文章第一篇,再看本篇博客。****** 有需要源代码,见文章末尾 ******

前言

通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。

文章的一二三章均于上一篇相同,可以直接看第四章改造内容。

此通讯录是基于通讯录1.0(静态版)的基础上进行改进,请先看系列文章第一篇,再看本篇博客。

****** 有需要源代码,见文章末尾 ******


系列文章目录

第一篇:【C语言】通讯录1.0 (静态版)

第二篇:【C语言】通讯录2.0 (动态增长版)

第三篇:【C语言】通讯录3.0 (文件存储版)


文章目录

前言

系列文章目录

一、什么是通讯录

二、静态版、动态增长版和文件存储版的区别

1. 静态版

2. 动态增长版

3. 文件存储版

三、通讯录模块组成(图文)

1. 通讯录文件构成

2. 通讯录个人信息

3. 通讯录功能模块

四、如何改造通讯录1.0(改造目标)

1. 改造目标

2. 需要的改造部分

五、如何改进(代码演示)

1. 通讯录结构模块

2. 通讯录初始化函数

3. 增加联系人函数

4. 添加内存释放函数

六、所有文件代码

1. 头文件

2. 函数文件

3. 测试逻辑文件

总结


一、什么是通讯录

通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。通讯录可以帮助人们管理自己的联系人,让人们更轻松地与他人保持联系。通讯录可以在手机、电脑、笔记本等设备上保存,也可以在云端储存和同步,方便用户随时查看和更新联系人信息。


二、静态版、动态增长版和文件存储版的区别

C语言静态版、动态增长版和文件存储版的区别如下:


1. 静态版

静态版:在程序编译时就确定了内存大小,程序运行期间内存大小不会发生变化,因此对于需要处理大量数据或者不确定数据大小的情况不适用。


2. 动态增长版

动态增长版:可以在程序运行期间根据需要动态增加内存大小,因此适用于处理不确定数据大小的情况。但是动态增长的内存需要手动释放,否则会导致内存泄漏。


3. 文件存储版

文件存储版:将数据存储在文件中,可以持久保存数据并随时读取。但是存储在文件中的数据需要进行IO操作,因此相比于内存操作来说效率较低。此外,文件存储版不适用于需要频繁修改的数据。


三、通讯录模块组成(图文)


1. 通讯录文件构成

image.png

2. 通讯录个人信息

image.png

3. 通讯录功能模块

image.png


四、如何改造通讯录1.0(改造目标)


1. 改造目标

  1. 通讯录的空间不是固定的,大小是可以调整的
  2. 默认能放3个人的信息,如果不够,就每次增加2个人的信息


2. 需要的改造部分

image.png


五、如何改进(代码演示)


1. 通讯录结构模块

  • 将通讯录的存储方式改成动态增长,用指针来调用
  • 需要增加通讯录的现有的容量值
//动态版typedefstructContact{
PeoInfo*data;
intsz;
intcapacity;
}Contact;

2. 通讯录初始化函数

  • 本来初始化通讯录是使用内存函数memset来实现
  • 现在由malloc动态内存函数来动态开辟内存
  • 初始化设置容量为3个联系人的容量
//动态版voidInitContact(Contact*pc)
{
assert(pc);
pc->data= (PeoInfo*)malloc(3*sizeof(PeoInfo));
if (pc->data==NULL)
    {
perror("InitContact");
return;
    }
pc->capacity=3;
pc->sz=0;
}

3. 增加联系人函数

  • 本来前提是判断是否通讯录已满,现在改为判断当通讯录容量满的时候增加动态内存
  • 需要写一个函数来判断容量是否已满
  • 当容量已满的时候。使用realloc动态内存函数,来增加动态内存
//动态版voidAddContact(Contact*pc)
{
assert(pc);       //断言if (determine(pc) ==0)
    {
return;
    }
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++;    //通讯录加1printf("联系人增加成功\n");
}
//判断内存是否已满函数intdetermine(Contact*pc)
{
assert(pc);
if (pc->capacity==pc->sz)
    {
PeoInfo*ptr= (PeoInfo*)realloc(pc->data, (pc->capacity+2) *sizeof(PeoInfo));
if (ptr==NULL)
        {
perror("determine");
return0;
        }
else        {
pc->capacity+=2;
pc->data=ptr;
printf("增容成功\n");
return1;
        }
    }
return1;
}

4. 添加内存释放函数

  • 在通讯录菜单栏,选择退出 0 通讯录时要释放内存
  • 也要将容量和size 归零
  • 需要写一个函数来进行这个操作
voidDestroyContact(Contact*pc)
{
free(pc->data);
pc->data=NULL;
pc->capacity=0;
pc->sz;
}


六、所有文件代码


1. 头文件

#pragma once#include<stdio.h>#include<assert.h>#include<string.h>#include<stdlib.h>#define MAX 100#define NAME 10#define SEX  5#define TELE 12#define ADDR 30//使用枚举  定义选择   enumOPTION{
EXIT,//0ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT};
//个人信息类型声明typedefstructPeoInfo{
charname[NAME];
intage;
charsex[SEX];
chartele[TELE];
charaddr[ADDR];
}PeoInfo;
//建立通讯录//静态版//typedef struct Contact//{//  PeoInfo data[MAX]; //通讯录数量//  int sz;             //目前通讯录内的人数 //}Contact;//动态版typedefstructContact{
PeoInfo*data;
intsz;
intcapacity;
}Contact;
//函数声明//初始化通讯录voidInitContact(Contact*pc);
//增加联系人voidAddContact(Contact*pc);
//显示所有联系人的信息voidShowContact(constContact*pc);
//删除指定联系人voidDelContact(Contact*pc);
//查找指定联系人voidSearchContact(constContact*pc);
//修改指定联系人voidModifyContact(Contact*pc);
//释放内存voidDestroyContact(Contact*pc);

2. 函数文件

#define _CRT_SECURE_NO_WARNINGS 1#include "addbook.h"intdetermine(Contact*pc)
{
assert(pc);
if (pc->capacity==pc->sz)
    {
PeoInfo*ptr= (PeoInfo*)realloc(pc->data, (pc->capacity+2) *sizeof(PeoInfo));
if (ptr==NULL)
        {
perror("determine");
return0;
        }
else        {
pc->capacity+=2;
pc->data=ptr;
printf("增容成功\n");
return1;
        }
    }
return1;
}
//静态版//void InitContact(Contact* pc)//{//  assert(pc);   //断言//  memset(pc->data, 0, sizeof(pc->data));   //内存函数  data初始化为0  //  pc->sz = 0;//}//动态版voidInitContact(Contact*pc)
{
assert(pc);
pc->data= (PeoInfo*)malloc(3*sizeof(PeoInfo));
if (pc->data==NULL)
    {
perror("InitContact");
return;
    }
pc->capacity=3;
pc->sz=0;
}
//动态版voidAddContact(Contact*pc)
{
assert(pc);       //断言if (determine(pc) ==0)
    {
return;
    }
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++;    //通讯录加1printf("联系人增加成功\n");
}
//静态版//void AddContact(Contact* pc)//{//  assert(pc);       //断言//  if (pc->sz == MAX)         //如果通讯录已经满了  则返回//  {//      printf("通讯录已满,无法添加\n");//      return;//  }//  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//  printf("联系人增加成功\n");//}//搜索名字找通讯录函数staticintFindname(constContact*pc, charna[])
{
inti=0;
assert(pc&&na);
for (i=0; i<pc->sz; i++)
    {
if (strcmp(pc->data[i].name, na) ==0)
        {
returni;
        }
    }
return-1;
}
voidDelContact(Contact*pc)
{
if (pc->sz==0)
    {
printf("通讯录为空\n");
return;
    }
charname[NAME] = { 0 };
assert(pc);
//输入要查找的联系人名字printf("请输入要查找的名字:>");
scanf("%s", &name);
//找到要查找的联系人intdel=Findname(pc, name);
//删除坐标位子的联系人 ,将后面的联系人进行代替其位置if (del==-1)
    {
printf("找不到,此人不存在\n");
return;
    }
else    {
inti=0;
for (i=del; i<pc->sz; i++)
        {
pc->data[i] =pc->data[i+1];
        }
pc->sz--;
    }
printf("成功删除联系人\n");
}
voidShowContact(constContact*pc)
{
assert(pc);
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
inti=0;
for (i=0; i<pc->sz; i++)
    {
printf("%-10s\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);
    }
printf("通讯录展示完毕\n");
}
voidSearchContact(constContact*pc)
{
if (pc->sz==0)
    {
printf("通讯录为空\n");
return;
    }
charname[NAME] = { 0 };
assert(pc);
//输入要查找的联系人名字printf("请输入要查找的名字:>");
scanf("%s", &name);
//找到要查找的联系人inti=Findname(pc, name);
if (i==-1)
    {
printf("找不到,此人不存在\n");
return;
    }
else    {
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-10s\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);
    }
printf("成功找到联系人\n");
}
voidModifyContact(Contact*pc)
{
assert(pc);
charname[NAME] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", &name);
intmod=Findname(pc, name);
if (mod==-1)
    {
printf("找不到,不存在\n");
return;
    }
else    {
printf("请输入姓名:>");
scanf("%s", pc->data[mod].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[mod].age));
printf("请输入性别:>");
scanf("%s", pc->data[mod].sex);
printf("请输入电话:>");
scanf("%s", pc->data[mod].tele);
printf("请输入地址:>");
scanf("%s", pc->data[mod].addr);
printf("联系人修改成功\n");
    }
}
voidDestroyContact(Contact*pc)
{
free(pc->data);
pc->data=NULL;
pc->capacity=0;
pc->sz;
}

3. 测试逻辑文件

#define _CRT_SECURE_NO_WARNINGS 1#include"addbook.h"voidmenu()
{
printf("********************************\n");
printf("***** 1. ADD     2. DEL    *****\n");
printf("***** 3. SEARCH  4. MODIFY *****\n");
printf("***** 5. SHOW    6. SORT   *****\n");
printf("***** 0. EXIT              *****\n");
printf("********************************\n");
}
voidtest()
{
intinput=0;
Contactcon;
InitContact(&con);
do    {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
        {
caseADD:
AddContact(&con);
break;
caseDEL:
DelContact(&con);
break;
caseSEARCH:
SearchContact(&con);
break;
caseMODIFY:
ModifyContact(&con);
break;
caseSHOW:
ShowContact(&con);
break;
caseSORT:
printf("功能待开发\n");
break;
caseEXIT:
DestroyContact(&con);
printf("成功退出通讯录\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
        }
    } while (input);
}
intmain()
{
test();
return0;
}

总结

本期博客,是通讯录2.0(动态增长版),是对前面所学知识进行复习,编写通讯录时有助于理解自定义类型和动态内存管理的学习和了解,后期会对现在的通讯录进行更新!!!


如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。

目录
相关文章
|
1月前
|
存储 C语言
探索C语言数据结构:利用顺序表完成通讯录的实现
本文介绍了如何使用C语言中的顺序表数据结构实现一个简单的通讯录,包括初始化、添加、删除、查找和保存联系人信息的操作,以及自定义结构体用于存储联系人详细信息。
22 2
|
1月前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
6月前
|
C语言
C语言——通讯录系统—基于 VS2022
C语言——通讯录系统—基于 VS2022
|
3月前
|
存储 搜索推荐 算法
【C语言】C语言—通讯录管理系统(源码)【独一无二】
【C语言】C语言—通讯录管理系统(源码)【独一无二】
|
3月前
|
存储 数据可视化 C语言
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
|
5月前
|
机器学习/深度学习 搜索推荐 程序员
C语言实现个人通讯录(功能优化)-2
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-2
|
5月前
|
存储 C语言 索引
C语言实现个人通讯录(功能优化)-1
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-1
|
5月前
|
C语言
C语言学习记录——通讯录(静态内存)
C语言学习记录——通讯录(静态内存)
32 2
|
6月前
|
存储 C语言
C语言实现通讯录
C语言实现通讯录
42 2
|
6月前
|
存储 C语言
C语言实验-动态顺序表实现简易通讯录(二)
在这个C语言实验中,你将实现一个简单的通讯录,它使用动态顺序表来存储联系人信息。
51 2