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

    科技2025-10-16  12

    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;         }

            //

        }

    }

    Processed: 0.009, SQL: 8