【C语言】使用C语言实现静态、动态的通讯录(简单易懂)

我们在学习结构体之后,就可以尝试去实现通讯录的制作,如果您这边对于结构体还没有太多的认识的话,请先访问这一篇文章,会有利于接下来的学习。【自定义类型】带你走进结构体、枚举、联合_小王学代码的博客-CSDN博客

 

目录

一、通讯录

二、静态通讯录

1.完成什么功能

2.通讯录的主干怎么写?

1.结构体的实现

2.初始化通讯录

3.添加人员

3.删除指定人员

4.查找指定人员的信息

5.改变指定人员的信息

6.打印通讯录人员信息

7.排序通讯录

三、动态通讯录

1.改动结构体

2.改动初始化

3.改动添加人员函数

四、整体通讯录代码

1.静态通讯录

1.test.c文件

2.Contact.c

3.Contact.h

2.动态通讯录

1.test.c

2.Contact.c

3.Contact.h

总结


前言

通讯录是一个简单的程序,我们接下来用C语言来实现静态以及动态通讯录。我们先了解一下什么叫静态?

静态通讯录:通讯录能存储人员的大小是固定的,可能会浪费,可能会不够

动态通讯录:可以实现动态扩容,不够就扩容,比较节省时间和空间,更加方便


一、通讯录

首先我们应该知道,通讯录应该有那些功能

1.增删查改,都要有

2.关闭通讯录

3.排序通讯录中的人员

二、静态通讯录

动态比静态只需要修改一部分内容,我们先讲解一下静态通讯录如何制作

1.完成什么功能

图示:

2.通讯录的主干怎么写?

使用菜单的形式,在main函数外使用test函数,在test中使用do while和switch函数,实现通讯录的基本框架,具体代码如下。

代码演示:


//这边进行主要的通讯录流程操作

void menu() {
	printf("***********************************************\n");
	printf("******      1.add           2.del        ******\n");
	printf("******      3.search        4.change     ******\n");
	printf("******      5.show          6.sort       ******\n");
	printf("******      0.exit                       ******\n");
	printf("***********************************************\n");

}
void test() {
	int input = 0;
	int pos = 0;
	Contact pc;
	//Contact pc={0};
	//当然可以这样初始化,但是不一定后来初始化都这样,所以有InitContact()
	InitContact(&pc);
	do {
		menu();
	//打印选择菜单
		printf("请选择:>");
		scanf("%d", &input);
		switch (input) {
			case 1:
				addContact(&pc);
				break;
			case 2:
				delContact(&pc);
				break;
			case 3:
                searchContact(&pc);
				break;
			case 4:
				changeContact(&pc);
				break;
			case 5:
				showContact(&pc);
				break;
			case 6:
				sortContact(&pc);
				break;
			case 0:
				printf("退出通讯录\n");
				break;
			default:
				break;
			}
	} while (input);
}
int main()
{
	test();
	return 0;
}



3.逐步完成各项功能

初始化、增删改查,排序等功能的实现,我们放在Contact.c文件中进行实现

1.结构体的实现

代码如下:

#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 20
#define TELE_MAX 12


//下面两个define是用于动态通讯录的
#define MAX1 3	//表示第一次容积是多少
#define MAX2 2  //表示一次扩容多少




//构建通讯录所需的结构体
typedef struct PeopleInfo {
	char name[NAME_MAX];//姓名
	int age;//年龄
	char sex[NAME_MAX];//性别
	char addr[ADDR_MAX];//地址
	char tele[TELE_MAX];//电话号码
}PeopleInfo;

//这是静态通讯录  就是data这个数组是固定死的MAX
typedef struct Contact {
	PeopleInfo data[MAX];//表示存储的通讯录最大人员数
	int sz;//表示当前Contact通讯录人员个数
}Contact;

2.初始化通讯录

代码如下:

//这是静态初始化
void InitContact(Contact* pc) {
	//进行初始化的时候,我们当然可以直接
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
	//memset 函数  这样的话,从data这个数组的地址开始 sizeof(pc->data)个字节,都赋值为0
}

使用了memset内存管理函数,对pc->data数组进行初始化都为0,sz表示的是人员个数,也为0

3.添加人员

代码如下:

//静态通讯录
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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("添加完成,请继续操作\n");
//添加完一个就sz++,表示有一个人员加入通讯录中
	pc->sz++;
}

3.删除指定人员

代码如下:

void delContact(Contact* pc) {
	assert(pc);
	printf("请选择删除的目标:>");
	if (pc->sz == 0) {
		return;
	}
	//删除的话只需要找到对应的要删除的数据,比如以名字为准,先找到,然后再讲其后面的元素覆盖前面的
	int pos = searchContact(pc);
	//换位置
	if (pos == -1) {
		printf("没有查找到该成员\n");
		return;
	}
	for (int i = pos; i < pc->sz - 1; i++) {
		pc->data[i] = pc->data[i + 1];
	}

	pc->sz--;//直接--不用管换位置之后最后一个数字的问题
	printf("删除完成\n");
}

可以删除指定姓名人员,当然可以自行做出一些改善,这是比较简单易懂的通讯录。

4.查找指定人员的信息

代码如下:

int  searchContact(Contact* pc) {
	assert(pc);//断言
	char name[20];
	int pos = -1; //pos等于-1是因为 如果找不到一样的姓名,就返回-1,表示没有
	scanf("%s", name);
	//查询
	for (int i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;   //使用strcmp函数,进行比较
		}
	}
	return pos;
}

使用了strcmp函数,大家有不理解的可以去下面链接进行访问查看

【C语言进阶】带你轻松玩转字符、字符串函数_小王学代码的博客-CSDN博客

5.改变指定人员的信息

代码如下:

int  searchContact(Contact* pc) {
	assert(pc);
	char name[20];
	int pos = -1;
	scanf("%s", name);
	//查询
	for (int i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;
		}
	}
	return pos;
}

//协助查找函数被,找到被查改人员在data数组的下标位置,再进行修改
void changeContact(Contact* pc) {
	assert(pc);
	//先找到
	int pos = searchContact(pc);
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);
	printf("更改完成, 请继续操作\n");
}

协助于查找函数,找到被查改人员在data数组的下标位置,再进行修改。

6.打印通讯录人员信息

代码如下:

void showContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		return;
	}//可以有可无
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (int i = 0; i < pc->sz; i++) {
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}
	printf("打印完成\n");
}

对于printf中的 %-20s \ t 进行解释,-表示左对齐,20表示这个字符串20个位置,保持左对齐打印,\t 是字表符,是为了更加美观,使得各项数据对齐

7.排序通讯录

排序的依据有很多,我们这里是按照姓名大小排序,使用函数strcmp,实际上也可以使用qsort函数进行排序

代码如下:

void sortContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		printf("通讯录中暂无元素\n");
		return;
	}
	Contact s = { 0 };
	for (int i = 0; i < pc->sz-1; i++) {
		for (int j = i; j < pc->sz-1; j++) {
			if (strcmp(pc->data[j].name, pc->data[j + 1].name)==1) {
				s.data[j] = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = s.data[j];
			}
		}
	}
}

使用的是strcmp函数结合冒泡排序,这样还可以使用qsort函数,使用方法可以参考

【C语言进阶】指针的进阶(下)_小王学代码的博客-CSDN博客

qsort函数代码如下:

int compare(const void* e1, const void* e2) {
	return *((int*)e1) - *((int*)e2);
}
void sort(Contact*pc) {
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare);
}

三、动态通讯录

动态通讯录相较于静态通讯录主要在结构体、初始化、增加成员的时候进行了改动

1.改动结构体

代码如下:

//构建通讯录所需的结构体
typedef struct PeopleInfo {
	char name[NAME_MAX];//姓名
	int age;//年龄
	char sex[NAME_MAX];//性别
	char addr[ADDR_MAX];//地址
	char tele[TELE_MAX];//电话号码
}PeopleInfo;
//实现动态通讯录
typedef struct Contact {
	PeopleInfo *data;//表示存储的通讯录最大人员数
	int sz;//表示当前Contact通讯录人员个数
	int capacity; //表示当前容量  作为扩容的依据
}Contact;

讲data数组变成指针的形式,不再固定通讯录容量大小,可以适当扩容

2.改动初始化

使用malloc函数进行内存申请,初始化

代码如下:

//这是动态通讯录的初始化
void InitContact(Contact* pc) {
	//进行初始化的时候,我们当然可以直接
	assert(pc);//断言
	pc->sz = 0;
	PeopleInfo *ptr=(PeopleInfo*)calloc(MAX1,sizeof(PeopleInfo));
	if (ptr == NULL) {
		perror("malloc::data");
		return;
	}
	pc->data = ptr;
	pc->capacity=MAX1;
}

对data空间进行申请,MAX1 表示的是初始的时候data容量大小

3.改动添加人员函数

实现扩容机制,如果sz和capacity相等,表示人员个数和容量相等,不能再添加人员了,这个时候需要check_capacity函数进行检查是否满,并扩容

代码如下:

//动态通讯录
void check_capacity(Contact* pc) {
	PeopleInfo* ptr = (PeopleInfo*)realloc(pc->data, sizeof(PeopleInfo)*(pc->capacity+MAX2));
	if (ptr == NULL) {
		perror("check_capacity");
		return;
	}
	pc->data = ptr;
	pc->capacity = pc->capacity + MAX2;
	
}
void addContact(Contact* pc) {
	assert(pc);
	if (pc->sz == pc->capacity) {
		//使用realloc函数 进行扩容
		check_capacity(pc);
		printf("扩容完成\n");
	}
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("添加完成,请继续操作\n");
	pc->sz++;
}

使用了realloc函数进行扩容处理

四、整体通讯录代码

1.静态通讯录

都有三种文件,test.c  Contact.c  Contact.h,分别是框架,实现,头文件声明,三个作用

1.test.c文件

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"

//这边进行主要的通讯录流程操作

void menu() {
	printf("***********************************************\n");
	printf("******      1.add           2.del        ******\n");
	printf("******      3.search        4.change     ******\n");
	printf("******      5.show          6.sort       ******\n");
	printf("******      0.exit                       ******\n");
	printf("***********************************************\n");

}
void test() {
	//打印选择菜单

	int input = 0;
	int pos = 0;
	Contact pc;
	//Contact pc={0};
	//当然可以这样初始化,但是不一定后来初始化都这样,所以有InitContact()
	InitContact(&pc);
	
	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input) {
			case 1:
				addContact(&pc);
				break;
			case 2:
				delContact(&pc);
				break;
			case 3:
				pos = searchContact(&pc);
				if (pos == -1) {
					printf("没有查找到该成员\n");
				}
				else {
					printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc.data[pos].name, pc.data[pos].age, pc.data[pos].sex, pc.data[pos].addr, pc.data[pos].tele);
				}
				break;
			case 4:
				changeContact(&pc);
				break;
			case 5:
				showContact(&pc);
				break;
			case 6:
				sort(&pc);
				break;
			case 0:
				printf("退出通讯录\n");
				break;
			default:
				break;
			}
	} while (input);
}
int main()
{
	test();
	return 0;
}

2.Contact.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
//用来实现头文件的代码
//
这是静态初始化
void InitContact(Contact* pc) {
	//进行初始化的时候,我们当然可以直接
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
	//memset 函数  这样的话,从data这个数组的地址开始 sizeof(pc->data)个字节,都赋值为0
}


静态通讯录
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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("添加完成,请继续操作\n");
	pc->sz++;
}

void delContact(Contact* pc) {
	assert(pc);
	printf("请选择删除的目标:>");
	if (pc->sz == 0) {
		return;
	}
	//删除的话只需要找到对应的要删除的数据,比如以名字为准,先找到,然后再讲其后面的元素覆盖前面的
	int pos = searchContact(pc);
	//换位置
	if (pos == -1) {
		printf("没有查找到该成员\n");
		return;
	}
	for (int i = pos; i < pc->sz - 1; i++) {
		pc->data[i] = pc->data[i + 1];
	}

	pc->sz--;//直接--不用管换位置之后最后一个数字的问题
	printf("删除完成\n");
}


int  searchContact(Contact* pc) {
	assert(pc);
	char name[20];
	int pos = -1;
	scanf("%s", name);
	//查询
	for (int i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;
		}
	}
	
	return pos;
}

void showContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		return;
	}//可以有可无
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (int i = 0; i < pc->sz; i++) {
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}
	printf("打印完成\n");
}



void changeContact(Contact* pc) {
	assert(pc);
	//先找到
	int pos = searchContact(pc);
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);
	printf("更改完成, 请继续操作\n");
}


void sortContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		printf("通讯录中暂无元素\n");
		return;
	}
	Contact s;
	InitContact(&s);
	for (int i = 0; i < pc->sz-1; i++) {
		for (int j = 0; j < pc->sz-1-i; j++) {
			if (strcmp(pc->data[j].name, pc->data[j + 1].name)==1) {
				s.data[j] = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = s.data[j];
			}
		}
	}
}

int compare(const void* e1, const void* e2) {
	return *((int*)e1) - *((int*)e2);
}
void sort(Contact*pc) {
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare);
}

3.Contact.h

#define _CRT_SECURE_NO_WARNINGS

//Contact 实现通讯录 头文件
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<malloc.h>
#include<stdlib.h>
#include<search.h>

#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 20
#define TELE_MAX 12


//下面两个define是用于动态通讯录的
#define MAX1 3	//表示第一次容积是多少
#define MAX2 2  //表示一次扩容多少


//构建通讯录所需的结构体
typedef struct PeopleInfo {
	char name[NAME_MAX];//姓名
	int age;//年龄
	char sex[NAME_MAX];//性别
	char addr[ADDR_MAX];//地址
	char tele[TELE_MAX];//电话号码
}PeopleInfo;

//这是静态通讯录  就是data这个数组是固定死的MAX
typedef struct Contact {
	PeopleInfo data[MAX];//表示存储的通讯录最大人员数
	int sz;//表示当前Contact通讯录人员个数
}Contact;


//初始化通讯录
void InitContact(Contact* pc);
//添加通讯录的信息
void addContact(Contact* pc);
//删除通讯录中的信息
void delContact(Contact* pc);
//查找通讯录成员信息
int searchContact(Contact* pc);
//打印
void showContact(Contact* pc);
//改变指定元素
void changeContact(Contact* pc);
//排序,按照名字排序
void sortContact(Contact* pc);

2.动态通讯录

1.test.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"

//这边进行主要的通讯录流程操作

void menu() {
	printf("***********************************************\n");
	printf("******      1.add           2.del        ******\n");
	printf("******      3.search        4.change     ******\n");
	printf("******      5.show          6.sort       ******\n");
	printf("******      0.exit                       ******\n");
	printf("***********************************************\n");

}
void test() {
	//打印选择菜单

	int input = 0;
	int pos = 0;
	Contact pc;
	//Contact pc={0};
	//当然可以这样初始化,但是不一定后来初始化都这样,所以有InitContact()
	InitContact(&pc);
	
	do {
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input) {
			case 1:
				addContact(&pc);
				break;
			case 2:
				delContact(&pc);
				break;
			case 3:
				pos = searchContact(&pc);
				if (pos == -1) {
					printf("没有查找到该成员\n");
				}
				else {
					printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc.data[pos].name, pc.data[pos].age, pc.data[pos].sex, pc.data[pos].addr, pc.data[pos].tele);
				}
				break;
			case 4:
				changeContact(&pc);
				break;
			case 5:
				showContact(&pc);
				break;
			case 6:
				sort(&pc);
				break;
			case 0:
				printf("退出通讯录\n");
                free(pc.data);
				break;
			default:
				break;
			}
	} while (input);
}
int main()
{
	test();
	return 0;
}

2.Contact.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
//用来实现头文件的代码
//


//这是动态通讯录的初始化
void InitContact(Contact* pc) {
	//进行初始化的时候,我们当然可以直接
	assert(pc);//断言
	pc->sz = 0;
	PeopleInfo *ptr=(PeopleInfo*)calloc(MAX1,sizeof(PeopleInfo));
	if (ptr == NULL) {
		perror("malloc::data");
		return;
	}
	pc->data = ptr;
	pc->capacity=MAX1;
}

//动态通讯录
void check_capacity(Contact* pc) {
	PeopleInfo* ptr = (PeopleInfo*)realloc(pc->data, sizeof(PeopleInfo)*(pc->capacity+MAX2));
	if (ptr == NULL) {
		perror("check_capacity");
		return;
	}
	pc->data = ptr;
	pc->capacity = pc->capacity + MAX2;
	
}
void addContact(Contact* pc) {
	assert(pc);
	if (pc->sz == pc->capacity) {
		//使用realloc函数 进行扩容
		check_capacity(pc);
		printf("扩容完成\n");
	}
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->sz].tele);
	printf("添加完成,请继续操作\n");
	pc->sz++;
}
void delContact(Contact* pc) {
	assert(pc);
	printf("请选择删除的目标:>");
	if (pc->sz == 0) {
		return;
	}
	//删除的话只需要找到对应的要删除的数据,比如以名字为准,先找到,然后再讲其后面的元素覆盖前面的
	int pos = searchContact(pc);
	//换位置
	if (pos == -1) {
		printf("没有查找到该成员\n");
		return;
	}
	for (int i = pos; i < pc->sz - 1; i++) {
		pc->data[i] = pc->data[i + 1];
	}

	pc->sz--;//直接--不用管换位置之后最后一个数字的问题
	printf("删除完成\n");
}


int  searchContact(Contact* pc) {
	assert(pc);
	char name[20];
	int pos = -1;
	scanf("%s", name);
	//查询
	for (int i = 0; i < pc->sz; i++) {
		if (strcmp(pc->data[i].name, name) == 0) {
			pos = i;
		}
	}
	
	return pos;
}

void showContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		return;
	}//可以有可无
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (int i = 0; i < pc->sz; i++) {
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
	}
	printf("打印完成\n");
}



void changeContact(Contact* pc) {
	assert(pc);
	//先找到
	int pos = searchContact(pc);
	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].addr);
	printf("请输入电话:>");
	scanf("%s", pc->data[pos].tele);
	printf("更改完成, 请继续操作\n");
}


void sortContact(Contact* pc) {
	assert(pc);
	if (pc->sz == 0) {
		printf("通讯录中暂无元素\n");
		return;
	}
	Contact s;
	InitContact(&s);
	for (int i = 0; i < pc->sz-1; i++) {
		for (int j = 0; j < pc->sz-1-i; j++) {
			if (strcmp(pc->data[j].name, pc->data[j + 1].name)==1) {
				s.data[j] = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = s.data[j];
			}
		}
	}
}

int compare(const void* e1, const void* e2) {
	return *((int*)e1) - *((int*)e2);
}
void sort(Contact*pc) {
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare);
}

3.Contact.h

#define _CRT_SECURE_NO_WARNINGS

//Contact 实现通讯录 头文件
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<malloc.h>
#include<stdlib.h>
#include<search.h>

#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 20
#define TELE_MAX 12


//下面两个define是用于动态通讯录的
#define MAX1 3	//表示第一次容积是多少
#define MAX2 2  //表示一次扩容多少

//构建通讯录所需的结构体
typedef struct PeopleInfo {
	char name[NAME_MAX];//姓名
	int age;//年龄
	char sex[NAME_MAX];//性别
	char addr[ADDR_MAX];//地址
	char tele[TELE_MAX];//电话号码
}PeopleInfo;

//实现动态通讯录
typedef struct Contact {
	PeopleInfo *data;//表示存储的通讯录最大人员数
	int sz;//表示当前Contact通讯录人员个数
	int capacity; //表示当前容量  作为扩容的依据
}Contact;

//初始化通讯录
void InitContact(Contact* pc);
//添加通讯录的信息
void addContact(Contact* pc);
//删除通讯录中的信息
void delContact(Contact* pc);
//查找通讯录成员信息
int searchContact(Contact* pc);
//打印
void showContact(Contact* pc);
//改变指定元素
void changeContact(Contact* pc);
//排序,按照名字排序
void sortContact(Contact* pc);

总结

静态通讯录和动态通讯录都是比较简单好实现的,静态通讯录是固定的数组的形式储存成员,不确定成员个数的情况下,可能会浪费空间,也可能不够用。但是动态通讯录通过不断扩容,更好的解决了这个空间的事情,不会造成太多浪费。

动态,是依靠malloc、free、calloc、realloc这些函数进行申请空间,进行维护不断扩容的,下一章节,我们来一起细致的去讲解一下这四种函数的使用和区别

猜你喜欢

转载自blog.csdn.net/qq_63319459/article/details/128686169