返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言静态与动态通讯录的实现流程详解
  • 485
分享到

C语言静态与动态通讯录的实现流程详解

2024-04-02 19:04:59 485人浏览 八月长安
摘要

目录静态通讯录contact.hcontact.ctest.c动态通讯录contact.hcontact.cqsort.ctest.c本次通讯录的代码已经放到我的gitee仓库中,感

本次通讯录的代码已经放到我的gitee仓库中,感兴趣的小伙伴可以去看看

Gitee

静态通讯录

在我们学习C语言的结构体、指针以及动态内存管理之后,我们就可以实现一些有意思的小项目了,通过这些小项目可以加深我们对于相关知识的理解。

静态通讯录主要要求有

  • 静态大小,可以记录10个人的信息(大小自己定)
  • 记录的信息如下:名字、性别、年龄、电话、住址
  • 可以实现联系人的增删查改

为了方便代码的管理和维护,我们分文件实现以上的要求

  • contact.h 用于声明相关的接口
  • contact.c 用于实现相关的接口
  • test.c 用于测试相关的接口

contact.h

在contact.h中,我们统一用预处理指令来确定好通讯录的大小,以及每一个联系人信息的范围大小,方便后续的修改

在确定好范围后,我们通过定义结构体类型的方式来实现对数据的统一管理

结构体类型确定后,就是相关接口的声明了


//首先引入需要用到的头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//确定每一个联系人名字、电话等信息的范围大小
#define MAX_NAME 10
#define MAX_PHONE 20
#define MAX_ADDR 25

// 确定通讯录的总大小
#define MAX_CAPACITY 10

//由于每一个联系人都有多个信息,因此需要定义一个结构体类型来管理
//定义联系人相关信息的结构体
 typedef struct PeoInfo {

	char name[MAX_NAME];
	char sex;
	int  age;
	char phone[MAX_PHONE];
	char address[MAX_ADDR];

}peo;


//通讯录内包含多个成员,因此也需要统一管理,所以还是使用结构体
 //定义一个通讯录结构体,管理通讯录和记录有效联系人个数信息
typedef struct Contact {

	peo data[MAX_CAPACITY];//这里是一个数组,数组的每一个元素都是一个结构体
	int size;
}con;





//------------------------------------------------------
//以下是相关接口的声明

//菜单接口
void menu();

//对结构体变量进行初始化
void InitContact(con* con);

//打印通讯录信息
void Print(con* con);

//实现增加联系人的接口
void AddContact(con* con);

//实现删除联系人的接口
void DelContact(con* con);

//实现查找联系人的接口
void SearchContact(con* con);

//实现修改联系人的接口
void ModifyContact(con* con);

contact.c

contact.c是整个项目的关键,需要对相关接口进行定义


//通讯录各个接口的实现
//首先引入.h文件
#include"Contact.h"

//菜单接口
void menu() {

	printf("*******************************\n");
	printf("********静态简易通讯录*********\n");
	printf("*******   0.退出通讯录   ******\n");
	printf("*******   1.增加联系人   ******\n");
	printf("*******   2.删除联系人   ******\n");
	printf("*******   3.查找联系人   ******\n");
	printf("*******   4.修改联系人   ******\n");
	printf("*******   5.打印联系人   ******\n");
	printf("*******************************\n");
	printf("\n");

}



//对结构体变量进行初始化
void InitContact(con* con) {

	//结构体的初始化一般用memset
	//我们首先让通讯录结构体变量的数组一开始为0
	memset(con->data, 0, sizeof(con->data));
	
	con->size = 0;//同时由于此时一个联系人的信息都没有,所以size也是0
}


//打印通讯录信息
void Print(con* con){
	int i = 0;
	if (con->size == 0) {
		printf("暂无可打印信息\n");
		return ;
	}
	printf("name\tsex\tage\tphone\taddress\n");
	for (i = 0; i < con->size; i++) {
		printf("%s\t%c\t%d\t%s\t%s\n", 
			con->data[i].name, con->data[i].sex,
			con->data[i].age, con->data[i].phone, con->data[i].address);
	}

}


//实现增加联系人的接口
void AddContact(con* con) {
	if (con->size == MAX_CAPACITY) {

		printf("容量已满,无法增加\n");
		return;
	}

	printf("请输入姓名:\n");
	scanf("%s", con->data[con->size].name);

	getchar();

	printf("请选择性别:(m表示男,w表示女)\n");
	scanf("%c", &(con->data[con->size].sex));

	printf("请输入年龄:\n");
	scanf("%d", &(con->data[con->size].age));

	printf("请输入手机号码:\n");
	scanf("%s", con->data[con->size].phone);

	printf("请输入住址:\n");
	scanf("%s", con->data[con->size].address);

	con->size++;
}

//实现删除联系人的接口
void DelContact(con* con) {

	if (con->size == 0) {
		printf("暂无可以删除的信息");
		return;
	}

	printf("请输入你要删除的联系人的姓名:\n");
	char name[MAX_NAME] = {0};

	scanf("%s", name);
	int i = 0;
	for (i = 0; i < con->size; i++) {
		if (strcmp(name, (con->data)[i].name) == 0) {
			int j = 0;
			for (j = i; j < con->size - 1; j++) {
				memmove(&(con->data[j]), &(con->data[j + 1]), sizeof(con->data[0]));
			}
			con->size--;
			return;

		}
	}
	printf("你输入的联系人不存在\n");
	
}


//实现查找联系人的接口
void SearchContact(con* con) {

	if (con->size == 0) {
		printf("暂无查找的信息");
		return;
	}

	printf("请输入你要查找的联系人的姓名:\n");
	char name[MAX_NAME] = { 0 };

	scanf("%s", name);
	int i = 0;
	for (i = 0; i < con->size; i++) {
		if (strcmp(name, (con->data)[i].name) == 0) {
			printf("%s\t%c\t%d\t%s\t%s\n",
				con->data[i].name, con->data[i].sex,
				con->data[i].age, con->data[i].phone, con->data[i].address);
			return;

		}
	}
	printf("你想要查找的联系人不存在\n");
}

//实现修改联系人的接口
void ModifyContact(con* con) {

	if (con->size == 0) {
		printf("暂无可以修改的信息");
		return;
	}

	printf("请输入你要修改的联系人的姓名:\n");
	char name[MAX_NAME] = { 0 };

	scanf("%s", name);
	int i = 0;
	for (i = 0; i < con->size; i++) {
		if (strcmp(name, (con->data)[i].name) == 0) {

			printf("请重新输入姓名:\n");
			scanf("%s", con->data[i].name);

			getchar();

			printf("请重新选择性别:(m表示男,w表示女)\n");
			scanf("%c", &(con->data[i].sex));

			printf("请重新输入年龄:\n");
			scanf("%d", &(con->data[i].age));

			printf("请重新输入手机号码:\n");
			scanf("%s", con->data[i].phone);

			printf("请重新输入住址:\n");
			scanf("%s", con->data[i].address);
			return;

		}
	}
	printf("你想要修改的联系人不存在\n");

}

提示

我们在实现接口的时候,如果形参传入的是指针,一般都需要先判断一下传入的指针是否为空指针,以免造成非法访问,但是由于我的疏忽,就没有写上去了!

test.c

test.c就是用来测试相关接口的文件,可以根据自己的想法来设定


#include"Contact.h"


int main() {

	//创建结构体并且初始化
	con c;
	InitContact(&c);

	menu();
	int input = 0;


	while (1) {

		printf("请输入你的选择:\n");
		scanf("%d", &input);

		switch (input) {
		case 1:
			AddContact(&c);
			break;
		case 2:
			DelContact(&c);
			break;
		case 3:
			SearchContact(&c);
			break;
		case 4:
			ModifyContact(&c);
			break;
		case 5:
			Print(&c);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("你的输入有误,请重新选择\n");
			break;

		}

		if (input == 0) {
			break;
		}
	}

	return 0;
}

动态通讯录

静态通讯录有一个缺点,那就是通讯录的大小,也就是只能存储的联系人是要求确定大小的,大小给多了浪费空间,给少了又不够用。

动态通讯录就是通过动态内存管理的函数来实现动态开辟空间大小,以满足需要的。

contact.h


//动态版本通讯录的实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>


#define MAX_NAME 15
#define MAX_PHONE 15
#define MAX_ADDR 25

//给定通讯录默认大小为5,不够可以增容
#define DefaultSize 5

//联系人结构体的声明
typedef struct PeoInfo {

	char name[MAX_NAME];
	char sex;
	short age;
	char phone[MAX_PHONE];
	char addr[MAX_ADDR];

}peo;

//通讯录结构体的声明
typedef struct Contact {

	peo* p;//我们通过指针的方式来管理联系人数组
	int capacity;
	int size;
}con;


//菜单函数
void menu();

//初始化通讯录
void InitCon(con* c);

//销毁通讯录
void DestoryCon(con* c);

//检查容量的接口
void CheckCapacity(con* c);

//打印联系人信息
void Print(con* c);

//联系人的增加
void AddCon(con* c);

//联系人的删除
void DelCon(con* c);

//联系人的查找
void SearchCon(con* c);

//联系人的修改
void ModifyCon(con* c);

//-------------------------------------------
//下面是我通过快排的原理,手写的快排来实现一下通过联系人名字和年龄排序的接口

//通过名字来排序
void SortByname(con* c);

//通过年龄来排序
void SortByage(con* c);


void Swap(char* p1, char* p2, int width);


void QSort(void* p, int num, int width, int(*cmp)(const void* , const void* ));


int cmpbyname(const void* p1,const void* p2);


int cmpbyage(const void* p1,const void* p2);

contact.c

关键接口的实现和静态通讯录的大同小异,只不过我们需要多定义一个检查空间的接口

每次增加联系人的时候,就调用这个接口,做到满了就增容

其中增容接口使用的时realloc函数


#include"contact.h"

//菜单函数
void menu() {

	printf("******************************************\n");
	printf("*************   动态版通讯录   ***********\n");
	printf("*************   1.增加联系人   ***********\n");
	printf("*************   2.删除联系人   ***********\n");
	printf("*************   3.查找联系人   ***********\n");
	printf("*************   4.修改联系人   ***********\n");
	printf("*************   5.按名字排序   ***********\n");
	printf("*************   6.按年龄排序   ***********\n");
	printf("*************   7.打印联系人   ***********\n");
	printf("*************   0.退出通讯录   ***********\n");
	printf("******************************************\n");


}

//初始化通讯录
void InitCon(con* c) {

	//这里也可以用relloc函数来初始化,这样的话就会有初始值
	c->p = (con*)malloc(DefaultSize * sizeof(peo));
	c->capacity = DefaultSize;
	c->size = 0;
}


//销毁通讯录
void DestoryCon(con* c) {

	free(c->p);
	c->p = NULL;
	c->capacity = 0;
	c->size = 0;

}

//检查容量的接口
void CheckCapacity(con* c) {

	if (c->capacity == c->size) {

		//每次增容二倍
		peo* tmp = (peo*)realloc(c->p, 2 * (c->capacity) * sizeof(peo));
		if (tmp != NULL) {
			c->p = tmp;
			c->capacity = 2 * c->capacity;
			printf("增容成功\n");
		}
		else {
			printf("增容失败\n");
			exit(1);
		}
	}
}

//打印联系人信息
void Print(con* c) {

	if (c->size == 0) {
		printf("暂无可以打印的信息\n");
		return;
	}

	printf("name\tsex\tage\tphone\taddress\n");

	int i = 0;
	for (i = 0; i < c->size; i++) {
		printf("%s\t%c\t%d\t%s\t%s\n", 
			c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].phone, c->p[i].addr);

	}
}

//联系人的增加
void AddCon(con* c) {

	//每一次增加联系人都要先检查容量是否足够
	CheckCapacity(c);

	printf("请输入名字:>\n");
	scanf("%s", c->p[c->size].name);
	getchar();
	printf("请输入性别:>(m表示男,w表示女)\n");
	scanf("%c", &(c->p[c->size].sex));
	printf("请输入年龄:>\n");
	scanf("%d", &(c->p[c->size].age));
	printf("请输入电话:>\n");
	scanf("%s", c->p[c->size].phone);
	printf("请输入地址:>\n");
	scanf("%s", c->p[c->size].addr);

	c->size++;
	printf("添加成功\n");
}

//联系人的删除
void DelCon(con* c) {

	printf("请输入你想要删除的联系人的名字\n");
	char name[MAX_NAME];
	scanf("%s", name);

	int i = 0;
	for (i = 0; i < c->size; i++) {

		if (strcmp(name, c->p[i].name) == 0) {

			
			int j = i;
			for (j = i; j < c->size - 1; j++) {
				memmove(&(c->p[j]), &(c->p[j + 1]), sizeof(c->p[0]));
			}
			c->size--;
			return;
		}

	}

	printf("你想要删除的联系人不存在\n");
}

//联系人的查找
void SearchCon(con* c) {

	printf("请输入你想要查找的人的名字:\n");
	char name[MAX_NAME];
	scanf("%s", name);

	int i = 0;
	for (i = 0; i < c->size; i++) {

		if (strcmp(name, c->p[i].name) == 0) {

			printf("%s\t%c\t%d\t%s\t%s\n",
				c->p[i].name, c->p[i].sex, c->p[i].age, c->p[i].phone, c->p[i].addr);
			return;
		}

	}

	printf("你想要查找的联系人不存在\n");

}

//联系人的修改
void ModifyCon(con* c) {

	printf("请输入你想要修改的人的名字:\n");
	char name[MAX_NAME];
	scanf("%s", name);

	int i = 0;
	for (i = 0; i < c->size; i++) {

		if (strcmp(name, c->p[i].name) == 0) {

			printf("请重新输入名字:>\n");
			scanf("%s", c->p[i].name);
			getchar();
			printf("请重新输入性别:>(m表示男,w表示女)\n");
			scanf("%c", &(c->p[i].sex));
			printf("请重新输入年龄:>\n");
			scanf("%d", &(c->p[i].age));
			printf("请重新输入电话:>\n");
			scanf("%s", c->p[i].phone);
			printf("请重新输入地址:>\n");
			scanf("%s", c->p[i].addr);
			return;
		}

	}

	printf("你想要修改的联系人不存在\n");

}



//通过名字来排序
void SortByname(con* c) {

	QSort(c->p, c->size, sizeof(c->p[0]),cmpbyname );

}

//通过年龄来排序
void SortByage(con* c) {

	QSort(c->p, c -> size, sizeof(c->p[0]), cmpbyage);

}

qsort.c

这是我根据快速排序的原理,手写的快速排序


#include"contact.h"


//快排的交换函数
void Swap(char* p1, char* p2, int width) {

	int i = 0;
	for (i = 0; i < width; i++) {
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}

}

//手写快排来进行通讯录排序
void QSort(void* p, int num, int width, int(*cmp)(const void*, const void*)) {

	int i = 0;
	for (i = 0; i < num - 1; i++) {

		int j = 0;
		for (j = 0; j < num - 1 - i; j++) {

			if (cmp((char*)p + j * width, (char*)p + (j + 1) * width) > 0) {
				Swap((char*)p + j * width, (char*)p + (j + 1) * width, width);
			}
		}

	}
}

int cmpbyage(const void* p1, const void* p2) {

	return (*(peo*)p1).age - (*(peo*)p2).age;
}

int cmpbyname(const void* p1, const void* p2) {

	return strcmp(((peo*)p1)->name,((peo*)p2)->name);
}

test.c

test.c用于测试相关的接口,可以根据自己的想法来测试


#include"contact.h"


int main() {


	menu();
	int input = 0;
		


	con c;
	InitCon(&c);

	while (1) {
		
		printf("请输入你的选择:\n");
		scanf("%d", &input);

		switch (input) {
		case 1:
			AddCon(&c);
			break;
		case 2:
			DelCon(&c);
			break;
		case 3:
			SearchCon(&c);
			break;
		case 4:
			ModifyCon(&c);
			break;
		case 5:
			SortByname(&c);
			break;
		case 6:
			SortByage(&c);
			break;
		case 7:
			Print(&c);
			break;
		case 0:
			printf("退出通讯录\n");
			break;

		}
		if (input == 0) {
			DestoryCon(&c);
			break;
		}
	}

	return 0;
}

到此这篇关于C语言静态与动态通讯录的实现流程详解的文章就介绍到这了,更多相关C语言 通讯录内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言静态与动态通讯录的实现流程详解

本文链接: https://lsjlt.com/news/157846.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言静态与动态通讯录的实现流程详解
    目录静态通讯录contact.hcontact.ctest.c动态通讯录contact.hcontact.cqsort.ctest.c本次通讯录的代码已经放到我的Gitee仓库中,感...
    99+
    2024-04-02
  • C语言动态与静态分别实现通讯录详细过程
    目录前言:一.静态通讯录的实现1.环境的分工逻辑2.待实现的功能3.contact.h4.contact.c5.test.c6.实现效果二.通讯录动态的实现1.contact.h2....
    99+
    2024-04-02
  • C语言与C++动态通讯录超详细实现流程
    目录1、思路以及要实现的功能2、详细步骤2.1 打印菜单界面(建一个源文件test.c)2.2 主函数2.3 初始化函数与加载函数2.4 增加联系人函数AddContact2.5 删...
    99+
    2024-04-02
  • C语言动态与静态分别实现通讯录的方法
    这篇文章主要讲解了“C语言动态与静态分别实现通讯录的方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言动态与静态分别实现通讯录的方法”吧!一.静态通讯录的实现1.环境的分工逻辑由于过程...
    99+
    2023-06-29
  • C语言静态与动态通讯录的实现方法是什么
    这篇文章主要讲解了“C语言静态与动态通讯录的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言静态与动态通讯录的实现方法是什么”吧!静态通讯录在我们学习完C语言的结构体、指针...
    99+
    2023-06-25
  • C语言静态版通讯录的设计与实现
    目录1. 配置运行环境2. 通讯录的实现2.1 通讯录的功能目录2.2 增加信息功能代码的实现2.3 显示信息功能代码的实现2.4 删除信息功能代码的实现2.5 查询信息功能代码的实...
    99+
    2023-05-16
    C语言静态版通讯录 C语言通讯录实现
  • C语言实现一个文件版动态通讯录流程详解
    目录通讯录思维导图一、Contact.h二、Contact.c1.初始化通讯录2.检查容量是否满3.添加联系人4.显示联系人5.查找联系人6.修改联系人7.通过名字来排序联系人8.保...
    99+
    2023-01-29
    C语言动态通讯录 C语言通讯录
  • C语言静态动态两版本通讯录实战源码
    目录正片开始静态版本头文件( phonebook.h)接口(test.c)功能板块(phonebook.c)1. 初始化:2. 增添:3.查找4.删除5.修改6.排序7.全览静态版全...
    99+
    2024-04-02
  • 基于C语言怎么实现静态通讯录
    这篇文章主要介绍“基于C语言怎么实现静态通讯录”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于C语言怎么实现静态通讯录”文章能帮助大家解决问题。一、项目要求实现一个通讯录通讯录可以用来存储100个...
    99+
    2023-07-02
  • C语言模拟实现动态通讯录
    目录1.模拟实现通讯录总体架构一览图2.文件执行任务3.分模块实现 测试模块 test.c头文件 功能函数声明 contact.h功能函数逐一实现1.模拟实现通讯录总体架构...
    99+
    2024-04-02
  • C语言示例讲解动态/文件/静态功能版本的通讯录实现
    目录一、代码展示test.ccontact.ccontact.h二、效果展示静态版本基本功能的实现动态版本扩容功能的实现文件版本保存本地功能实现一、代码展示 test.c ✅使用枚举...
    99+
    2024-04-02
  • C语言实现可增容动态通讯录详细过程
    目录创建可自动扩容的通讯录添加用户信息删除用户信息查找联系人修改用户信息以名字将用户排序销毁通讯录创建可自动扩容的通讯录 这里我们想实现通讯录自动扩容,不够了能扩大内存,变得稍微有点...
    99+
    2024-04-02
  • C语言实现通讯录的方法(包括静态版本和动态版本)
    目录1.静态通讯录的实现实现的方法:2.动态通讯录的实现实现的方法:3.总结1.静态通讯录的实现 实现的方法: 我们采用的方法就是工程形势,实现将功能和定义以及测试分成三个文件,其中...
    99+
    2024-04-02
  • C语言实现静态版通讯录的代码分享
    目录前言通讯录设计的关键思想点分析 通讯录界面(meun)设计 增加信息功能实现代码删除信息功能实现代码查询信息功能实现代码修改信息功能实现代码按年龄升序排序信息...
    99+
    2023-01-12
    C语言静态通讯录 C语言通讯录
  • 基于C语言实现静态通讯录的示例代码
    目录一、项目要求二、Contact.h三、Contact.c1、静态函数2、初始化通讯录3、打印4、增加联系人信息5、通过名字查找6、删除联系人信息7、修改信息8、排序通讯录9、清空...
    99+
    2024-04-02
  • C语言实现静态存储通讯录的示例代码
    目录最初的构思与规划显示菜单以及main函数增加个人信息显示所有联系人的信息删除个人信息查找个人信息更改个人信息对联系人信息进行排序最后产品展示contart.h 头文件contar...
    99+
    2024-04-02
  • C语言怎么模拟实现动态通讯录
    本篇内容主要讲解“C语言怎么模拟实现动态通讯录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言怎么模拟实现动态通讯录”吧!目录模拟实现通讯录总体架构一览图文件执行任务分模块实现 测...
    99+
    2023-06-20
  • C语言多功能动态通讯录实现示例
    目录前言一、预设置1,头文件的包含2,联系人的信息格式3,通讯录的信息格式4,通讯录相关宏定义5,通讯录功能枚举6,基本主函数二、功能函数实现1,初始化函数2,查找函数3,打印菜单4...
    99+
    2023-01-31
    C语言多功能动态通讯录 C语言 通讯录
  • C语言实现动态版通讯录的代码分享
    目录前言初始化函数具体实现代码检查容量函数实现代码销毁通讯录函数实现代码动态版通讯录完整代码前言 哈喽各位友友们,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!我仅已...
    99+
    2023-01-12
    C语言动态版通讯录 C语言动态通讯录 C语言 通讯录
  • C语言实现简易通讯录(静态版本)的代码分享
    目录一、通讯录1.演示效果2.完整代码二、代码解析1.宏定义及结构体声明2.主菜单函数3.主函数4.查找函数5.初始化联系人信息6.添加联系人信息7.显示所有联系人信息8.删除指定联...
    99+
    2022-11-13
    C语言静态通讯录 C语言 通讯录
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作