c语言小课设--通讯录(动态内存管理)

前言:

在没学动态内存管理之前,我们用的结构体,数组等都是静态分配内存的,也就是说数组的长度是固定的,但是这并不满足我们的实际需求,所以在通讯录项目里面我就用到了动态内存分布。简单来说,就是当需要储存的联系人数据太多了的时候,我们就可以扩大一点空间用来存放新的数据,也就是说实现了要多少,就开辟多少的空间。

项目介绍:

该项目实现一个通讯录功能,除了能根据具体需求扩大空间之外,也实现了最基本基本的增删查改等功能,并在退出通讯录时销毁创造的空间,从而不造成内存泄露。

另外,这个项目由三部分组成,函数功能的实现在Contact.c源文件中,各种头文件、函数等声明则由文件Contact.h来实现,最后测试在源文件test.c文件中进行。

一、teat.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"


enum Option {
	Exit,
	add,
	modify,
	del,
	search,
	show,
	sort
};

void menu() {
	printf("************************\n");
	printf("**1.添加    2.修改******\n");
	printf("**3.删除    4.搜索******\n");
	printf("**5.展示    6.排序******\n");
	printf("**0.退出          ******\n");
	printf("************************\n");
}


int main() {
	int input = 0;
	Contacts Con;
	Init(&Con);
	do {
		menu();
		printf("请输入你的选择--》\n");
		scanf("%d", &input);
		switch (input) {
		case add://添加
			Add_Peo(&Con);
			break;
		case modify://修改
			Modify_Peo(&Con);
			break;
		case del:
			Del_Peo(&Con);
			break;
		case search:
			Sear_Peo(&Con); 
			break;
		case show:
			Show_Peo(&Con);
			break;
		case sort:
			Sort_Peo(&Con);
			break;
		case Exit:
			Destory_Contacts(&Con);
			printf("退出通讯录\n");
			break;
		default:
			printf("你的输入有误!\n");
			break;

		}
	} while (input != 0);
	return 0;
}

二、Contact.h头文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include

#define name_max 20
#define sex_max 5
#define tele_max 12
#define addr_max 20
#define num_max 100
#define default_cap 3

typedef struct PeoInfo {
	char name[name_max];
	char sex[sex_max];
	char tele[tele_max];
	int age;
}PeoInfo;
//静态通讯录版本
//typedef struct Contacts {
//	PeoInfo data[num_max];
//	int sz;
//}Contacts;
//动态版本
typedef struct Contacts {
	PeoInfo *data;//存放数据
	int sz;//记录当前联系人的数量
	int cap;//当前通讯录的容量
}Contacts;



//初始化通讯录
void Init(Contacts* Con);
//添加功能
void Add_Peo(Contacts* Con);
//修改功能
void Modify_Peo(Contacts* Con);
//删除联系人
void Del_Peo(Contacts* Con);
//展示联系人
void Show_Peo(Contacts* Con);
//查询联系人
void Sear_Peo(Contacts* Con);
//排序
void Sort_Peo(Contacts* Con);

三、Contact.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"

// 自定义比较剂,按名字字典序排序

int cmp(void* e1,void *e2) {
	//printf("%s %s\n", (, ((struct PeoInfo*)e2)->name);
	return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}

//初始化通讯录
void Init(Contacts* Con) {
	assert(Con);
	Con->sz = 0;
	Con->cap = default_cap;
	Con->data = calloc(Con->cap, sizeof(PeoInfo));
	if (Con->data == NULL) {
		printf("初始化失败\n");
		return;
	}
}

//void Init(Contacts* Con) {
//	assert(Con);
//	Con->sz = 0;
//	memset(Con->data, 0, sizeof(Con->data));
//}

//增加容量
void check_cap(Contacts* Con) {
	
		PeoInfo* ptr = realloc(Con->data, (Con->cap + 2) * sizeof(PeoInfo));
		if (ptr != NULL) {
			Con->data = ptr;
			Con->cap += 2;
			printf("增容成功\n");
		}
		else {
			perror("AddContacts->realloc");
			return;
		}
	
}
//添加功能
//动态版本
void Add_Peo(Contacts* Con) {
	assert(Con);
	if (Con->sz == Con->cap) {
		check_cap(Con);
	}
	printf("请输入添加人的姓名\n");
	scanf("%s", Con->data[Con->sz].name);
	printf("请输入添加人的年龄\n");
	scanf("%d", &Con->data[Con->sz].age);
	printf("请输入添加人的性别\n");
	scanf("%s", Con->data[Con->sz].sex);
	printf("请输入添加人的号码\n");
	scanf("%s", Con->data[Con->sz].tele);
	Con->sz++;
	return;
}
//静态版本
//void Add_Peo(Contacts* Con) {
//	assert(Con);
//	if (Con->sz == num_max) {
//		printf("通讯录已满\n");
//		return;
//	}
//	else {
//		printf("请输入添加人的姓名\n");
//		scanf("%s", Con->data[Con->sz].name);
//		printf("请输入添加人的年龄\n");
//		scanf("%d", &Con->data[Con->sz].age);
//		printf("请输入添加人的性别\n");
//		scanf("%s", Con->data[Con->sz].sex);
//		printf("请输入添加人的号码\n");
//		scanf("%s", Con->data[Con->sz].tele);
//		Con->sz++;
//		return;
//	}
//}
//按名字查找
int find_name(Contacts* Con,char *tager) {
	assert(Con);
	for (int i = 0; i < Con->sz; i++) {
		if (strcmp(Con->data[i].name, tager)==0) {
			return i;
		}
	}
	return -1;
	
	
}
//修改功能
void Modify_Peo(Contacts* Con) {
	assert(Con);
	char name[name_max] = {0};
	while (1) {
		printf("请输入你要修改联系人的名字\n");
		scanf("%s", name);
		int k = find_name(Con, name);
		if ( k!= -1&&k>=0&&ksz) {
			printf("请重新输入修改的姓名\n");
			scanf("%s", Con->data[k].name);
			printf("请重新输入修改的的年龄\n");
			scanf("%d",&Con->data[k].age);
			printf("请重新输入修改的的性别\n");
			scanf("%s", Con->data[k].sex);
			printf("请重新输入修改的的号码\n");
			scanf("%s", Con->data[k].tele);
			printf("修改成功!\n");
			break;
		}
		else {
			printf("查无此人\n");
			break;
		}
	}

}
//删除联系人
void Del_Peo(Contacts* Con) {
	assert(Con);
	if (Con->sz == 0) {
		printf("该通讯录还没有联系人\n");
		return;
	}
	printf("请输入你要删除联系人的姓名\n");
	char name1[name_max] = { 0 };
	scanf("%s", name1);
	int k = find_name(Con, name1);
	if (k != -1&&k>=0&&ksz) {
		for (int i = k; i < Con->sz - 1; i++) {
			Con->data[i] = Con->data[i + 1];
		}
		Con->sz--;
		printf("删除成功\n");
	}
	else {
        printf("查无此人\n");
		return;
	}
}
//展示联系人
void Show_Peo(Contacts* Con) {
	assert(Con);
	if (Con->sz == 0) {
		printf("没有联系人\n");
		return;
	}
	printf("-------------------------------------------------\n");
	printf("|%-20s |%-5s |%-5s |%-12s| \n","姓名","年龄","性别","号码");
	printf("-------------------------------------------------\n");
	for (int i = 0; i < Con->sz; i++) {
		printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[i].name, Con->data[i].age, Con->data[i].sex, Con->data[i].tele);
		if (i != (Con->sz - 1)) {
			printf("-------------------------------------------------\n");
		}
	}
	printf("-------------------------------------------------\n");
}
//查询联系人
void Sear_Peo(Contacts* Con) {
	assert(Con);
	char tager[name_max] = { 0 };
	if (Con->sz == 0) {
		printf("没有联系人\n");
		return;
	}
	printf("请输入你要查找的名字\n");
	scanf("%s", tager);
	int k = find_name(Con, tager);
	if (k != -1 && k >= 0 && k < Con->sz) {
		printf("-------------------------------------------------\n");
		printf("|%-20s |%-5s |%-5s |%-12s| \n", "姓名", "年龄", "性别", "号码");
		printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[k].name, Con->data[k].age, Con->data[k].sex, Con->data[k].tele);
		printf("-------------------------------------------------\n");
	}
	else {
		printf("查无此人\n");
		return;
	}
}
//排序
void Sort_Peo(Contacts* Con) {
	assert(Con);
	qsort(Con->data, Con->sz, sizeof(struct PeoInfo), cmp);
	printf("排序成功\n");
	return;
}
//销毁通讯录
void Destory_Contacts(Contacts* Con) {
	free(Con->data);
	Con->data = NULL;
	Con->cap = 0;
	Con->sz = 0;
}

好了以上就是整个项目的源代码了,是不是很简单呢?感兴趣的可以自己去试试哦!

你可能感兴趣的:(c语言必备知识点,c语言,开发语言)