【C语言】动态通讯录

该文章介绍了如何将静态通讯录转变为动态版本,通过使用`malloc`和`realloc`在需要时分配和扩展内存。主要功能包括初始化、添加、删除、查找、修改、显示和排序联系人,同时在添加新联系人时会检查容量并自动扩容。此外,还提供了销毁通讯录以释放内存的函数。
摘要由CSDN通过智能技术生成

今天来改进一下静态版本的通讯录,让通讯录的内存空间可以随大小变化;

一、测试部分

测试部分的改动不大,主要的改动还是在函数实现的部分和声明部分;

			void menu()
			{
				printf("******      1.Add         2.Del     ***********\n");
				printf("******      3.Search      4.Modify  ***********\n");
				printf("******      5.Show        6.Sort    ***********\n");
				printf("******             0.exit           ***********\n");
				printf("***********************************************\n");
			}
			
			enum Option
			{
				EXIT,
				ADD,
				DEL,
				SEARCH,
				MODIFY,
				SHOW,
				SORT,
			};
			
			int main()
			{
				int input = 0;
				Contact con;
				InitContact(&con);
				do
				{
					menu();
					printf("请选择:\n");
					scanf("%d", &input);
					switch (input)
					{
					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 EXIT:
						DestoryContact(&con);
						printf("退出通讯录\n");
						break;
					default:
						printf("输入错误。请重新输入:\n");
						break;
					}
				} while (input);
				return 0;
			}

二、 函数的实现部分

函数的实现部分主要改变了:

  1. 通讯录初始化的方式,改用malloc开辟空间

  2. 添加联系人的方式,当空间容量不够,使用realloc拓展空间

  3. 退出通讯录,需要使用free释放空间以及置空;

     		//动态版本初始化通讯录
     		void InitContact(Contact* pc)
     		{
     			pc->data = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo));
     			assert(pc->data);
     			pc->sz = 0;
     			pc->Capacity = DEFAULT_SZ;
     		}
     		
     		//查找函数
     		//加static修饰这个函数是为了这个函数只能在这个.c文件内用,出了这个文件就用不了
     		static int FindByName(Contact* pc, char* name)
     		{
     			int i = 0;
     			for (i = 0; i < pc->sz; i++)
     			{
     				//如果找到了就返回这个下标
     				if (strcmp(pc->data[i].name, name) == 0)
     				{
     					return i;
     				}
     			}
     			return -1;
     		}
     		
     		
     		//打印通讯录
     		void ShowContact(Contact* pc)
     		{
     			int i = 0;
     			//打印标题
     			printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
     			for (i = 0; i < pc->sz; i++)
     			{
     				printf("%-10s %-4d %-5s %-12s %-30s\n",
     					pc->data[i].name,
     					pc->data[i].age,
     					pc->data[i].sex,
     					pc->data[i].tele,
     					pc->data[i].addr);
     			}
     			printf("\n");
     		}
     		
     		
     		//检查Capacity的容量是否满
     		void CheakCapacity(Contact* pc)
     		{
     			if (pc->Capacity == pc->sz)
     			{
     				PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->Capacity + INC_SZ) * sizeof(PeoInfo));
     				assert(ptr);
     		
     				pc->Capacity += INC_SZ;
     				pc->data = ptr;
     		
     				printf("增容成功!\n");
     			}
     		}
     		
     		//增加指定联系人
     		void AddContact(Contact* pc)
     		{
     			CheakCapacity(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);
     		
     			//添加完sz的长度++
     			pc->sz++;
     			printf("添加成功\n");
     		}
     		
     		
     		//删除指定联系人
     		void DelContact(Contact* pc)
     		{
     			//通讯录为空
     			if (pc->sz == 0)
     			{
     				printf("通讯录为空,无法删除\n");
     				return;
     			}
     			//不为空,删除
     			char name[MAX_NAME];
     			printf("请输入名字:");
     			scanf("%s", &name);
     			//一个查找函数,因为查找功能重复,所以写一个查找函数更好
     			int pos = FindByName(pc, name);
     			if (pos == -1)
     			{
     				printf("要删除的不存在\n");
     				return;
     			}
     			int i = 0;
     			//将后面的数据往前挪
     			for (i = pos; i < pc->sz; i++)
     			{
     				pc->data[i] = pc->data[i + 1];
     			}
     			//挪完后有效数据的长度--
     			pc->sz--;
     			printf("删除成功\n");
     		}
     		
     		
     		//在通讯录查找指定的人
     		void SearchContact(Contact* pc)
     		{
     			printf("请输入要查找的人的名字:");
     			char name[MAX_NAME];
     			scanf("%s", &name);
     			int pos = FindByName(pc, name);
     			if (pos == -1)
     			{
     				printf("要查找的人不存在\n");
     				return;
     			}
     			printf("查找成功!\n\n");
     			printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
     			//找到了打印数据
     			printf("%-10s %-4d %-5s %-12s %-30s\n",
     				pc->data[pos].name,
     				pc->data[pos].age,
     				pc->data[pos].sex,
     				pc->data[pos].tele,
     				pc->data[pos].addr);
     			printf("\n");
     		}
     		
     		
     		//修改通讯录的数据
     		void ModifyContact(Contact* pc)
     		{
     			printf("请输入需要修改的人的名字:");
     			char name[MAX_NAME];
     			scanf("%s", &name);
     			int pos = FindByName(pc, name);
     			if (pos == -1)
     			{
     				printf("不存在此人\n");
     				return;
     			}
     			//找到了就修改pos下标的数据
     			printf("请重新输入TA的数据\n");
     			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);
     			printf("修改成功\n");
     		}
     		
     		
     		//按照名字排序
     		int cmp_by_name(void* e1, void* e2)
     		{
     			//强转成PeoInfo*类型
     			return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
     		}
     		
     		void SortContact(Contact* pc)
     		{
     			printf("按照名字排列:\n");
     			qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);
     			printf("排序成功\n\n");
     		}
     		
     		
     		//销毁通讯录
     		void DestoryContact(Contact* pc)
     		{
     			free(pc->data);
     			pc->data = NULL;
     			pc->Capacity = 0;
     			pc->sz = 0;
     			printf("释放内存\n");
     		}
    

三、函数的声明部分

			#include <stdio.h>
			#include <string.h>
			#include <stdlib.h>
			#include <assert.h>
			
			#define MAX_NAME 20
			#define MAX_SEX 5
			#define MAX_TELE 12
			#define MAX_ADDR 30
			
			//定义开始默认通讯录开辟空间的大小
			#define DEFAULT_SZ 3
			//定义每次
			#define INC_SZ 2
			
			//表示一个人的信息
			typedef struct PeoInfo
			{
				char name[MAX_NAME];
				int age;
				char sex[MAX_SEX];
				char tele[MAX_TELE];
				char addr[MAX_ADDR];
			}PeoInfo;
			
			//定义另外一个结构体,存放第一个结构体的数据和记录通讯录中有效信息的个数
			typedef struct Contact
			{
				PeoInfo* data;//data指向了存放数据的空间
				int sz;//记录通讯录中有效信息的个数
				int Capacity;//通讯录当前的容量
			}Contact;
			
			
			//初始化通讯录
			void InitContact(Contact* pc);
			
			//打印通讯录
			void ShowContact(Contact* pc);
			
			//增加指定联系人
			void AddContact(Contact* pc);
			
			//删除指定联系人
			void DelContact(Contact* pc);
			
			//在通讯录查找指定的人
			void SearchContact(Contact* pc);
			
			//修改通讯录的数据
			void ModifyContact(Contact* pc);
			
			//排序通讯录
			void SortContact(Contact* pc);
			
			//销毁通讯录
			void DestoryContact(Contact *pc);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值