动态通讯录实现(C语言)

这篇具有很好参考价值的文章主要介绍了动态通讯录实现(C语言)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

一:单个节点的设计和主逻辑 

结点设计

主逻辑

二:接口实现

(1)生成一个新的结点

(2)增加信息

(3)打印信息

(4)查找 

(5)删除信息

(6)修改信息

(7)排序

 插入排序

快速排序

(8)已有数据读取

(9)更新数据录入

三:全部代码

contact.h(声明)

contact.c(接口)

test.c(主逻辑)


前言:

本文使用的存储结构是不带哨兵位链表,还包含了文件操作(读取和录入),有类似课程设计的同学可能需要(完整代码在最后)。

链表(知道基础概念,清楚形参实参关系的可以不看):

https://blog.csdn.net/2301_76269963/article/details/129586021?spm=1001.2014.3001.5502


一:单个节点的设计和主逻辑 

结点设计

需求:一个人要包含姓名、年龄、性别、电话号码、地址这些信息,把这些信息封装成一个结构体。

动态通讯录实现(C语言)


要让每个人的数据链接成一个整体,节点除了个人信息之外还要保存下个结点的地址

动态通讯录实现(C语言)


主逻辑

(1)每次开始都从文件中读取数据

(2)通讯录的功能包括:①增加数据

                                     ②依据名字删除数据

                                     ③依据名字查找数据

                                     ④依据名字修改数据

                                     ⑤依据年龄排序数据

                                     ⑥打印数据

(3)退出后重新录入数据


二:接口实现

(1)生成一个新的结点

//生成一个新节点
Node* BuyNewNode()
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	if (NewNode == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	NewNode->next = NULL;

	printf("请输入名字:");
	scanf("%s", NewNode->data.name);
	printf("请输入年龄:");
	scanf("%d", &NewNode->data.age);
	printf("请输入性别:");
	scanf("%s", NewNode->data.sex);
	printf("请输入电话:");
	scanf("%s", NewNode->data.tele);
	printf("请输入地址:");
	scanf("%s", NewNode->data.addr);

	return NewNode;
}

(2)增加信息

//增加信息,可能要更改头指针,传二级指针修改一级指针
void AddContact(Node** pphead)
{
	//生成新节点
	Node* NewNode = BuyNewNode();
	//单独处理空的情况
	if (*pphead == NULL)
	{
		*pphead = NewNode;
		return;
	}
	else
	{
		NewNode->next = *pphead;
		*pphead = NewNode;
	}
}

图解:

动态通讯录实现(C语言)

(3)打印信息

//打印信息
void PrintContact(Node* phead)
{
	//注意打印格式,加-表示字符左对齐,数字表示最小字符数(不足补空格)
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
	while (phead != NULL)
	{
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n", 
			   phead->data.name,phead->data.age,
			   phead->data.sex,phead->data.tele,phead->data.addr);
		//迭代
		phead = phead->next;
	}
}

(4)查找 

注意:后续的删除和修改都需要用到查找,为增强代码复用性,查找函数返回结点的地址,如果未查找到就返回空。

//查找,第二个参数为名字字符串首地址
Node* FindContact(Node* phead,char* name)
{
	//遍历链表
	while (phead)
	{
		//strcmp()函数用于字符串比较,相同返回0,否则返回非0值
		if (strcmp(phead->data.name, name) == 0)
		{
			return phead;
		}
		phead = phead->next;
	}
	//没找到返回空
	return NULL;
}

(5)删除信息

先查找,找到待删除结点地址,如果待删除结点为头节点,需要更新头指针

否则就需要找到待删除结点的前一个结点,前一个结点指针域指向待删除结点的下一个结点,然后释放待删除结点。

//删除信息,可能要更改头指针,传二级指针修改一级指针
void DelContact(Node** pphead)
{
	//信息为空不能删除
	assert(*pphead != NULL);
	
	//查找
	char name[max_name];
	printf("请输入要删除联系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(*pphead,name);
	if (pos == NULL)
	{
		printf("查找失败\n");
		return;
	}

	//如果pos是第一个节点
	if (pos == *pphead)
	{
		//找到下一个
		Node* NEXT = pos->next;
		free(pos);
		*pphead = NEXT;
	}
	else
	{
		//找到前一个
		Node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
	printf("删除成功\n");
}

图解:

动态通讯录实现(C语言)

(6)修改信息

先查找到目标结点,然后进行修改。

//修改信息
void ModifyContact(Node* phead)
{
	//查找
	char name[max_name];
	printf("请输入要修改联系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(phead, name);
	if (pos == NULL)
	{
		printf("查找失败\n");
		return;
	}
	else
	{
		printf("找到了,进行修改\n");
		printf("请输入名字:");
		scanf("%s", pos->data.name);
		printf("请输入年龄:");
		scanf("%d", &pos->data.age);
		printf("请输入性别:");
		scanf("%s", pos->data.sex);
		printf("请输入电话:");
		scanf("%s", pos->data.tele);
		printf("请输入地址:");
		scanf("%s", pos->data.addr);
	}
}

(7)排序

这里给两种实现方式,第一种使用插入排序(方便理解)第二种使用快速排序(效率更快,有空间消耗,代码量更多)


 插入排序

插入排序的核心思想是:将一个未排序的元素插入到已排序的子序列中,使得插入后依然保持有序。具体实现时,我们可以从第二个元素开始,将其与前面已排序序列的元素比较,找到其正确的插入位置,然后插入即可。在插入过程中,需要将已排序序列中比该元素大的元素后移,为该元素腾出插入位置(看一遍就可以看代码和图解)。

//交换数据
void swap(Node* p1, Node* p2)
{
	struct PepInfo tmp = p1->data;
	p1->data = p2->data;
	p2->data = tmp;
}

//进行排序
void sort(Node* phead)
{
	//空不排序
	assert(phead != NULL);

	Node* begin = phead;
	Node* end = phead->next;
	while (end)
	{
		while (begin != end)
		{
			if (begin->data.age > end->data.age)
			{
				swap(begin,end);
			}
			begin = begin->next;
		}
        //更新
		end = end->next;
		begin = phead;
	}
}

图解:

动态通讯录实现(C语言)


快速排序

这里就不展开讲快速排序的思想了,也不建议用快速排序,一般通讯录这样的数据量用插入排序就足够了,感兴趣的同学可以看链接。

快速排序链接:https://blog.csdn.net/2301_76269963/article/details/130473353?spm=1001.2014.3001.5502

先将链表中的数据拷贝到数组中,对数组进行排序,再把数组数据拷贝回链表。

//交换数据
void swap(PepInfo* p1, PepInfo* p2)
{
	PepInfo tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

// 三数取中
int GetMidIndex(PepInfo* a, int left, int right)
{
	int midi = left + (right - left) / 2;

	if (a[midi].age > a[right].age)
	{
		if (a[midi].age < a[left].age)
			return midi;
		else if (a[right].age > a[left].age)
			return right;
		else
			return left;
	}
	else    //a[right] > a[mid]
	{
		if (a[midi].age > a[left].age)
			return midi;
		else if (a[left].age < a[right].age)
			return left;
		else
			return right;
	}
}

//前后指针法
int partion3(PepInfo* a, int left, int right)
{
	int midi = GetMidIndex(a, left, right);
	swap(&a[midi], &a[left]);

	int keyi = left;
	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
		//++prev和cur相等,无效交换,不换
		if (a[cur].age < a[keyi].age && ++prev != cur)
		{
			swap(&a[prev], &a[cur]);
		}
		cur++;
	}
	swap(&a[keyi], &a[prev]);
	return prev;
}

//快速排序
void QuickSort(PepInfo* a, int left, int right)
{
	//如果left>right,区间不存在
	//left==right,只有一个元素,可以看成是有序的
	if (left >= right)
	{
		return;
	}
	else
	{
		//单次排序
		int keyi = partion3(a, left, right);
		//分成左右区间,排序左右区间
		QuickSort(a, left, keyi - 1);
		QuickSort(a, keyi + 1, right);
	}
}

// 链表快速排序函数
void sortList(Node* phead) 
{
	// 处理空或单节点链表的情况
	if (!phead || !phead->next)
	{
		return;
	}

	//求链表长度
	int len = 0;
	Node* cur = phead;
	while (cur) 
	{
		len++;
		cur = cur->next;
	}

	// 将链表转换为数组
	PepInfo* arr = malloc(len * sizeof(PepInfo));
	if (arr == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	cur = phead;
	for (int i = 0; i < len; i++) 
	{
		arr[i] = cur->data;
		cur = cur->next;
	}

	// 快速排序
	QuickSort(arr, 0, len - 1);

	// 将数组转换为链表
	cur = phead;
	for (int i = 0; i < len; i++) 
	{
		cur->data = arr[i];
		cur = cur->next;
	}

	free(arr);
}

(8)已有数据读取

①生成一个新结点,将读取的数据存入新结点中。

②第一次读取时链表为空,修改头指针。

③后面的新结点链接到链表的尾部。

(注意:读模式打开文件需要文件夹中有这个文件,第一次需要手动创建一个data.txt文件)

//已有数据读取,可能要更改头指针,传二级指针修改一级指针
void StartFileEntry(Node** pphead)
{
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}

	//保存读取到的数据
	PepInfo* tmp = (PepInfo*)malloc(sizeof(PepInfo));
	if (tmp == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	//先读取一次
	fread(tmp, sizeof(PepInfo), 1, pf);
	//保存尾部节点地址
	Node* tail = NULL;
	
	//读取到结尾时feof()返回0,未读取到结尾返回非0值
	while (!feof(pf))
	{
		//生成新节点
		Node* NewNode = (Node*)malloc(sizeof(Node));
		if (NewNode == NULL)
		{
			printf("malloc error\n");
			exit(-1);
		}
		NewNode->data = *tmp;
		NewNode->next = NULL;
		//第一次头为空,更新
		if (*pphead == NULL)
		{
			*pphead = NewNode;
			tail = *pphead;
		}
		//头不为空,新节点链接到尾后面,尾指针更新
		else
		{
			tail->next = NewNode;
			tail = tail->next;
		}
		//继续读取
		fread(tmp, sizeof(PepInfo), 1, pf);
	}
	fclose(pf);
}

(9)更新数据录入

链表为空,直接返回;否则遍历链表,依次录入数据。文章来源地址https://www.toymoban.com/news/detail-454312.html

//新数据录入
void UpdateFileEntry(Node* phead)
{
	FILE* pf = fopen("data.txt", "wb");
	if (phead == NULL)
	{
		return;
	}
	else
	{
		while (phead)
		{
			fwrite(&(phead->data), sizeof(PepInfo), 1, pf);
			phead = phead->next;
		}
	}
	fclose(pf);
}

三:全部代码

contact.h(声明)

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
//方便后面更改这些信息的最大容量
#define max_name 20
#define max_tele 20
#define max_addr 20
#define max_sex 10

//个人信息
typedef struct PepInfo
{
	char name[max_name];
	int age;
	char sex[max_sex];
	char tele[max_tele];
	char addr[max_addr];
}PepInfo;

typedef struct Node
{
	//个人信息
	struct PepInfo data;
	//指针域
	struct Node* next;
}Node;


//生成一个新节点
Node* BuyNewNode();

//增加信息,可能要更改头指针,传二级指针修改一级指针
void AddContact(Node** pphead);

//打印信息
void PrintContact(Node* phead);

//查找
Node* FindContact(Node* phead, char* name);

//删除信息,可能要更改头指针,传二级指针修改一级指针
void DelContact(Node** pphead);

//修改信息
void ModifyContact(Node* phead);

//进行排序
// 链表快速排序函数
void sortList(Node* phead);
//插入排序
void sort(Node* phead);

//已有数据读取,可能要更改头指针,传二级指针修改一级指针
void StartFileEntry(Node** pphead);

//更新数据录入
void UpdateFileEntry(Node* phead);

contact.c(接口)

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

//生成一个新节点
Node* BuyNewNode()
{
	Node* NewNode = (Node*)malloc(sizeof(Node));
	if (NewNode == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	NewNode->next = NULL;

	printf("请输入名字:");
	scanf("%s", NewNode->data.name);
	printf("请输入年龄:");
	scanf("%d", &NewNode->data.age);
	printf("请输入性别:");
	scanf("%s", NewNode->data.sex);
	printf("请输入电话:");
	scanf("%s", NewNode->data.tele);
	printf("请输入地址:");
	scanf("%s", NewNode->data.addr);

	return NewNode;
}

//增加信息,可能要更改头指针,传二级指针修改一级指针
void AddContact(Node** pphead)
{
	//生成新节点
	Node* NewNode = BuyNewNode();
	//单独处理空的情况
	if (*pphead == NULL)
	{
		*pphead = NewNode;
		return;
	}
	else
	{
		NewNode->next = *pphead;
		*pphead = NewNode;
	}
}

//打印信息
void PrintContact(Node* phead)
{
	//注意打印格式,加-表示字符左对齐,数字表示最小字符数(不足补空格)
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
	while (phead != NULL)
	{
		printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n", 
			   phead->data.name,phead->data.age,
			   phead->data.sex,phead->data.tele,phead->data.addr);
		//迭代
		phead = phead->next;
	}
}

//查找,第二个参数为名字字符串首地址
Node* FindContact(Node* phead,char* name)
{
	//遍历链表
	while (phead)
	{
		//strcmp()函数用于字符串比较,相同返回0,否则返回非0值
		if (strcmp(phead->data.name, name) == 0)
		{
			return phead;
		}
		phead = phead->next;
	}
	//没找到返回空
	return NULL;
}

//删除信息,可能要更改头指针,传二级指针修改一级指针
void DelContact(Node** pphead)
{
	//断言,信息为空不能删除
	assert(*pphead != NULL);
	
	//查找
	char name[max_name];
	printf("请输入要删除联系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(*pphead,name);
	if (pos == NULL)
	{
		printf("查找失败\n");
		return;
	}

	//如果pos是第一个节点
	if (pos == *pphead)
	{
		//找到下一个
		Node* NEXT = pos->next;
		free(pos);
		*pphead = NEXT;
	}
	else
	{
		//找到前一个
		Node* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
	printf("删除成功\n");
}

//修改信息
void ModifyContact(Node* phead)
{
	//查找
	char name[max_name];
	printf("请输入要修改联系人的名字:");
	scanf("%s", name);
	Node* pos = FindContact(phead, name);
	if (pos == NULL)
	{
		printf("查找失败\n");
		return;
	}
	else
	{
		printf("找到了,进行修改\n");
		printf("请输入名字:");
		scanf("%s", pos->data.name);
		printf("请输入年龄:");
		scanf("%d", &pos->data.age);
		printf("请输入性别:");
		scanf("%s", pos->data.sex);
		printf("请输入电话:");
		scanf("%s", pos->data.tele);
		printf("请输入地址:");
		scanf("%s", pos->data.addr);
	}
}

交换数据
//void swap(PepInfo* p1, PepInfo* p2)
//{
//	PepInfo tmp = *p1;
//	*p1 = *p2;
//	*p2 = tmp;
//}
//
 三数取中
//int GetMidIndex(PepInfo* a, int left, int right)
//{
//	int midi = left + (right - left) / 2;
//
//	if (a[midi].age > a[right].age)
//	{
//		if (a[midi].age < a[left].age)
//			return midi;
//		else if (a[right].age > a[left].age)
//			return right;
//		else
//			return left;
//	}
//	else // a[right] > a[mid]
//	{
//		if (a[midi].age > a[left].age)
//			return midi;
//		else if (a[left].age < a[right].age)
//			return left;
//		else
//			return right;
//	}
//}
//
前后指针法
//int partion3(PepInfo* a, int left, int right)
//{
//	int midi = GetMidIndex(a, left, right);
//	swap(&a[midi], &a[left]);
//
//	int keyi = left;
//	int prev = left;
//	int cur = left + 1;
//	while (cur <= right)
//	{
//		//++prev和cur相等,无效交换,不换
//		if (a[cur].age < a[keyi].age && ++prev != cur)
//		{
//			swap(&a[prev], &a[cur]);
//		}
//		cur++;
//	}
//	swap(&a[keyi], &a[prev]);
//	return prev;
//}
//
快速排序
//void QuickSort(PepInfo* a, int left, int right)
//{
//	//如果left>right,区间不存在
//	//left==right,只有一个元素,可以看成是有序的
//	if (left >= right)
//	{
//		return;
//	}
//	else
//	{
//		//单次排序
//		int keyi = partion3(a, left, right);
//		//分成左右区间,排序左右区间
//		QuickSort(a, left, keyi - 1);
//		QuickSort(a, keyi + 1, right);
//	}
//}
//
 链表快速排序函数
//void sortList(Node* phead) 
//{
//	// 处理空或单节点链表的情况
//	if (!phead || !phead->next)
//	{
//		return;
//	}
//
//	//求链表长度
//	int len = 0;
//	Node* cur = phead;
//	while (cur) 
//	{
//		len++;
//		cur = cur->next;
//	}
//
//	// 将链表转换为数组
//	PepInfo* arr = malloc(len * sizeof(PepInfo));
//	if (arr == NULL)
//	{
//		printf("malloc error\n");
//		exit(-1);
//	}
//	cur = phead;
//	for (int i = 0; i < len; i++) 
//	{
//		arr[i] = cur->data;
//		cur = cur->next;
//	}
//
//	// 快速排序
//	QuickSort(arr, 0, len - 1);
//
//	// 将数组转换为链表
//	cur = phead;
//	for (int i = 0; i < len; i++) 
//	{
//		cur->data = arr[i];
//		cur = cur->next;
//	}
//
//	free(arr);
//}

//交换数据
void swap(Node* p1, Node* p2)
{
	struct PepInfo tmp = p1->data;
	p1->data = p2->data;
	p2->data = tmp;
}

//进行排序
void sort(Node* phead)
{
	//空不排序
	assert(phead != NULL);

	Node* begin = phead;
	Node* end = phead->next;
	while (end)
	{
		while (begin != end)
		{
			if (begin->data.age > end->data.age)
			{
				swap(begin,end);
			}
			begin = begin->next;
		}
		end = end->next;
		begin = phead;
	}
}


//已有数据读取,可能要更改头指针,传二级指针修改一级指针
void StartFileEntry(Node** pphead)
{
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		printf("打开文件失败\n");
		exit(-1);
	}

	//保存读取到的数据
	PepInfo* tmp = (PepInfo*)malloc(sizeof(PepInfo));
	if (tmp == NULL)
	{
		printf("malloc error\n");
		exit(-1);
	}
	//先读取一次
	fread(tmp, sizeof(PepInfo), 1, pf);
	//保存尾部节点地址
	Node* tail = NULL;
	
	//读取到结尾时feof()返回0,未读取到结尾返回非0值
	while (!feof(pf))
	{
		//生成新节点
		Node* NewNode = (Node*)malloc(sizeof(Node));
		if (NewNode == NULL)
		{
			printf("malloc error\n");
			exit(-1);
		}
		NewNode->data = *tmp;
		NewNode->next = NULL;
		//第一次头为空,更新
		if (*pphead == NULL)
		{
			*pphead = NewNode;
			tail = *pphead;
		}
		//头不为空,新节点链接到尾后面,尾指针更新
		else
		{
			tail->next = NewNode;
			tail = tail->next;
		}
		//继续读取
		fread(tmp, sizeof(PepInfo), 1, pf);
	}
	fclose(pf);
}


//新数据录入
void UpdateFileEntry(Node* phead)
{
	FILE* pf = fopen("data.txt", "wb");
	if (phead == NULL)
	{
		return;
	}
	else
	{
		while (phead)
		{
			fwrite(&(phead->data), sizeof(PepInfo), 1, pf);
			phead = phead->next;
		}
	}
	fclose(pf);
}

test.c(主逻辑)

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

void menu()
{
	printf("********************************\n");
	printf("***** 1.增加      2.删除  ******\n");
	printf("***** 3.查找      4.修改  ******\n");
	printf("***** 5.排序      6.打印  ******\n");
	printf("***** 0.退出              ******\n");
	printf("********************************\n");

}

int main()
{
	Node* head = NULL;
	int input = 0;

	//原信息录入,这里用读模式打开,第一次需要手动创建文件
	StartFileEntry(&head);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&head);
			printf("增加成功\n");
			break;
		case 2:
			DelContact(&head);
			break;
		case 3:
		{
			char name[max_name];
			printf("请输入要查找联系人的名字:");
			scanf("%s", name);
			Node* pos = FindContact(head, name);
			if (pos == NULL)
			{
				printf("查找失败\n");
			}
			else
			{
				printf("找到了\n");
				printf("%-20s\t%-5d\t%-5s\t%-20s\t%-20s\n",
					pos->data.name, pos->data.age, pos->data.sex,
					pos->data.tele, pos->data.addr);
			}
			break;
		}
		case 4:
			ModifyContact(head);
			break;
		case 5:
			sort(head);
			printf("排序成功\n");
			break;
		case 6:
			PrintContact(head);
			break;
		case 0:
			printf("退出\n");
			break;
		default:
			printf("非法输入,重新输入\n");
			break;
		}
	} while (input);

	//新信息录入
	UpdateFileEntry(head);
	return 0;
}

到了这里,关于动态通讯录实现(C语言)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言实现通讯录--动态版

    实现一个通讯录,联系人的数量可多可少 1.在静态版本的基础上改用动态的方法: (1)默认能够存放三个人的信息 (2)不够的话,每次增加两个人的信息 2.其他功能不变 建立三个文件: test.c 用于测试通讯录的相关功能 contsct.c 通讯录的实现模块(用函数实现功能) conta

    2024年02月15日
    浏览(52)
  • C语言动态内存练习:【通讯录(动态内存版本)实现】

    前面我们写了一个静态数组版本的通讯录,再结合刚学习的动态内存管理的知识,我们现在来实现一个动态内存版本的通讯录。 动态内存版本的通讯录,主要还是为了解决静态数组版本的通讯录空间太大导致的内存浪费和空间太小不够存放的问题。 扩容策略: 为通讯录设置

    2023年04月13日
    浏览(72)
  • C语言之通讯录的实现(静态版,动态版,文件版)

    个人主页(找往期文章包括但不限于本期文章中不懂的知识点): 我要学编程(ಥ_ಥ)-CSDN博客 目录 静态通讯录的实现逻辑  test.c:通讯录的逻辑实现 Contact.h:函数的声明与头文件的包含 Contact.c:函数的实现  通讯录源码:  test.c: Contact.c: Contect.h: 动态版通讯录  test.c: Co

    2024年04月13日
    浏览(42)
  • 【进阶C语言】动态版通讯录的实现(详细讲解+全部码源)

    前言 📕作者简介: 热爱跑步的恒川 ,致力于 C/C++、Java、Python 等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于 C语言进阶 系列,本专栏主要内容为数据的存储、指针的进阶、字符串和内存函数的介绍、自定义类型结构、动态内存管理、文件操作等,持续更

    2024年02月01日
    浏览(46)
  • 动态内存管理函数介绍及C语言实现通讯录管理系统2.0版(动态增长版本)

    之前向大家介绍了C语言实现通讯录管理系统1.0版本,但该版本有明显的不足之处,比如:一开始就开辟了1000个date数组,如果联系人很少,那么就会造成严重的内存浪费,或者联系人超过了1000人,那么原数组就放不下了,所以今天我们考虑使用动态内存管理的办法来实现一个

    2023年04月08日
    浏览(50)
  • 【C语言】动态通讯录 -- 详解

    前面详细介绍了静态版通讯录【C语言】静态通讯录 -- 详解_炫酷的伊莉娜的博客-CSDN博客,但是静态版通讯录的空间是无法被改变的,而且空间利用率也不高。为了解决静态通讯录这一缺点,这时就要有一个能够随着存入联系人数量的增加而增大空间的通讯录。接下来我们将

    2024年02月12日
    浏览(42)
  • 【C语言】动态通讯录(超详细)

    通讯录是一个可以很好锻炼我们对结构体的使用,加深对结构体的理解,在为以后学习数据结构打下结实的基础 这里我们想设计一个有 添加联系人,删除联系人,查找联系人,修改联系人,展示联系人,排序 这几种功能的通讯录 注意:我们按照三个区域划分 上图所示进行

    2024年02月08日
    浏览(35)
  • C语言实践——通讯录(2)(动态版)

    首先感谢上一篇博客的大佬们的点赞,非常感谢!!! 目录 前言  一、需要添加的功能 1. 初始化——动态内存开辟 2.添加联系人——通讯录扩容 3.退出通讯录——通讯录销毁 二、具体操作 1.铺垫 2.修改初始化函数 3.修改添加函数  4.退出通讯录,新增销毁函数 上一篇文章我

    2023年04月08日
    浏览(35)
  • 【C语言】——通讯录(静态-动态增长-文件储存)

      目录 前言: 一:整体框架 关于通讯录结构体的创建  二:通讯录的功能实现(静态) 2.1初始化通讯录 2.2增加联系人 2.3打印通讯录 2.4删除联系人  2.5 查找联系人 2.6修改联系人  2.7排序联系人 三:通讯录优化——动态内存  3.1通讯录的创建 3.2初始化通讯录  3.3增加联系

    2024年02月07日
    浏览(43)
  • 动态通讯录——C语言【详解+全部码源】

    作者简介: 辭七七,目前大一,正在学习C/C++,Java,Python等 作者主页: 七七的个人主页 文章收录专栏: 进阶C语言,本专栏主要讲解数据存储,进阶指针,动态内存管理,文件操作,程序环境和预处理等 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 我们之前以及写过静态版

    2023年04月21日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包