c语言练习85:通讯录的实现(基于顺序表实现)

news2025/5/15 8:23:43

通讯录的实现(基于顺序表实现)

基于动态顺序表实现通讯录 C语⾔基础要求:结构体、动态内存管理、顺序表、⽂件操作

1、功能要求

1)⾄少能够存储100个⼈的通讯信息

2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等

3)增加联系⼈信息

4)删除指定联系⼈

5)查找制定联系⼈

6)修改指定联系⼈

7)显⽰联系⼈信息

处理方法:

contact.h

#define  _CRT_SECURE_NO_WARNINGS 
//创建保存联系人数据的结构
#define NAME_MAX 100
#define SEX_MAX 100
#define TEL_MAX 100
#define ADDR_MAX 100
struct ContactInfo
{
	char name[NAME_MAX];//使用定长数组还是动态数组?
	char sex[SEX_MAX];//字符数组数组名即为数组首元素地址
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
};
typedef struct ContactInfo CInfo;
//通讯表的底层是通过顺序表来实现的
typedef struct SeqList contact;
//通讯录的初始化和销毁
void ContactInit(contact* pcon);//
void ContactDistory(contact* pcon);
//添加联系人
void ContactAdd(contact* pcon);
int FindByName(contact* pcon, char* name);
//删除联系人
void ContactDel(contact* pcon);
//修改联系人
void ContactModify(contact* pcon);
//查看联系人
void ContactShow(contact* pcon);
//查找联系人
void ContactFind(contact* pcon);

Seqlist.h

#define  _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include"Contact.h"
//typedef int SLDataType;
typedef struct ContactInfo SLDataType;//更改数据类型为通讯录数据类型
typedef struct SeqList
{
	SLDataType* a;
	int size;//顺序表中有效的数据格式
	int capacity;//顺序表当前的空间大小
}SL;
//typedef struct SeqList SL(即为)
//对顺序表进行初始化
void SLInit(SL* ps);
//对顺序表进行销毁
void SLDestory(SL* ps);
//尾部插入
void SLPushBack(SL* ps, SLDataType x);
//头部插入
void SLPushFront(SL* ps, SLDataType x);
//尾部删除
void SLPopBack(SL* ps);
//头部删除
void SLPopFront(SL* ps);
//打印
void SLPrint(SL* ps);
//判断顺序表是否位空
bool SLIsEmpty(SL* ps);
//在任意位置插入删除
//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps, int pos);
bool SLFind(SL* ps, SLDataType x);
//判断空间是否足够,不够则进行扩容
void SLCheckCapacity(SL* ps);

contact.c

#define  _CRT_SECURE_NO_WARNINGS 
#include"Contact.h"
#include"SeqList.h"
//通讯录的初始化和销毁
void ContactInit(contact* con) {
	SLInit(con);
}
void ContactDistory(contact* con) {
	SLDestory(con);
}
void ContactAdd(contact* pcon) {
	//所有数据都是CInfo里的
	CInfo info;
	printf("请输入联系人姓名: \n");
	scanf("%s", info.name);//数组名即为首地址
	printf("请输入联系人姓别: \n");
	scanf("%s", info.sex);
	printf("请输入联系人年龄: \n");
	scanf("%d", info.age);
	printf("请输入联系人电话: \n");
	scanf("%s", info.tel);
	printf("请输入联系人地址: \n");
	scanf("%s", info.addr);
	//获取到联系人数据后,其被保存到了结构体info中
	//下一步即为往通讯录顺序表中插入数据
	SLPushBack(pcon, info);
}
int FindByName(contact* pcon, char* name) {
	for (int i = 0; i < pcon->size; i++) {
		if (strcmp(pcon->a[i].name, name) == 0) {
			return i;
		}
	}
	return -1;
}
//删除联系人
void ContactDel(contact* pcon) {
	printf("请输入要删除的用户名称:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findindex = FindByName(pcon, name);
	if (findindex < 0) {
		printf("要删除的用户不存在!\n");
		return;
	}
	//找到了要删除findindex位置的数据
	SLErase(pcon, findindex);
}
//修改联系人
void ContactModify(contact* pcon) {
	//打印通讯录所有的数据
	//先打印表头文字
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
	for (int i = 0; i < pcon->size; i++) {
		printf("%s %s %d %s %s",
			pcon->a[i].name,
			pcon->a[i].sex,
			pcon->a[i].age,
			pcon->a[i].tel,
			pcon->a[i].addr
			);
	}
}
//查看联系人
void ContactShow(contact* pcon) {

}
//查找联系人
void ContactFind(contact* pcon) {

}

Seqlist.c

#define  _CRT_SECURE_NO_WARNINGS 
#include"SeqList.h"
void SLInit(SL* ps) {
	ps->a = NULL;
	ps->capacity = ps->size = 0;//也可在初始化时开辟空间
}
void SLDestory(SL* ps) {
	if (ps->a) {
		free(ps->a);
	}
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
void SLCheckCapacity(SL* ps) {
	//空间足够直接尾插
	//空间不够则进行扩容
	if (ps->size == ps->capacity) {
		//空间不够则进行扩容(relloc申请失败返回空指针)
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * 2 * sizeof(SLDataType));
		if (tmp == NULL) {
			perror("relloc fail\n");
			return 1;
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
}
void SLPushBack(SL* ps, SLDataType x){
	assert(ps != NULL);
	
	//空间足够直接尾插
	//空间不够则进行扩容(relloc申请失败返回空指针)
	SLCheckCapacity(ps);
		//直接插入数据
		ps->a[ps->size] = x;//ps->a[ps->size++] = x;
		ps->size++;
}
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);
	//判断空间是否足够不够则扩容
	SLCheckCapacity(ps);
	for (size_t i = ps->size; i > 0; i--) {
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;
}
void SLPopBack(SL* ps) {
	assert(ps);
	assert(!SLIsEmpty(ps));//assert(ps->size)也可以
	//ps->a[ps->size - 1] = 0;//(可有可无)
	ps->size--;//size最初为0,为0则不能减减
}
void SLPopFront(SL* ps, SLDataType x) {
	assert(ps);
	assert(!SLIsEmpty(ps));//进行判空操作,不为空才能继续
	//让后面数据往前挪一位
	for (size_t i = 0; i < ps->size-1; i++) {//size_t为无符号整形
		//最后一次进来i为ps->size-2
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}
void SLPrint(SL* ps) {
	for (size_t i = 0; i < ps->size; i++) {
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}
bool SLIsEmpty(SL* ps) {
	assert(ps);
	return ps->size == 0;//当前数据表有效数据位0,则当前数据表为空
}
//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);
	//对pos加以限制
	assert(pos >= 0 && pos <= ps->size);
	//扩容
	SLCheckCapacity(ps);
	//把pos位置及以后的数据往后挪动一位
	//循环里i的初始值可以为size或size-1k,但不同的初始值对应不同的结束条件
	/*for (size_t i = ps->size; i > pos; i--) {
		ps->a[i] = ps->a[i - 1];
	}*/
	for (size_t i = ps->size-1; i > pos-1; i--) {
		ps->a[i+1] = ps->a[i];
	}
	ps->a[pos] = x; 
	ps->size++;
}
//删除指定位置的数据
void SLErase(SL* ps, int pos) {
	assert(ps);
	assert(!SLIsEmpty(ps));//进行判空操作,不为空才能继续
	//对pos加以限制
	assert(pos >= 0 && pos <= ps->size);
	for (int i = pos; i < ps->size - 1; i++) {
		//最后一次进来的i的数据为ps->size - 2
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}
//bool SLFind(SL* ps, SLDataType x) {
//	assert(ps);
//	for (int i = 0; i < ps->size; i++) {
//		if (ps->a[i] == x) {
//			找到了
//			return true;
//		}
//	}
//	return false;
//}

test.c

#define  _CRT_SECURE_NO_WARNINGS 
#include"SeqList.h"
#include"Contact.h"
//void SLtest() {
//	SL sl;
//	SLInit(&sl);
	//	//尾部插入
	//	SLPushBack(&sl, 1);
	//	SLPushBack(&sl, 2);
	//	SLPushBack(&sl, 3);
	//	SLPushBack(&sl, 4);
	//	SLPrint(&sl);
	//	//头部插入
	//	SLPushFront(&sl, 5);
	//	SLPushFront(&sl, 6);
	//	SLPushFront(&sl, 7);
	//	SLPrint(&sl);
	//	SLPopBack(&sl);
	//	SLPrint(&sl);
	//	SLPopBack(&sl);
	//	SLPrint(&sl);
	//    SLDestory(&sl);
	//}
	//void SLtest02() {
	//	SL sl;
	//	SLInit(&sl);
	//	//尾部插入
	//	SLPushBack(&sl, 1);
	//	SLPushBack(&sl, 2);
	//	SLPushBack(&sl, 3);
	//	SLPushBack(&sl, 4);
	//	SLPrint(&sl);
	//	头删
	//	//SLPopFront(&sl);
	//	//SLPrint(&sl);
	//	//SLPopFront(&sl);
	//	//SLPrint(&sl);
	//	//SLDestory(&sl);
	//	//在指定位置之前插入数据
	//	/*SLInsert(&sl, 1, 11);
	//	SLPrint(&sl);
	//	SLDestory(&sl);*/
	//	删除指定位置的数据
	//	//SLErase(&sl, 0);
	//	//SLPrint(&sl);
	//	//SLErase(&sl, sl.size-1);
	//	//SLPrint(&sl);
	//	//
	//	bool findRet=SLFind(&sl, 3);
	//	if (findRet) {
	//		printf("找到了\n");
	//	}
	//	else {
	//		printf("没有找到!\n");
	//	}
	//    SLDestory(&sl);
	

void contact01() {
	contact con;
	ContactInit(&con);
	//往通讯录中插入数据
	ContactAdd(&con);
	ContactDistory(&con);
	}
//}
int main() {
	//SLtest();
	//SLtest02();
	contact01();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android性能优化,可以从那些方面解决?方案一览

说到Android性能优化大家都很熟悉&#xff0c;这是一个老生畅谈的话题与技术。本篇讲讲Android性能优化需要学习那些&#xff0c;让这些技术做到极致。虽然老生常谈但是一直是一个合格的Android开发人员需要掌握的重点。要想进入大厂也是重要的敲门砖。 Android性能优化重要性…

【FreeRTOS】【STM32】02 FreeRTOS 移植

基于 [野火]《FreeRTOS%20内核实现与应用开发实战—基于STM32》 正点原子《STM32F429FreeRTOS开发手册_V1.2》 准备 基础工程&#xff0c;例如点灯 FreeRTOS 系统源码 FreeRTOS 移植 上一章节已经说明了Free RTOS的源码文件在移植时所需要的&#xff0c;FreeRTOS 为我们提供…

leetcode:1967. 作为子字符串出现在单词中的字符串数目(python3解法)

难度&#xff1a;简单 给你一个字符串数组 patterns 和一个字符串 word &#xff0c;统计 patterns 中有多少个字符串是 word 的子字符串。返回字符串数目。 子字符串 是字符串中的一个连续字符序列。 示例 1&#xff1a; 输入&#xff1a;patterns ["a","abc&…

AlGaN/GaN结构的氧基数字蚀刻

引言 宽带隙GaN基高电子迁移率晶体管(HEMTs)和场效应晶体管(fet)能够提供比传统Si基高功率器件更高的击穿电压和电子迁移率。常关GaN非常需要HEMT来降低功率并简化电路和系统架构&#xff0c;这是GaN HEMT技术的主要挑战之一。凹进的AlGaN/GaN结构是实现常关操作的有用选择之一…

使用IDEA自带功能将WSDL转java

好像IDEA2018版本之后不再支持webservice转java&#xff0c;可以下载2018.3.6版本的IDEA&#xff08;直接IDEA官网下载即可&#xff09;&#xff0c;然后打开一个项目&#xff0c;在根目录处单击右键 选择Generate Java Code From Wsdl...&#xff0c; 选择OK&#xff0c;即可…

二、DMSP/OLS夜光数据校正之饱和校正

一、前言 首先需要将DMSP/OLS夜光数据下载,那么这里方便大家,可以直接私信我获得DMPS/OLS和NPP/VIIRS夜光原始数据,以百度云网盘形式分享给大家。 当把34期DMSP/OLS夜光数数据下载至电脑之后,解压后可以看到如下图的数据。 选择稳定平均灯光数据作为我们研究数据,也就是F…

MYSQL的事务原理

事务基础 事务概念 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务特性 原子性&#xff08;Atomicity&#xff09…

中兴通讯加入 “数字孪生网络基础框架”开源合作计划

在近日举行的“预见未来——数字孪生网络&#xff08;DTN&#xff09;”分论坛上&#xff0c;中国移动研究院不仅发布了“数字孪生网络基础框架”成果&#xff0c;同时与中兴通讯等合作伙伴正式启动了“数字孪生网络基础框架”开源&#xff08;Open-DTN&#xff09;合作计划。 …

基于SSM的国学文化网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Lenovo联想笔记本IdeaPad YOGA 710-11IKB(80V6)原装出厂Win10系统镜像

下载链接&#xff1a;https://pan.baidu.com/s/1qAJ6QSQ0NV1Lmwv3YTqwHw?pwdrqxa 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1a;9.62GB 注&#xff1a;…

API攻防-接口安全SOAPOpenAPIRESTful分类特征导入项目联动检测

文章目录 概述什么是接口&#xff1f; 1、API分类特征SOAP - WSDLWeb services 三种基本元素&#xff1a; OpenApi - Swagger UISpringboot Actuator 2、API检测流程Method&#xff1a;请求方法URL&#xff1a;唯一资源定位符Params&#xff1a;请求参数Authorization&#xff…

关键词搜索1688商品列表数据接口,1688商品列表数据接口

在网页抓取方面&#xff0c;可以使用 Python、Java 等编程语言编写程序&#xff0c;通过模拟 HTTP 请求&#xff0c;获取1688网站上的商品页面。在数据提取方面&#xff0c;可以使用正则表达式、XPath 等方式从 HTML 代码中提取出有用的信息。值得注意的是&#xff0c;1688网站…

docker--使用docker login 报错解决方案

我们在本地使用 docker login 命令登录时报错&#xff0c;可以尝试一下先 docker logout 命令退出登录后&#xff0c;在使用 docker login命令进行登录操作&#xff1b; docker logout

OpenCV4(C++)—— 直方图

文章目录 前言一、计算直方图二、归一化三、直方图均衡化四、直方图匹配 前言 直方图(Histogram)最开始在统计学中被提出&#xff0c;由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型&#xff0c;纵轴表示分布情况。在图像领域&#xff0c;直方…

vue3+ts项目03 element-plus、vue-router、pinia

yarn add element-plus yarn add element-plus/icons-vue修改main.ts import { createApp } from vue import App from ./App.vueimport ElementPlus from element-plus import element-plus/dist/index.css import zhCn from element-plus/dist/locale/zh-cn.mjsconst app c…

Arduino程序设计(十四)舵机控制实验(SG90)

舵机控制实验 前言一、SG90舵机1、SG90舵机简介2、硬件电路连线3、Servo库常用函数 二、舵机实验1、舵机0~180来回转动2、串口控制舵机转动固定角度 总结 前言 本文介绍SG90舵机控制原理及实验&#xff0c;主要内容有&#xff1a;1、介绍SG90舵机&#xff1b;2、舵机0~180来回…

Android---java内存模型与线程

Java 内存模型翻译自 Java Memory Model&#xff0c;简称 JMM。它所描述的是多线程并发、CPU 缓存等方面的内容。 在每一个线程中&#xff0c;都会有一块内部的工作内存&#xff0c;这块内存保存了主内存共享数据的拷贝副本。但在 Java 线程中并不存在所谓的工作内存&#xff0…

发行版兴趣小组季度动态:Anolis OS 支持大热 AI 软件栈,引入社区合作安全修复流程

发行版兴趣小组&#xff08;Special Interest Group&#xff09; &#xff1a;旨在为龙蜥社区构建、发布和维护一个稳定的操作系统发行版。 秋天的季节&#xff0c;发行版兴趣小组在 AI、安全、国产 OS 领域同样也是硕果累累。一起来看一下第三季度发行版兴趣小组的成果总结有…

IPv4报文头部

1、version&#xff08;版本&#xff09;:用于标识封装是IPv4还是IPv6 2、IHL&#xff08;头部长度&#xff09;&#xff1a;描述了数据包头的内容长度 3、Type of service&#xff08;服务类型&#xff09;&#xff1a;用于标识DSCP或IP优先级&#xff0c;用于Qos识别 4、T…

野火开发板使用FlyMcu一键ISP下载时

1.ISP 一键下载 野火开发板使用FlyMcu一键ISP下载时&#xff0c;记得拔掉JTAG那个20针的东西&#xff0c;要不然一直芯片超时不连接。 bsp:9600&#xff0c;使用共写入2KB,进度100%,耗时16641毫秒。 bsp:115200&#xff0c;共写入2KB,进度100%,耗时2188毫秒。 bsp:115200&#…