0基础学C++ | 第09天 | 基础知识 | 结构体指针 | switch结构 | 通讯管理系统案例练习

news2024/7/6 20:34:06

前言

这个案例相当于是对前面所学的结构体、数组、switch结构等知识进行的一个总结

功能实现

该案例是要求完成一个通讯管理系统,包括添加联系人、查找联系人、修改联系人信息等能够。通讯录最多联系人不能超过1000,因为在本案例中通讯录涉及两个数据类型(一个是联系人(结构体数组),另一个是联系人的数量(int型)),所以用结构体数据类型来构建通信录这个变量,

另外,联系人涉及到姓名、性别、电话号码等多个数据类型,同时,联系人有多个,所以采用结构体数组类型来构建联系人,最终采用结构体嵌套的方式来设计在这个管理系统的变量,定义好变量后,就开始封装各个功能函数(例如删除、查找、修改等)。下面就是具体的实现代码。

创建联系人结构体

首先构建联系人结构体,该结构体包含姓名、性别、年龄(这里用1表示女性,2表示男性)、电话号码、家庭地址等属性。

结构体的创建语法:

struct 结构体名 { 结构体成员列表 };

//创建联系人结构体
struct Person
{
    string name;
    int m_Sex; //1 男 2 女
    int m_Age;
    string m_Phone;
    string m_Addr;
};

创建通讯录结构体

通讯录结构体中的成员主要就是联系人以及联系人的数量,联系人也是一个结构体,它是嵌入在通讯录结构体中的,这里的 struct person就相当于是一个数据类型(结构体类型)personArray就是变量名,这里就是一个结构体数组类型的数据 ,personArray这个变量就包含了其Person结构体中的所有元素。

//创建通讯录结构体
struct Addressbooks
{
    struct Person personArray[MAX];//通讯录中保存的联系人数组
    int m_Size;//通讯录中人员个数
};

显示菜单 

我们首先要写个菜单来供用户选择,这个显示菜单就是单纯的显示有哪些功能,具体实际的选择功能要使用下面的switch来实现。这里一共实现了7个功能选项,只需要在页面打印出每个选项的就可以。

//首先是显示菜单功能
//创建一个函数来显示菜单功能
 void showMenu()
{
    cout << "1、添加联系人" << endl;
    cout << "2、显示联系人" << endl;
    cout << "3、删除联系人" << endl;
    cout << "4、修改联系人" << endl;
    cout << "5、查找联系人" << endl;
    cout << "6、清空联系人" << endl;
    cout << "0、推出通讯录" << endl;
}

选项功能实现以及推出功能 (使用switch)

要是实现更具选项的不同,进入不同的功能,就要用到switch,例如当我输入1时,就进行添加联系人操作,选择0时,就退出整个通讯录。

这里的退出机制,就用了前面讲的system("pause"),这条语句是命令程序运行到这一步停止的语句。 另外这里的关于管理系统最多只能1000人的数量,采用了宏定义,因为这样方便系统的维护,如果最多可以有2000人,这时就只用改其前面宏定义的部分

#include<iostream>
using namespace std;
#include<string>

#define MAX 1000 //通讯录联系人数最多为1000 用宏定义是为了方便维护

int main()
{

    //搭建选择选项,这里用switch来判断多种情况选一种
    //首先定义一个输入选择的变量  
    int select = 0;
    cin >> select;

    //为了每次都能返回菜单,所以需要一个循环,只有当输入0的时候才会推出这个
    while(ture)
    {
        switch(select)
        {
            case 1:     //1、添加联系人
                addPerson(&abs); //利用地址传递,可以修饰实参
                break;
            case 2:    //2、显示联系人
                break;
            case 3:    //3、删除联系人
                break;

            case 4:    //4、修改联系人
                break;
    
            case 5:    //5、查找联系人
                break;

            case 6:    //6、清空联系人
                break;

            case 0:    //0、推出通讯录
                cout << "欢迎下次使用"<<endl;
                systrm("pause");
                return 0;
                break;
            default:
                break;
        }  
    }  

    syetrm("pause");
    return 0;

}

添加联系人 

封装一个添加联系人的函数,函数传入的参数是整个通讯录结构体的地址,这里为什么是指针呢,因为结构体指针才能修改实参。Addressbook * abs 是一个用指针接收的参数,abs 是我们创建的结构体变量,这个变量他指向任何一个Addressbook类型的结构体,同时,使用  ->  符号来取得Addressbook的一个成员 (我也还没搞明白结构体指针)

定义了结构体:

struct Person{ ... }; //联系人结构体

struct  Addressbook //通讯录结构体

{

       struct Person personArray[MAX]; 

};


Addressbooks abs;//创建结构体变量

void addPerson(Addressbooks * abs)  //定义的添加联系人的函数,

int age = addPerson(&abs)//传递过去, &取地址

abs->personArray[abs->m_Size].m_Name = name;//获取Addressbook中personArray的第m_Size个m_Name成员,并赋予它name值

添加联系人前 ,首先我们要进行判断通讯录人数是否满了(也就是达到了1000人),所以对m_Size(m_Size是通讯录的人数)进行判断是否等于MAX(MAX就是我们宏定义的1000),如果没满,就进行添加操作,包括添加姓名、性别、年龄等,这里其实就是对我们通讯录结构体中的联系人变量(personArray)进行实例化,实例化方式就是通过->符号来获取联系人结构体里的每个成员,并赋值。添加完成之后,不要忘了更新通讯录的人数,也就是更新m_Size(因为添加一个人,m_Size就少一个,所以是 m_Size - - ),最后使用 system("cls")语句来清屏。

//封装添加联系人函数
void addPerson(Addressbooks * abs)
{
    if(abs->m_Size==MAX)
    {
        cout << "通讯录已满,无法添加 "<< endl;
    }
    else
    {
        //添加具体联系人
        //姓名
        string name;
        cout << "请输入姓名:"<<endl;
        cin >> name;
        abs->personArray[abs->m_Size].m_name = name;

        //性别
        int sex == 0;
        cout << "请输入性别:"<<endl;
        cout << "1 -- 男"<<endl;
        cout << "2 -- 女"<<endl;
      
        while(ture)
        {  
            cin >> sex;
            if(sex == 1 || sex == 2)
            {
                   abs->personArray[abs->m_Size].m_sex = sex;
                   break;
             }
             cout << "输入有误,请重新输入"<<endl;
        }

        //年龄
        int age == 0;
        cout << "请输入年龄:"<<endl;
        cin >> age;
        abs->personArray[abs->m_Size].m_age = age;

        //电话
        string phone;
        cout << "请输入电话:"<<endl;
        cin >> phone;
        abs->personArray[abs->m_Size].m_phone = phone;

        //住址
        string address;
        cout << "请输入家庭住址:"<<endl;
        cin >> address
        abs->personArray[abs->m_Size].m_Addr = address;
        
        //更新人数
        abs->m_Size++;
        cout <<"添加成功"<< endl;
        system("cls"); //清屏操作
    }
}

显示联系人 

添加联系人后,我们可以选择对联系人进行显示,当然没添加也可以进行显示,那么在显示之前就需要判断通讯录的人是否为空,也就是m_Size是否为0,如果不是我们就依次打印联系人的信息,因为不只一个联系人 所以我们要使用for循环来依次打印,注意:在性别那一行,因为我们规定的是1为女 2为男 为了方便,所以用了 a?b:c这个运算符 (如果a为真则取b 否则取c)。


​//封装显示联系人函数
int showPserson(Addressbook * abs)
{
    //判断通讯录中人数是否为0
    //如果不为空,就显示联系人的信息
    if(bas->personArray[i].m_Size == 0)
    {
        cout << "通讯录为空" << endl; //找到了,返回这个人在数组中的位置
    }
    else
    {
        for(int i = 0; i < abs->m_Size;i++)
        {
            
            cout << "姓名:" << abs->personArray[i].m_Name << \t;
            cout << "性别:" << abs->personArray[i].m_Sex ==1?"女":"男"<< \t;
            cout << "年龄:" << abs->personArray[i].m_Age << \t;
            cout << "电话:" << abs->personArray[i].m_Phone << \t;
            cout << "住址:" << abs->personArray[i].m_Address << endl;
        }
    }
   
    system("pause");
    system("cls");
  
}

检测联系人是否存在

检测联系人是否存在先对来说就要简单很多,只需要判断输入的名词和数组里的名字是否相等。

​
​//封装检测联系人是否在函数,如果存在 返回联系人在数组中的具体位置,如果不存在,则返回-1
int isEist(Addressbook * abs,string name)
{
    for(int i = 0; i < abs->m_Size;i++)
    {
        if(bas->personArray[i].m_Name == name)
        {
            return i; //找到了,返回这个人在数组中的位置
        }
    }

    system("pause");
    system("cls");
  
}

 实现删除指定的联系人

删除联系人需要先判断联系人是否存在,这里需要用到上面的函数isEist,如果存在,我们只需要找到该名字的下标(m_Szie)然后用后面的数据将前面的数据进行覆盖就OK了,其实就是将 i+1的值赋给 i 就好了。

//创建删除联系人函数
void deletePerson(Addressbooks *abs)
{
    cout <<"请输入要删除的人的名字:"<< endl;
    string name;
    cin >> name;

    //-1没查到,1 查到了
    int ret = isExist(abs,name)
    if(ret != -1)
    {
        //查找到人,进行删除
        for(int i = 0; i < abs->m_Size)
        {    
            //数据前移
            abs->personArray[i] = abs->personArray[i+1];
        }
        abs->m_Size--;    //更新通讯录联系人的人数
        cout << "删除成功" << endl;
        
    }
    else
    {
        cout << " 杳无此人" << endl;
        system("pause");
        system("cls");
    }
} 

实现查找联系人功能

查找联系人也需要判断联系人是否存在,然后利用姓名的数组下标 来获取其他的信息(性别、年龄等)

//封装查找函数
void findPerson(Addressbook * abs)
{
     cout << "请输入查找联系人的姓名:" <<endl;
    string name;
    cin name;
  
    //-1没查到,1 查到了
    int ret = isExist(abs,name)

    if(ret != -1)
    {
        //查找到人,输出相关信息
        cout << "姓名:" << abs->personArray[ret].m_Name << endl;
        cout << "性别:" << abs->personArray[ret].m_Sex << endl;
        cout << "年龄:" << abs->personArray[ret].m_Age << endl;
        cout << "电话:" << abs->personArray[ret].m_Phone << endl;
        cout << "住址:" << abs->personArray[ret].m_Address << endl;
      
    }
    else
    {
        cout << " 杳无此人" << endl;
    }
    system("pause");
    system("cls");  
}

实现修改联系人

同样,修改联系人也需要判断联系人是否存在,然后利用联系人姓名的数组下标来修改联系人的其他信息,修改信息,只需要将输入的数据赋值给原先的值就可以了,这里只是性别那需要进行判断,只能输入 1或2,属于其他的话是没有效的。

​//封装修改函数
void modifyPerson(Addressbook * abs)
{
    cout << "请输入修改联系人的姓名:" <<endl;
    string name;
    cin name;
  
    //-1没查到,1 查到了
    int ret = isExist(abs,name)

    if(ret != -1)  //查找到人,修改相关信息
    {
        //修改姓名
        string name;
        cout << "请输入姓名:" << endl;
        cin >> name;
        abs->personArray[ret].m_Name = name;

        //修改性别
        cout << "请输入性别:" << endl;
        cout << "1---女" << endl;
        cout << "2---男" << endl;
        int sex= 0;
        while(true)
        { 
            cin >> sex;
            if(sex == 1 || sex == 2)
            {
               abs->personArray[ret].m_Sex = sex;
               break; 
            }
            else
            {
                 cout << "输入有误,请重新输入年龄:" << endl;
            }
        
        }
       
        //修改年龄
        cout << "请输入年龄:" << endl;
        int age = 0;
        cin >> age;
        abs->personArray[ret].m_Age = age;

        //修改电话
        string phone;
        cout << "请输入电话:" << endl;
        cin >> phone;
        abs->personArray[ret].m_Phone = phone;

        //修改住址
        string address;
        cout << "请输入住址:" << endl;
        cin >> address;
        abs->personArray[ret].m_Address = address;
        cout << " 修改成功!" << endl;
    }
    else   //未查找到联系人
    {
        cout << " 杳无此人" << endl;
    }

    system("pause");
    system("cls");
  
}

清空联系人

清空联系人 ,这里使用了一个比较暴力的手段,就是直接将通讯录的大小改为了0(m_Size = 0)

​//封装清空函数
void cleanPerson(Addressbook * abs)
{
    abs->m_Size = 0;
    cout << "通讯录已清空" << endl;
    system("pause");
    system("cls");
  
}

整体系统实现(函数调用)

整个功能实现后,也就是功能函数封装好以后,就是在主函数里调用这些功能函数。将实参传进函数体就可以了

​
#include<iostream>
using namespace std;
#include<string>

#define MAX 1000 //通讯录联系人数最多为1000 用宏定义是为了方便维护

int main()
{
    showMenu(); //调用菜单显示函数

    //创建结构体变量
    Addressbooks abs;

    //初始化通讯录中当前人员个数
    abs.m_Size = 0;

    //搭建选择选项,这里用switch来判断多种情况选一种
    //首先定义一个输入选择的变量  
    int select = 0;
    cin >> select;

    //为了每次都能返回菜单,所以需要一个循环,只有当输入0的时候才会推出这个
    while(ture)
    {

        switch(select)
        {
            case 1:     //1、添加联系人
                addPerson(&abs); //利用地址传递,可以修饰实参
                break;
            case 2:
                showPerson(&abs)    //2、显示联系人
                break;
            case 3:    //3、删除联系人
                deletePerson(&abs)
                break;

            case 4:    //4、修改联系人
                modifyPerson(&abs)
                break;
    
            case 5:    //5、查找联系人
                findPerson(&abs)
                break;

            case 6:    //6、清空联系人
                cleanPerson(&abs)
                break;

            case 0:    //0、推出通讯录
                cout << "欢迎下次使用"<<endl;
                systrm("pause");
                return 0;
                break;

            default:
                break;
        }  
    }  

    syetrm("pause");
    return 0;

}

​

 以上就是整个通讯录管理系统的实现,主要还是指针部分还有点反应不过来,后面继续理解一下。

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

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

相关文章

swiftui中常用组件picker的使用,以及它的可选样式

一个可选项列表就是一个picker组件搞出来的&#xff0c;它有多个样式可以选择&#xff0c;并且可以传递进去一些可选数据&#xff0c;有点像前端页面里面的seleted组件&#xff0c;但是picker组件的样式可以更多。可以看官方英文文档&#xff1a;PickerStyle | Apple Developer…

1分钟了解,预写日志WAL的核心思路...

上一篇《刷盘&#xff0c;还是不刷盘&#xff0c;是一个问题》中我们遇到了哪些问题&#xff1f; 1. 已提交事务未提交事务的ACID特性怎么保证&#xff1f; 画外音&#xff1a;上一篇中遇到的问题&#xff0c;主要是原子性与持久性。 2. 数据库崩溃&#xff0c;怎么实施故障恢复…

Python28-5 k-means算法

k-means 算法介绍 k-means 算法是一种经典的聚类算法&#xff0c;其目的是将数据集分成 ( k ) 个不同的簇&#xff0c;每个簇内的数据点尽可能接近。算法的基本思想是通过反复迭代优化簇中心的位置&#xff0c;使得每个簇内的点与簇中心的距离之和最小。k-means 算法的具体步骤…

如何使用ECharts和Java接口实现可视化的数据挖掘

如何使用ECharts和Java接口实现可视化的数据挖掘 【引言】 随着大数据时代的到来&#xff0c;数据挖掘成为了一项重要的技术&#xff0c;在企业决策、市场分析等领域发挥着重要作用。数据挖掘需要将大量的数据进行分析和展示&#xff0c;而可视化是一种直观、形象的展示方式。…

【kafka】可视化工具cmak(原kafka-manager)安装问题解决

众所周知&#xff08;反正不管你知不知道&#xff09;&#xff0c;kafka-maneger更名了&#xff0c;现在叫cmak&#xff01;原因是什么呢&#xff1f;据不可靠小道信息说&#xff0c;原kafka-manager这个名字涉及到kafka商标使用问题&#xff0c;应该是被律师函警告了&#xff…

DeepFaceLive----AI换脸简单使用

非常强大的软件,官方github https://github.com/iperov/DeepFaceLive 百度云链接: 链接&#xff1a;https://pan.baidu.com/s/1VHY-wxqJXSh5lCn1c4whZg 提取码&#xff1a;nhev 1下载解压软件 下载完成后双击.exe文件进行解压.完成后双击.bat文件打开软件 2 视频使用图片换…

零基础入门GIS开发,必看实用教程【附智慧校园实战笔记源码】

GIS开发也叫webgis&#xff0c;web就是指网页端&#xff0c;所以GIS开发大部分情况下是指网页端的地图可视化开发。 因此GIS开发需要学习前端开发HTML/CSS/JS&#xff0c;以及一些常见的前端框架&#xff0c;例如vue和react等&#xff08;新中地教育通常是教vue&#xff0c;其…

【Kafka】记录一次Kafka消费者重复消费问题

文章目录 现象业务背景排查过程Push与Pull 现象 用户反馈消费者出现消息积压&#xff0c;并且通过日志看&#xff0c;一直重复消费&#xff0c;且没有报错日志。 业务背景 用户的消费者是一个将文件做Embedding的任务&#xff0c;&#xff08;由于AI技术的兴起&#xff0c;大…

Windows下Visual Studio 中配置第一个CUDA工程

今天整NVIDIA 的CUDA 安装和第一个CUDA 代码&#xff0c;顺便添加一个有CUDA工程的空框架。 &#xff08;1&#xff09;首先确认自己的CUDA 已经安装成功 >>cmd 进入命令窗&#xff0c;在窗口输入查看cuda 是否安装成功&#xff0c;能查到CUDA的版本号&#xff0c;表示安…

2.WeBASE一键部署

一、官方文档 一键部署可以在 同机 快速搭建WeBASE管理台环境&#xff0c;方便用户快速体验WeBASE管理平台。 一键部署会搭建&#xff1a;节点&#xff08;FISCO-BCOS 2.0&#xff09;、管理平台&#xff08;WeBASE-Web&#xff09;、节点管理子系统&#xff08;WeBASE-Node-…

统计信号处理基础 习题解答11-11

题目 考虑矢量MAP估计量 证明这个估计量对于代价函数 使贝叶斯风险最小。其中&#xff1a;, &#xff0c;且. 解答 贝叶斯风险函数&#xff1a; 基于概率密度的非负特性&#xff0c;上述对积分要求最小&#xff0c;那就需要内层积分达到最小。令内层积分为&#xff1a; 上述积…

视频批量剪辑一键垂直翻转,轻松转换格式为mov,视频制作从此事半功倍!

在视频制作的海洋中&#xff0c;我们时常需要面对各种挑战&#xff0c;其中之一就是视频的翻转与调整。不论是出于创意需求还是格式转换的需要&#xff0c;视频翻转都是一个不可或缺的功能。今天&#xff0c;我要向大家介绍一款真正的批量视频翻转神器——视频剪辑高手&#xf…

Python高速下载及安装的十大必备事项与C++联调

选择正确的版本&#xff1a; 访问Python官网&#xff08;https://www.python.org/&#xff09;下载最新稳定版本&#xff0c;目前最新稳定版本为3.12.4 避免下载并安装Python 2.x版本&#xff0c;因为它已经停止维护。 选择适合操作系统的安装包&#xff1a; 根据你的操作系…

2.4 C#开发环境 xml格式保存参数----范例实现

2.4C#开发环境 xml格式保存参数----范例实现 1 程序参数保存目录层次说明 1 选择程序号| 相机号|窗口号 2 导入参数&#xff1a;就会从本地目录读取参数&#xff0c;并且显示图片和ROI 3 保存参数&#xff1a;把当前控件图片和ROI信息保存到指定程序号|相机号|窗口号中 2 参数…

Xilinx FPGA:vivado单端RAM实现输出偶数(单端RAM的简单应用)

一、实验步骤 &#xff08;1&#xff09;先创建一个工程 &#xff08;2&#xff09;调用IP资源找到RAMs&ROMs&BRAMs&#xff0c;选择其中的块资源 &#xff08;3&#xff09;修改配置参数 timescale 1ns / 1ps //写入0-99的数据&#xff0c;读出偶数 module single_ra…

MeEdu网校系统搜索功能问题处理

MeEdu通过 MeiliSearch 实现全文搜索服务。 一、下载 MeiliSearch 程序 https://github.com/meilisearch/MeiliSearch/releases/tag/v0.24.0 只能下载 v0.24.0 版本&#xff0c;其版本不支持 下载 meilisearch-linux-amd64就可以了 二、上传 MeiliSearch 三、启动命令如下…

如何用简单的html,css,js写出一个带有背景层的删除弹出框

虽然每次项目都是主要写后端&#xff0c;但是有时候前端的样式太丑了&#xff0c;也有点看不下去。弹出框是项目中用的比较多的&#xff0c;比如删除&#xff0c;修改或者添加什么的&#xff0c;都需要一个弹出框。 所以这里简单记录一下&#xff0c;应该如何实现。实现效果如…

threejs 微信小程序原生版本的使用 obj模型的加载

直接上代码&#xff0c; <canvas class"webgl" type"webgl" id"gl" bindtouchstart"onTX" bindtouchend"onTX" bindtouchmove"onTX" style"width:100vw;height:90vh"></canvas> const co…

手写starter写核心

文章目录 使用cn.smart 不能使用com 避免在yml配置的时候 开启或者 写万能接口实现调整日志级别写了core核心 但是没有引入其他功能组件,就是注解可以使用但是功能没有增,所以core的作用就是写入注解从新写starter 第一步提取注解 写到核心包里面,看其他包 新建模块 使用cn.s…

5分钟教你部署MySQL8.0环境

此方法基于Windows操作系统&#xff01; 一、在MySQL官网单击downloads&#xff08;下载&#xff09;MySQLhttps://www.mysql.com/cn/ 选择在Windows操作系统下载 二、选择合适的版本 推荐下载第二种&#xff0c;安装时离线安装即可 三、安装MySQL8.0 1、找到MySQL下载完成…