java转c++的第三天,写完了人生中的第一个c++小程序,啥也不说了,直接贴源码:

注释里面是我写的时候的一些思考和写完之后的经验教训,给自己和其他初学c++的猿友们加油!

//教训:
//①(已改进!)代码复用度不够高,可以多新建几个局部函数(尤其是查找函数),或者是把这些函数添加进类里,
//就像Java一样,面向对象编程
//②(未改进!)用结构体来实现结点会好一些。
//③注意new (在堆区)和直接定义类(局部函数在栈上)的区别
//④区别指针和应用和对象本体的区别,特别是要注意有些不应该更改形参的地方,应该使用引用或者是const。
//⑤注意删除的时候一定要先令temp_2 =temp_1,temp_1 = temp_nextNode,最后再delete temp_2.否则会出现逻辑错误。
//⑥注意使用对象时用“.”使用对象的指针时用“->”
//⑦该通信录没有加入去重功能

需要源码的人直接从下面开始粘贴就好,把源码粘贴到编译器里就方面阅读了,第一次写博客,嫌麻烦,不想排版了。

#include<iostream>
#include <vector>

using namespace std;
//联系人链表
//使用类而不是结构体
class Person
{
    //默认是private权限,为了使外部程序可以访问应该写成public权限
public:
    string name;
public:
    string sex;
public:
    int age;
public:
    string num;
public:
    string addr;

//运算符重载,判断两个person对象是否相等
    bool operator==(Person &a)//注意这里面使用引用比使用指针好,不会修改数据,
    {
        if (this->name == a.name && this->sex == a.sex &&
            this->age == a.age && this->num == a.num && this->addr == a.addr)
            return true;
        else
            return false;
    }

//修改函数
public:
    void revise() {
        cout << "请输入联系人姓名:" << endl;
        cin >> this->name;
        cout << "请输入联系人性别:" << endl;
        cin >> this->sex;
        cout << "请输入联系人年龄:" << endl;
        cin >> this->age;
        cout << "请输入联系人电话号码:" << endl;
        cin >> this->num;
        cout << "请输入联系人地址:" << endl;
        cin >> this->addr;
    }
    //构造函数1
public:
    Person(string name, string sex, int age, string num, string addr)
        :name(name), sex(sex), age(age), num(num), addr(addr)
    {
        cout << "成功新建联系人"<<name<<"!" << endl;
    }
    //构造函数2
public:
    Person(){}
        
    //析构函数
public:
    ~Person() { ; }
};
class PersonList {
    //注意这里一定要写成public,不然下一个结点新建或者删除时,无法修改这些数据
    //说明链表的结点还是用结构体会好一些
public:
    Person* val;//注意这里只是一个指针
public:
    PersonList* nextNode;//指向下一个结点的指针
public:
    PersonList* beforeNode;

//遍历到当前链表的最后一个节点
public:
    PersonList* toEnd()//返回指向最后一个节点的指针
    {
        PersonList* res = this;
        //cout << this;
        //cout << this->beforeNode;
        while (res->nextNode != NULL) {
            res = res->nextNode;
        }
        //cout << res;
        return res;
    }
public:PersonList(Person* val, PersonList* beforeNode)
{
    this->val = val;
    this->beforeNode = beforeNode;
    //cout << "当前的list" << this << endl;
    if (beforeNode)
    {
        //cout << "已经在前一个结点添加指向该节点的指针" << endl;
        beforeNode->nextNode = this;//让前一个节点的下一个节点指向当前的这个节点
        //cout << "当前的list" << this << endl;
        //cout << "beforeNode的nextNode"<< beforeNode->nextNode << endl;
        //cout << "beforeNode的地址" << beforeNode << endl;
    }

this->nextNode = NULL;

}
public:~PersonList() {
    //析构函数要完成:1.删除val指针指向的Person类 2.使上一个节点的nextNode指向当前nextNode
    //3.使下一个节点指向的beforeNode指向当前的beforeNode

delete this->val;//!!!万分注意,这里里面的delete要应用于一个指针。不然就会报错!
    //因为第一个节点的beforeNode是head,所以无需要考虑上一个节点是否为空
    (this->beforeNode)->nextNode = this->nextNode;
    if((this->nextNode) != NULL)
        (this->nextNode)->beforeNode = this->beforeNode;
    //test
    //cout << "调用了PersonList的析构函数" << endl;

}
};

//显示菜单
void showMenu() {
    cout << "***************************" << endl;
    cout << "*****  1、添加联系人  *****" << endl;
    cout << "*****  2、显示联系人  *****" << endl;
    cout << "*****  3、删除联系人  *****" << endl;
    cout << "*****  4、查找联系人  *****" << endl;
    cout << "*****  5、修改联系人  *****" << endl;
    cout << "*****  6、清空联系人  *****" << endl;
    cout << "*****  0、退出通讯录  *****" << endl;
    cout << "***************************" << endl;

}

//添加联系人
void addContact(PersonList* head) {

Person* ptr_person = new Person;
    //调用person类的修改函数来添加
    ptr_person->revise();
    
    //一定要用new,不然会在局部函数结束后自动析构掉局部函数创建的变量,因为直接
    //定义的话,该对象是在栈里新建的,局部函数执行完成之后,栈会自动弹出
    //如果是new,就是在堆区新建,不会自动析构
    
    new PersonList (ptr_person, head->toEnd());

cout << "将联系人"<< ptr_person ->name<<"成功添加到通信录!" << endl;
    
    
};

//显示联系人
void showContacts(PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通信录为空" << endl;
        return;
    }
    PersonList* temp = head->nextNode;
    cout << "通信录所有内容如下:" << endl;
    while (temp != NULL)
    {
        cout << temp->val->name << "  "
            << temp->val->sex << "  "
            << temp->val->age << "  "
            << temp->val->num << "  "
            << temp->val->addr << endl;
        temp = temp->nextNode;
    }
}

//查找联系人,注意应该先定义查找,这样才能方便在删除函数中使用查找函数
void searchContacts(PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待查找联系人的姓名:" << endl;
    cin >> person.name;

while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

//通过vector的大小来确定下一步操作
    if(arr.size() == 0)
    {
        cout << "当前通讯录无此人!" << endl;
        return;
    }
    else 
    {
        cout << "查找到:" << endl;
        for (int i = 0; i < arr.size(); i++)
        {
            cout << arr[i]->val->name << "  "
                << arr[i]->val->sex << "  "
                << arr[i]->val->age << "  "
                << arr[i]->val->num << "  "
                << arr[i]->val->addr << endl;
        }
    }
}

//删除联系人(在查找联系人基础上修改)
void deleteContact( PersonList* head) {
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

//删除联系人首先用名字寻找,如果遇到同名的,就要求用户输入更多详细信息
    Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待删除联系人的姓名:" << endl;
    cin >> person.name;

while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

//通过vector的大小来确定下一步操作
    switch (arr.size())
    {
    case 0:
        cout << "当前通讯录无此人!" << endl;
        return;
    case 1:
        delete arr[0];//delete会调用析构函数
        cout << "删除联系人" << person.name << "成功" << endl;
        return;
    default:
        cout << "存在" << arr.size() << "个同名联系人!输入0取消删除,输入1删除全部,输入2进行精确删除" << endl;
        break;
    }

//此时说明存在同名联系人
    int flag = 0;//标记删除了几个联系人
    int r;//标记下一步动作
    cin >> r;
    switch (r)
    {
    case 1:
        for (int i = 0; i < arr.size(); i++)
            delete arr[i];
        cout << "已经删除" << arr. size()<< "个联系人!" << endl;
        break;
    case 2:
        cout << "请输入该联系人性别:" << endl;
        cin >> person.sex;
        cout << "请输入该联系人年龄:" << endl;
        cin >> person.age;
        cout << "请输入该联系人电话号码:" << endl;
        cin >> person.num;
        cout << "请输入该联系人地址:" << endl;
        cin >> person.addr;

//这里要判断对象是否相等,使用运算符重载对两个对象进行直接判断
        
        for (int i = 0; i < arr.size(); i++)
        {
            if ((*arr[i]->val) == person)//由此可以看出解指针的优先级更低一些
            {
                delete arr[i];
                flag++;
            }
        }
        cout << "已经删除" << flag << "个联系人!" << endl;
        break;
    default:
        cout << "已经取消删除" << endl;
        return;
    }

}

//修改联系人(在删除函数基础上修改))
void reviseContacts(PersonList* head){
    if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

if (head->nextNode == NULL)
    {
        cout << "当前通讯录为空!" << endl;
        return;
    }

//删除联系人首先用名字寻找,如果遇到同名的,就要求用户输入更多详细信息
    Person person;
    vector<PersonList*> arr;//定义一个容器数组arr
    PersonList* temp = head->nextNode;//用temp来遍历数组
    cout << "请输入待修改联系人的姓名:" << endl;
    cin >> person.name;

while (temp != NULL)
    {
        if (temp->val->name == person.name)
            arr.push_back(temp);//向vector末尾添加元素
        temp = temp->nextNode;
    }

//通过vector的大小来确定下一步操作
    switch (arr.size())
    {
    case 0:
        cout << "当前通讯录无此人!" << endl;
        return;
    case 1:
        arr[0]->val->revise();//调用revise函数,复用代码
        cout << "修改联系人" << person.name << "成功" << endl;
        return;
    default:
        cout << "存在" << arr.size() << "个同名联系人!请输入详细信息以确定修改哪一位联系人" << endl;
        person.revise();
        for (int i = 0; i < arr.size(); i++)
        {
            if ((*arr[i]->val) == person)
            {
                arr[i]->val->revise();//调用第一个符合条件的联系人的修改函数,只修改第一个!
                    //从这里还能看出面向对象的好处
                cout << "修改联系人"<<person.name<<"成功!" << endl;
                return;
            }
        }
        cout << "无符合条件的联系人!" << endl;
        break;
    }

}

//删除所有联系人
void deleteAllContacts(PersonList* head) {
    PersonList* temp_1 = head->nextNode;
    PersonList* temp_2 = NULL;//防止temp_2在通信录为空时,得不到初始化的问题。
    while (temp_1 != NULL)
    {
        temp_2 = temp_1;
        temp_1 = temp_1->nextNode;
        delete temp_2;
        
    }

if (head->nextNode == NULL)
        cout << "已清空通讯录!" << endl;
}
//main函数
int main() {
    //test
    /*int a = 10;
    int* ptr_a = &a;
    int* ptr_b = ptr_a;
    cout << *ptr_a << endl << *ptr_b;*/
    //首先新建一个联系人链表的头
    PersonList* head = new PersonList(NULL, NULL);
     
    int select = 0;

while (true) {
        //显示菜单
        showMenu();
        //获取选项
        cin >> select;
        //根据选项进行操作
        switch (select) {
        case 1: addContact(head);
            break;
        case 2: showContacts(head);
            break;
        case 3:deleteContact(head);
            break;
        case 4:searchContacts(head);
            break;
        case 5:reviseContacts(head);
            break;
        case 6:deleteAllContacts(head);
            break;
        case 0:
            return 0;
        default:
            break;
        }

//

}

}

通信录管理系统--我的第一个C++小程序(源码可用)相关推荐

  1. 2021知识付费、流量变现小程序源码系统搭建安装教程,一个小白都可以日入过千的项目。

    关于知识付费.流量变现目前的状况 大家都在谈论流量变现,知识付费,做互联网的基本每天都可以听到同行之间相互谈论.讨论,到底怎么去做了?其实微信的流量主就给我们提供了一个很好的变现方式,不管你流量的多少 ...

  2. 计算机毕业设计Python+uniapp联影医疗器械管理系统小程序(小程序+源码+LW)

    计算机毕业设计Python+uniapp联影医疗器械管理系统小程序(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ ...

  3. 计算机毕业设计Python+uniapp校友会管理系统小程序(小程序+源码+LW)

    计算机毕业设计Python+uniapp校友会管理系统小程序(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ pyt ...

  4. 【java毕业设计】基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码)——图书销售管理系统

    基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing+CS的图书销售管理系统GUI设计与实现,文章末尾附有本毕业设计的 ...

  5. 拼团小程序源码_纯小白如何做一个摄影电商拼团小程序?

    过去,摄影行业都是线下实体店为主,宣传手段单一.推广效率差,客户复购率更是不怎样.随着微信小程序的出现,各个摄影行业商家开始通过小程序来进行推广,连接线上线下场景,这样便能触达更多消费者. 小程序拥有 ...

  6. 计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署

    计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署 计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署 本源码技术栈: ...

  7. 一套Java 小区物业管理系统源码 物业管理小程序源码+安装视频+文档

    Java物业管理小程序源码 物业管理系统源码+安装视频+文档 语言:Java  页面:HTML  项目构建:maven  前端技术:layui 后端:springboot+ssm+shiro+layu ...

  8. 客户关系管理系统CRM小程序源码

    今天给大家带来一个小程序版本的客户关系小程序源码,之前做crm基本都是网页的或者app版本,用小程序的很少,所以就搞了一个小程序的crm毕业设计,基本功能是登录注册,添加客户,跟进客户,最后产生销售 ...

  9. 计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署

    计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署 计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署 本源 ...

最新文章

  1. 8种方法用Python实现线性回归,为你解析最高效选择
  2. java弧线_数据可视化API之弧线图实现
  3. 开发WebService两种开源工具CXF和Axis2的比较
  4. 网络嗅探混杂模式与非混杂模式的区别
  5. Arthas watch 命令使用指南
  6. centos 对已有卷扩容_CentOS LVM 新加硬盘,扩容逻辑卷步骤
  7. 【Python】集合的交、并、补、差集怎么算?
  8. Nginx-location配置指南
  9. 关于android的外文论文,关于android的外文文献.doc
  10. 震惊!三个万引大佬嘴仗,原来是为了他……?
  11. Mac OSX 安装nvm(node.js版本管理器)
  12. 如何通过数据分析鉴别假微博大V?
  13. 用vue语法写html,Vue -- 模板语法
  14. jquery 遍历 TextBox 输入框求和,求平均值并判断输入内容是否为数字
  15. react 中组件隐藏显示_React组件开发中常见的陷阱及解决
  16. 不卖了?这家公司暂停门店销售iPhone!
  17. windows防护之(一)屏蔽危险端口
  18. python周志_python第一周总结
  19. 在线全网音乐搭建源码_支持下载
  20. java排查full gc_FullGC排查心得

热门文章

  1. java spring根据外网IP和端口远程读取照片
  2. 2022年湖南医院三基考试每日一练及答案
  3. 云计算快感不长久,瘦终端才是王道
  4. 《保险业信息系统灾难恢复管理指引》
  5. mate10 html文件,华为Mate10怎么开启电脑模式?华为Mate10秒变PC教程
  6. 国内外主流云主机平台对比(含Github Education Pack的申请流程)
  7. php 培训ppt_php学习 字符串课件
  8. 对比ThinkPHP和Drupal看中外软件业现状
  9. Matlab计算THD、SNR、SINAD
  10. 34.Oracle深度学习笔记——12C的AWR初步解读