基于顺序表实现通讯录功能项目

本文通过顺序表实现通讯录的功能,增删查改数据

首先实现顺序表的功能,再用顺序表实现通讯录的功能

顺序表中的成员为一个结构体对象con,自定义的类型,里面包含着联系人的姓名性别年龄电话地址

seqlist.h:顺序表头文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"contact.h"//通讯录功能头文件,后面会加入
typedef con type;
typedef struct Seqlist {
    type* data;//顺序表存储的数据类型,此处为con,后续定义的结构体类型
    int size;//当前数据个数
    int capacity;//数据总容量
}sl;
//初始化顺序表
void initialize(sl* ps);
//销毁线性表
void destory(sl* ps);
//判断是否满员;
void isfull(sl* ps);
//头插数据
void headinsert(sl* ps,type c);
//尾插数据
void tailinsert(sl* ps,type c);
//头删数据
void headdelete(sl* ps);
//尾删数据
void taildelete(sl* ps);
//删除指定数据
void delete(sl* ps,int p);
 

seqlist.c:顺序表功能实现文件

#include"seqlist.h"
void initialize(sl* ps){//初始化顺序表
    ps->data = NULL;
    ps->size = ps->capacity = 0;
}
void destory(sl* ps) {//销毁顺序表
    if (ps->data) {
        free(ps->data);
        ps->data = NULL;
    }
    ps->size = ps->capacity = 0;
}
void isfull(sl* ps) {//判断顺序表是否满员,满了则扩容为原来容量的两倍
    assert(ps);//ps不能为野指针
    if (ps->size == ps->capacity) {//如果当前数量达到容量
        int newcapacity =ps->capacity== 0 ? 4 : 2 * ps->capacity;//未创建初始容量则是4,创建了则是扩容到当前容量的两倍
        type* p = (type*)realloc(ps->data, newcapacity * sizeof(type));//开辟空间
        if (p == NULL) {//开辟失败则退出
            perror("申请失败");
                return;
        }
        ps->data = p;//开辟空间成功则指针重新赋值保证有效;
        ps->capacity = newcapacity;//当前容量扩充成功
    }
}
void headinsert(sl* ps,type c) {//头插法
    assert(ps);//避免指针为空
    isfull(ps);//判断是否容量已满,满了则扩容
    for (int i = ps->size; i>=1; i--) {
        ps->data[i] = ps->data[i-1];
    }
    ps->data[0] =  c;
    ps->size++;

}
void tailinsert(sl* ps,type c) {//尾插法
    assert(ps);
    
    ps->data[ps->size++] = c;
}
void headdelete(sl* ps){//头删法
    if (ps->data) {
        for (int i = 0; i<=ps->size-2; i++) {
            ps->data[i] = ps->data[i + 1];
        }
        ps->size--;
    }
}
void taildelete(sl* ps){//尾删法
    assert(ps);
    ps->size--;

}

void delete(sl* ps,int p) {//删除指定位置数据
    assert(ps);
    assert(ps->size >= 0 && ps->size <= ps->capacity);//保证指针访问有效位置
    for (int i = p; i<=ps->size-2; i++) {
        ps->data[i] = ps->data[i + 1];
    }
    ps->size--;
    return;
}

顺序表功能已经实现完成,接下来实现通讯录功能,通讯录实质说顺序表,不同的名字,功能实质上和顺序表差不多,有细微差别 

contact.h:通讯录头文件

#pragma once
#define name_max 20
#define gender_max 20
#define tel_max 20
#define add_max 20
typedef struct person {
    char name[name_max];//名字
    char gender[gender_max];//性别
    int age;//年龄
    char tel[tel_max];//电话
    char address[add_max];//地址
}con;//定义的con结构体类型
typedef struct Seqlist contact;//前置申明,contact就是seqlist顺序表,不同名字而已
//通讯录初始化
void contactinit(contact* p);
//通讯录增加联系人
void contactadd(contact* p);
//删除联系人
int find(const contact* p,char*s);
void contactdel(contact* p);
//查找联系人
void contactsea(const contact*p);
//展示通讯录
void contactshow(contact p);
//更改通讯录
void contactmodify(contact* p);

//删除通讯录
void contactdestroy(contact* p);
 

contact.c:通讯录实现代码

#include"seqlist.h"
//通讯录初始化

void contactinit(contact* p) {
    initialize(p);//顺序表初始化
}
//通讯录增加联系人
void contactadd(contact* p) {
    assert(p);//避免野指针
    isfull(p);//判断数据是否满员,满了则扩容为两倍
    con f;//创建临时结构体用于存储接下来要输入的联系人信息
    printf("请输入要增加联系人姓名\n");
    scanf("%s", f.name);
    printf("请输入要增加联系人性别\n");
    scanf("%s", f.gender);
    printf("请输入要增加联系年龄\n");
    scanf("%d", &f.age);
    printf("请输入要增加联系人电话\n");
    scanf("%s", f.tel);
    printf("请输入要增加联系人地址\n");
    scanf("%s", f.address);
    headinsert(p, f);//我这里选择的是头插法增添数据
    printf("添加联系人成功!\n");
}
//查找联系人函数,查找成功返回该联系人下标
int find(const contact *p,char*s) {
    for (int i = 0; i < p->size; i++) {//遍历结构体成员data数组
        if (strcmp(p->data[i].name, s) == 0)return i;//找到则返回该联系人数组下标

    }
            return -1;//没找到则返回-1
}
void contactsea(const contact* p){//查找联系人
    char name[name_max];//存储接下来要输入的待查找人姓名
    printf("请输入你要查找的联系人姓名\n");
    scanf("%s", name);
    int ret = find(p, name);//增添ret变量存储查找函数得到的联系人数组下标
    if (ret >= 0) {//如果找到则打印该联系人
        printf("联系人姓名%s\t 联系人性别%s\t 联系人年龄%d\t ;联系人电话%s\t 联系人地址%s\t\n", p->data[ret].name, p->data[ret].gender, p->data[ret].age,p->data[ret].tel,p->data[ret].address);
        return;
    }
    else {
        printf("未找到该联系人\n");
        return;
    }

}
//删除联系人
void contactdel(contact* p) {
    char name[name_max];
    printf("请输入你要删除联系人的姓名\n");
    scanf("%s", name);
    int ret = find(p,name);//先找到要删除的联系人数组下标
    if (ret >= 0) {
        delete(p, ret);//顺序表删除指定位置元素
        printf("删除成功!\n");
        return;
    }
    else {
        printf("未找到该联系人\n");
        return;
    }
    
}
//展示通讯录
void contactshow(contact p) {//遍历整个通讯录
    for (int i = 0; i < p.size; i++) {
        printf("联系人姓名%s\t 联系人性别%s\t 联系人年龄%d\t ;联系人电话%s\t 联系人地址%s\t\n", p.data[i].name, p.data[i].gender, p.data[i].age, p.data[i].tel, p.data[i].address);
        
    }
    return;
}
//修改联系人
void contactmodify(contact* p) {
    char s[20] = { 0 };
    
    printf("请输入要修改的联系人姓名\n");
    scanf("%s", s);
    int ret = find(p, s);
    if (ret >= 0) {
        printf("请输入要修改后联系人姓名\n");
        scanf("%s", p->data[ret].name);
        printf("请输入要修改后联系人性别\n");
        scanf("%s", p->data[ret].gender);
        printf("请输入要修改后联系人年龄\n");
        scanf("%d", &p->data[ret].age);
        printf("请输入要修改后联系人电话\n");
        scanf("%s", p->data[ret].tel);
        printf("请输入要修改后联系人地址\n");
        scanf("%s", p->data[ret].address);
        printf("修改成功!\n");
    }
    else printf("没有改联系人");
    return;
}
void contactdestroy(contact* p) {//销毁通讯录
    destory(p);
}

 

通讯录功能已经全部实现,接下来测试并图形化页面

 

#include"seqlist.h"
void x() {
    printf("****************通讯录**********************\n");
    printf("***1添加联系人****************2删除联系人***\n");
    printf("***3查找联系人****************4更改联系人***\n");
    printf("***5展示联系人****************0退出*********\n");
    printf("********************************************\n");
    return;
}
int main() {
    contact p;//创建通讯录
    contactinit(&p);//通讯录初始化
    int a = -1;
    
    do {
        x();//打印菜单
        if (scanf("%d", &a) == 1) {//如果输入为1个整数

            switch (a)
            {
            case 1:
                contactadd(&p);//添加联系人
                break;
            case 2:
                contactdel(&p);//删除联系人
                break;
            case 3:
                contactsea(&p);//查找联系人
                break;
            case 4:
                contactmodify(&p);//修改联系人
                break;
            case 5:
                contactshow(p);//展示通讯录
                break;
            case 0://退出
                return 0;
                break;
            default://
                printf("输入错误,请重新输入!\n");
                break;
            }
        }
        else {//输入非整数的情况,如标点符号
            printf("请输入整数\n");
            while(getchar()!='\n');//输入非整数的情况,如标点符号,则情况缓冲区的字符
            continue;//跳过本次循环
        }

    }
    while (a!=0);

    contactdestroy(&p);
    return 0;
}

简单测试一下,都可以运行

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

摩尔线程 × 智汇云舟|打造视频孪生国产解决方案

近日&#xff0c;摩尔线程与国内数字孪生头部企业和视频孪生首倡者智汇云舟达成深度战略合作&#xff0c;双方将在技术融合、产品共创和市场推广领域加强合作&#xff0c;共同研发面向未来的视频孪生国产化解决方案&#xff0c;推动视频孪生技术在国内关键领域的应用落地&#…

闲置物品|基于SprinBoot+vue的校园闲置物品交易平台(源码+数据库+文档)

校园闲置物品交易平台 目录 基于SprinBootvue的校园闲置物品交易平台 一、前言 二、系统设计 三、系统功能设计 5.1系统功能实现 5.2管理员模块实现 5.3用户模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xf…

ZBrush入门使用介绍——11、边缘环

大家好&#xff0c;我是阿赵。   继续介绍ZBrush的用法。这次看看边缘环的使用方法。我个人的感觉&#xff0c;边缘环有点类似于3DsMax之类软件的挤出功能&#xff0c;可以沿着环形的面&#xff0c;添加凹凸效果。   边缘环工具入口在几何体编辑里面&#xff1a; 一、 边…

【python3.8安装报错】lmportError: DLL load failed while importing ft2font: 找不到指定的模块

客户需求背景&#xff1a; 安装python3.8无法运行&#xff0c;报错 lmportError: DLL load failed while importing ft2font: 找不到指定的模块 考虑兼容性问题 这个问题首先需要考虑的是是否是python版本太高了&#xff0c;因为python3.9不支持win7&#xff0c;而python3.8版…

arm64--异常处理与中断处理

一、异常等级 EL0 非特权模式&#xff0c;用于运行应用程序 EL1为特权模式&#xff0c;用于运行操作系统内核 EL2用于运行虚拟化管理程序 EL3用于运行安全世界的管理程序 二、同步异常与异步异常 1. 同步异常&#xff1a;处理器执行某条指令而直接导致的异常&#xff0c;…

有效提高媒体曝光率,智能推荐为什么是“最大的计算系统之一”?

导语&#xff1a;我认为很少有人意识到&#xff0c;推荐系统是世界上构想过的最大的计算系统之一。——Jensen Huang &#xfeff; 在信息过载的时代背景下&#xff0c;智能推荐系统已广泛应用于电子商务、社交媒体、新闻资讯、视频音乐、旅游出行等领域&#xff0c;为用户提…

力扣经典题目之->单值二叉树(递归判断)

一&#xff1a;题目 本博客采用此模型&#xff1a; 二&#xff1a;思路 单值二叉树即所有值相等的二叉树 1&#xff1a;递归的大事化小思路即&#xff1a; 将当前节点与它的左右子节点进行比较&#xff0c;如果不相等&#xff0c;则直接返回false。如果相等&#xff0c;则递归…

记一次 .NET某实验室自动进样系统 崩溃分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友在微信上联系到我&#xff0c;说他们的程序在客户那边崩掉了&#xff0c;让我帮忙看下怎么回事&#xff0c;dump也拿到了&#xff0c;那就上手分析吧。 二&#xff1a;WinDbg 分析 1. 哪里的崩溃 既然是程序的崩溃&#xff0c…

基于状态机实现WIFI模组物联网

1.0 状态机框架原理 如果成功的话就连接热点&#xff0c;如果失败就返回AT通信检查&#xff0c;如果AT通信检查还是失败就放回硬件复位这个状态&#xff0c;如果热点链接成功&#xff0c;就连接MQTT指令&#xff0c;如果失败就返回AT通信检查&#xff0c;如果成功就连接云平台通…

MySQL集群技术

一、MySQL部署 1.源码编译 实验环境为rhel7 安装依赖性 [rootmysql-node1 ~]# yum install cmake gcc-c openssl-devel \ ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el9_4.x86_64.rpm rpcgen.x86_64 -y [rootmysql-node1 ~]# tar zxf mysql-boost-5.7.44.tar.gz 源码…

达梦数据库的系统视图v$object_usage

达梦数据库的系统视图v$object_usage 在达梦数据库&#xff08;DM Database&#xff09;中&#xff0c;V$OBJECT_USAGE 视图提供了关于数据库对象的使用情况和统计信息。这些对象可以包括表、索引、视图、存储过程等。通过 V$OBJECT_USAGE 视图&#xff0c;数据库管理员可以监…

贵金属市场展望:黄金独领风骚,钯金、铂金与白银承压

黄金新高可期&#xff0c;避险魅力不减 黄金市场持续升温&#xff0c;近期价格屡创新高。随着全球经济不确定性增加及美联储降息预期的增强&#xff0c;黄金的避险属性得到进一步凸显。市场普遍预期&#xff0c;若美联储在年内维持宽松货币政策&#xff0c;黄金价格有望继续上扬…

新迪天工®看图,专业的三维CAD看图工具

替代专业CAD软件&#xff0c;方便查看各种三维和二维CAD图纸 新迪天工看图是一款功能强大的三维模型和二维图纸查看工具&#xff0c;能帮助制造企业以较低的成本、较高的数据安全性实现产品设计数据的跨业务浏览和交互。 应用场景 1、设计图纸评审 可直接对三维模型和二维…

【数据结构】—— 树和二叉树

1、树的概念2、树的相关术语3、树的常见表示方法4、树的实际应用5、二叉树的相关概念和性质6、二叉树的顺序存储&#xff08;堆&#xff09;6.1 堆的概念6.2 堆的结构和接口6.3 堆的初始化和销毁6.4 堆的插入6.5 堆的删除6.5 取堆顶数据6.6 获取有效节点个数6.7 判空6.8 源代码…

高并发业务下的库存扣减技术方案设计

扣减库存需要查询库存是否足够: 足够就占用库存不够则返回库存不足&#xff08;这里不区分库存可用、占用、已消耗等状态&#xff0c;统一成扣减库存数量&#xff0c;简化场景&#xff09; 并发场景&#xff0c;若 查询库存和扣减库存不具备原子性&#xff0c;就可能超卖&…

动态内存管理函数malloc,calloc,realloc,free

malloc 函数原型&#xff1a;void* malloc(size_t size); 这个函数向内存申请一块连续可用的size大小的空间&#xff0c;并返回指向这快空间的指针。如果开辟成功&#xff0c;则返回一个指向开辟好空间的指针。如果开辟失败&#xff0c;则返回一个NULL指针&#xff0c;因此ma…

Facebook AI策略全解:从数据分析到智能推荐的成功秘诀

在数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为推动科技发展的核心力量。Facebook&#xff0c;作为全球领先的社交网络平台&#xff0c;正通过先进的AI策略来优化用户体验和平台运营。从数据分析到智能推荐&#xff0c;Facebook的AI策略涵盖了多个方面&…

Git 分支操作全解析:创建、切换、合并、删除及冲突解决

“ 在现代软件开发中&#xff0c;高效的版本控制是确保项目成功的关键。Git 提供了强大的分支管理功能&#xff0c;使得开发者能够独立地进行功能开发、修复 bug 和进行紧急修补。本文将深入探讨 Git 分支的基本操作&#xff0c;包括创建、切换、合并和删除分支&#xff0c;同时…

Linux基础 - yum、rzsz、vim 使用与配置、gcc/g++的详细解说

目录 一、Linux 软件包管理器 yum A.什么是软件包&#xff1f; B.关于rzsz&#xff0c;yum的配置 1.安装 sz&#xff0c;rz 命令&#xff1a; a.执行命令sz可将linux中的文件传输到Windows中 b.执行rz命令可将Windows中的文件传输到linux 2.scp XXX.tgz 用户名另一台lin…

免费高画质提取PPT/Word/Excel中的图片工具

下载地址&#xff1a;https://pan.quark.cn/s/134ccc35b8a2 软件简介&#xff1a; 好不容易搞到一个几十上百MB的ppt&#xff0c;想导出里面的图片进行二次加工&#xff0c;却被ppt超低画质的图片另存为功能劝退&#xff0c;明知里面全是高清图片&#xff0c;走时却是两手空空…