通讯录的实现(初级版本)

思维导图:

目录

思维导图:

​编辑

一,实现通讯录的第一步——实现逻辑 

二,头文件内实现的内容

三,contect.c文件内的函数定义

3.1初始化通讯录:void InitContect(cotect*pc)

3.2:实现通讯录内容的增加:void AddContect(Contect* pc)

3.3:实现对通讯录的内容进行显示:void ShowContect(Contect* pc)

3.4对通讯录内的指定信息进行删除:void DelContect(Contect* pc)

3.5 实现对通讯录内人的信息的修改:void ModifyContect(Contect* pc)

 3.6查找联系人:void SearchContect(Contect* pc)

3.7排序联系人 :void SortContect(Contect* pc)

3.8contect.c内最特殊的函数


一,实现通讯录的第一步——实现逻辑 

1.1打印菜单

实现位置:test.c

实现函数:menu()

返回类型:void

作用:将通讯录可以实现的功能显示出来供使用对象选择

🤖代码🤖:

void menu() {
	printf("*****1.ADD    2.DEL    *****\n");
	printf("*****3.SEARCH 4.MODIFY *****\n");
	printf("*****5.SHOW   6.SORT   *****\n");
	printf("*****     0.EXIT       *****\n");
}

1.2:通讯录功能实现逻辑

实现位置:test.c

enum {
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT

};
int main() {
	Contect* con;
	InitContect(&con);//初始化通讯录
	int input = 0;
	do {
		menu();
		printf("请选择:>");
	scanf("%d", &input);
		switch (input) {
		case ADD: 
			AddContect();//添加通讯录的个人信息
			break;
		case DEL:
			DelConteCt();//删除通讯录内的信息
			break;
		case SEARCH:
			SearchContect();//查找通讯录的个人信息
			break;
		case MODIFY:
			ModifyContect();//修改通讯录里的个人信息
			break;
		case SHOW:
			ShowContect();//显示通讯录内的信息
			break;
		case SORT:
			SortCpntect();//排序通讯录内的信息
			break;
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
}

	} while (input);

}

小细节❗:

在实现switch……case语句时,我没有使用数字。原因是因为使用了enum关键字。

enum也就是枚举,会把它里面的第一个第一个参数标记为0,其它的参数在这个基础

之上按顺序加1。在我们的例子中,EXIT就表示0,ADD表示1,DEL表示为2……以此类推

二,头文件内实现的内容

实现位置:contect.h

其实头文件内部实现的内容无非就是各种函数的声明,我在这里也就不一 一介绍了,但是在这里着重介绍下面的内容。

宏定义最大值,以及通讯录内容的定义: 

通讯录的内容:

1.人的信息

名字,年龄,性别,电话,住址

2.是第几个人

代码:

#define MAX_sz 100
#define MAX_name 5
#define MAX_age 5
#define MAX_sex 5
#define MAX_Tele 12
#define MAX_address 20
typedef struct PeoInfo {
	char name[MAX_name];
	int age[MAX_age];
	char sex[MAX_sex];
	char tele[MAX_Tele];
	char address[MAX_address];
} PeoInfo;
typedef struct Contect {
	PeoInfo data[MAX_data];
	int sz;
}Contect ;

 ❗细节❗:

1.在这里使用宏定义的作用是为了后面方便修改结构体PeoInfo内的数组的大小

2.使用typedef的作用是对结构体进行重命名来方便使用结构体变量

三,contect.c文件内的函数定义

contect.c函数可谓是我们整个通讯录实现工程的重头戏了,

现在让我们把目光放到contect.c内部详细讲解这个文件内定义的函数。

3.1初始化通讯录:void InitContect(cotect*pc)

实现的功能:将通讯录内的内容初始化为0

代码:

Init(Contect* pc) {
    int sz = 0;//将sz初始化为0
	memset(pc->data, 0, sizeof(pc->data));//使用memset函数来对data进行初始化为0
};

知识补充:memset()

三个参数:

1. 要改变的数据的起始地址:pc->data

2.你想要改变为的值:0

3.你要改变的数据的字节大小:sizeof(pc->data)//sizeof(数组名)表示整个数组的大小

3.2:实现通讯录内容的增加:void AddContect(Contect* pc)

实现功能:对通讯录进行内容的填充

实现条件:在通讯录的空间还没有满

 代码:

void AddContect(Contect* pc) {
	if (pc -> sz < MAX_data) {
		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);
		pc->sz++;
		printf("增加联系人成功\n");
	}
	else {
		printf("通讯录已满\n");
	}

}

3.3:实现对通讯录的内容进行显示:void ShowContect(Contect* pc)

实现功能:对通讯录的内容进行容易看懂的展示

代码:

void ShowContect(Contect* pc) {
	printf("%-10s%-5s%-5s%-20s%-5s\n", 
		"名字","年龄","性别","电话","住址");
	int i = 0;
	while (i < pc->sz) {
		printf("%-10s%-5d%-5s%-20s%-5s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
		    i++;
	}
}

3.4对通讯录内的指定信息进行删除:void DelContect(Contect* pc)

实现功能:对指定的联系人的信息的删除。

代码:

Find_By_Name(Contect* pc) {
	char name[20];
	printf("请输入你要删除的人的名字:>");
	scanf("%s", name);
	int i = 0;
	for (i = 0;i < pc->sz;i++) {
		if (strcmp(name, pc->data[i].name)==0)
			return i;
	}
	return -1;
}
void DelContect(Contect* pc) {
	int pos = 0;
	int i = 0;
	 pos = Find_By_Name(pc);
	if (pos == -1) {
		printf("要删除的人的信息不存在\n");
		return;
	}
	for (i = pos;i < pc->sz - 1;i++) {
		pc->data[pos] = pc->data[pos + 1];
	}
	printf("删除成功!\n");
	pc->sz--;

}

实现方法:通过一个Find_By_Name函数来对要查找的人的信息进行定位,找到了就返回该信息的下标,找不到就返回-1。在找到该成员下标的前提下,通过该下标后面的人的信息覆盖前面人的信息的方法来达到删除的目的。

3.5 实现对通讯录内人的信息的修改:void ModifyContect(Contect* pc)

实现功能:对你所不满的人的信息进行修改 

 代码:

void ModifyContect(Contect* pc) {
	printf("请输入要修改人的名字:>");
	int pos = Find_By_Name(pc);
	if (pos == -1) {
		printf("找不到要修改的联系人\n");
return;
	}
	else {
		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");

	}

}

实现方法:通过Find_By_Name函数来找到要修改的人的下标,然后返回这个下标。如果这个下标是-1那就输出找不到这个联系人的信息结束进程。如果不是-1那就通过下标来对指定联系人的信息进行逐个修改。

 3.6查找联系人:void SearchContect(Contect* pc)

实现功能:找到联系人的信息并将他的信息显示出来。

代码:

void SearchContect(Contect* pc) {
	int pos = 0;
	printf("请输入要查找的人的信息:>");
	pos = Find_By_Name(pc);
	if (pos == -1) {
		printf("要查找的人的信息不存在\n");
		return;
	}
	else {
		printf("%-10s%-5s%-5s%-20s%-5s\n",
			"名字", "年龄", "性别", "电话", "住址");
			printf("%-10s%-5d%-5s%-20s%-5s\n",
				pc->data[pos].name,
				pc->data[pos].age,
				pc->data[pos].sex,
				pc->data[pos].tele,
				pc->data[pos].addr);
		
		
	}
}

实现方法:通过Find_By_Name函数对想要查找的联系人的信息进行查找,定位下标。找到了便对该下标对应的信息进行打印显示。找不到就打印提示信息。

3.7排序联系人 :void SortContect(Contect* pc)

实现功能:对通讯录的内容进行排序

代码:

int cmp_By_Name(void* e1, void* e2) {
	return strcmp(((Contect*)e1)->data->name , ((Contect*)e2)->data->name);
}
		
void SortContect(Contect* pc) {
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_By_Name);
	printf("排序成功\n");
}

 实现方法:运用qsort函数来对通讯录里的内容进行排序。现在排的是升序,如果你想要拍成降序只需要将cmp_By_Name内的两个参数交换一下位置就可以了。在这里也要注意,比较按照名字来排序也就是需要比较字符串,所以在比较时需要使用strcmp函数来进行比较

3.8contect.c内最特殊的函数

在这个文件里最特殊的函数便是Find_By_Name()这个函数。这个函数特殊的点在于它是没有在头文件里面声明的,因为这个函数只需要在contect.c文件里面使用。所以为了使这个函数能更加隐蔽,我们可以在Find_By_Name这个函数的前面加上一个static关键字。

static Find_By_Name(const Contect* pc) {
	char name[20];
	scanf("%s", name);
	int i = 0;
	for (i = 0;i < pc->sz;i++) {
		if (strcmp(name, pc->data[i].name)==0)
			return i;
	}
	return -1;
}

今天分享完毕!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/11761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python的基础

这是我自己学习Python的三个星期的小总结&#xff0c;内容包含了规范、数据类型、函数、类和捕捉异常&#xff0c;做了一个简单的梳理&#xff0c;希望可以帮助到和我一样开始学习Python的小伙伴&#xff0c;也希望多多支持&#xff0c;相互进步&#xff0c;下面步入正题。 基…

【Python】Python中的列表,元组,字典

文章目录列表创建列表获取元素修改元素添加元素查找元素删除元素列表拼接遍历列表切片操作元组创建元组元组中的操作字典创建字典添加/修改元素删除元素查找字典的遍历合法的key类型列表 列表是一种批量保存数据的方式&#xff0c;列表使用[]表示 创建列表 创建两个空列表 …

Java对日开发成趋势?网友:找工作打开了新思路

近两年行业环境起起伏伏&#xff0c;企业降本增效&#xff0c;提高人才招聘的门槛&#xff0c;导致大家找工作时觉得越来越难&#xff0c;尤其是Java开发&#xff0c;主打的就是一个“卷”&#xff01; 不过行业变革&#xff0c;挑战与机遇并存。Java作为编程语言排行榜的常年第…

malloc hook进行内存泄漏检测

记录下使用malloc的hook形式&#xff0c;写个小的demo&#xff0c;并记录遇到的问题 1. 实现代码&#xff1a; CMakeLists.txt和相应的memory_leak.cpp文件 cmake_minimum_required(VERSION 3.14) project(demo)set(_SRCmemory_leak.cpp)add_library(memory_leak SHARED ${_S…

SpringCloud:ElasticSearch之索引库操作

ElasticSearch索引库就类似数据库表&#xff0c;mapping映射就类似表的结构。 我们要向ElasticSearch中存储数据&#xff0c;必须先创建“库”和“表”。 1.mapping映射属性 mapping是对索引库中文档的约束&#xff0c;常见的mapping属性包括&#xff1a; type&#xff1a;…

【无人机】采用最基本的自由空间路损模型并且不考虑小尺度衰落(多径多普勒)固定翼无人机轨迹规划(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【Android Audio】TimeCheck机制

TimeCheck机制&#xff08;Android R/S&#xff09; TimeCheck.cpp TimeCheck.h frameworks/av/media/utils/TimeCheck.cpp TimeCheck守护线程的作用&#xff1a; 当audioserver中IAudioFlinger&#xff0c;IAudioPolicyService&#xff0c;IEffect中的每一个binder函数调用时…

E4--光纤接口通信测试应用2023-04-17

1.场景 使用两块开发板A和B&#xff0c;通过光纤接口将在A板上ROM中存储的图片数据转发到B板并显示在B板连接的显示屏上&#xff0c;实现光纤接口通信。 具体场景是&#xff0c;由于A735T片上资源有限&#xff0c;因此ROM IP存储了一张1024*600&#xff08;LVDS屏幕&#xff0…

深拷贝与浅拷贝

目录&#xff1a; 深拷贝与浅拷贝的区别实现深拷贝的方式利用JSON.parse(JSON.stringify())实现深拷贝的局限性cloneDeep与json的对比手写实现cloneDeep 深拷贝与浅拷贝的区别 深拷贝和浅拷贝是只针对Object和Array这样的引用数据类型的。 深拷贝和浅拷贝的示意图大致如下&a…

SpringBoot——Scheduled定时任务

目录 1.静态定时任务 2.动态定时任务 在一些业务场景中&#xff0c;我们需要定义一些任务在我们指定的时间或是每隔一个时间段就自动执行&#xff0c;来作为任务的前提&#xff0c;保证业务的执行。比如&#xff1a;我们需要一个定时任务&#xff0c;每天早上6点执行&#xf…

多通道振弦传感器无线采集采集仪如何开始使用

多通道振弦传感器无线采集采集仪如何开始使用 开始使用 设备电源 VS208~432 可使用内置电池&#xff08;默认&#xff09;也可使用外部电池工作。 需要特别注意&#xff1a;严禁内置和外部电池&#xff08;电源&#xff09;同时使用&#xff0c;严重时会造成短路起火&#xff0…

靶机精讲之CTF4

主机发现 靶机193 端口扫描 服务扫描 80&#xff0c;25&#xff08;明确版本&#xff09;攻击面更大 web渗透 blog是交互式的程序 发现index可进行手动爆破&#xff08;地址包含&#xff09; http://192.168.10.193/index.html?page../../../../../../../../etc/passwd 无发…

【数据挖掘与商务智能决策】第八章 K近邻算法

第八章 K近邻算法 1.K近邻算法简单代码演示 import pandas as pd df pd.read_excel(葡萄酒.xlsx) df原始样本酒精含量(%)苹果酸含量(%)分类0样本15201样本26102样本34103样本48314样本51021 # 特征变量和目标变量的切分 X_train df[[酒精含量(%),苹果酸含量(%)]] y_train …

PHP实现以函数的方式计算阶乘,使用函数输入数值逆序输出的两个代码程序

目录 前言 一、实现以函数的方式计算阶乘 1.1运行流程&#xff08;思想&#xff09; 1.2代码段 1.3运行截图 二、使用函数输入3个数求和&#xff0c;并以表单形式输出 2.1运行流程&#xff08;思想&#xff09; 2.2代码段 2.3运行截图 前言 1.因多重原因&#xff0c;…

【C++】模板进阶--非类型模板参数模板特化及分离编译

文章目录一、非类型模板参数二、模板的特化1.模板特化的概念2.函数模板的特化3.类模板的特化3.1 全特化3.2 偏特化4.类模板特化应用示例三、模板的分离编译四、模板总结一、非类型模板参数 模板参数分为类型形参与非类型形参&#xff0c;其中&#xff0c;类型形参即出现在模板…

Spring启动及Bean实例化过程来看经典扩展接口

目录 一、Spring启动及Bean实例化过程 二、分析其对应经典扩展接口 三、对开发的指导意义 备注&#xff1a;以下总结只是一些基本的总结思路&#xff0c;具体每个扩展接口的应用后续进行分析总结。 一、Spring启动及Bean实例化过程 Spring启动及Bean实例化的过程&#xff0…

CSS实现三角形的四种方法

方法一&#xff1a;使用 border (常见) 【解释】不设置宽高&#xff0c;用边框大小控制三角型大小 【分解步骤】 设置一个div不设宽高 【示例】 <style>#triangle{width: 0;height: 0;border: 100px solid;border-color: orangered skyblue gold yellowgreen;} </s…

Python第三方库安装

看见更大的Python世界 Python社区PyPI The Python Package Index PyPI: Python Package Index PSF维护的展示全球Python计算生态的主站 学会检索并利用PyPI&#xff0c;找到合适的第三方库开发程序 实例&#xff1a;开发与区块链相关的程序 第1步&#xff1a;在pypi.org…

第01章_Java语言概述

第01章_Java语言概述 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 1. Java知识脉络图 1.1 Java基础全程脉络图 1.2 本章专题与脉络 2. 抽丝剥茧话Java 2.1 当前大学生就业形势 麦可思研究院…

fMRI研究 | 社交情境下的混合情绪

导读 背景&#xff1a;神经科学通常都是单独研究各种情绪&#xff0c;而混合的情绪状态&#xff08;例如愉悦和厌恶、悲伤和快乐的共存&#xff09;在日常生活中很常见。心理生理学和行为学证据表明&#xff0c;混合情绪可能具有不同于其组成情绪的反应特征。然而&#xff0c;…