通信录管理系统--我的第一个C++小程序(源码可用)
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++小程序(源码可用)相关推荐
- 2021知识付费、流量变现小程序源码系统搭建安装教程,一个小白都可以日入过千的项目。
关于知识付费.流量变现目前的状况 大家都在谈论流量变现,知识付费,做互联网的基本每天都可以听到同行之间相互谈论.讨论,到底怎么去做了?其实微信的流量主就给我们提供了一个很好的变现方式,不管你流量的多少 ...
- 计算机毕业设计Python+uniapp联影医疗器械管理系统小程序(小程序+源码+LW)
计算机毕业设计Python+uniapp联影医疗器械管理系统小程序(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ ...
- 计算机毕业设计Python+uniapp校友会管理系统小程序(小程序+源码+LW)
计算机毕业设计Python+uniapp校友会管理系统小程序(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ pyt ...
- 【java毕业设计】基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码)——图书销售管理系统
基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing+CS的图书销售管理系统GUI设计与实现,文章末尾附有本毕业设计的 ...
- 拼团小程序源码_纯小白如何做一个摄影电商拼团小程序?
过去,摄影行业都是线下实体店为主,宣传手段单一.推广效率差,客户复购率更是不怎样.随着微信小程序的出现,各个摄影行业商家开始通过小程序来进行推广,连接线上线下场景,这样便能触达更多消费者. 小程序拥有 ...
- 计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署
计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署 计算机毕业设计ssm农村老人管理系统的设计与实现36jlv系统+程序+源码+lw+远程部署 本源码技术栈: ...
- 一套Java 小区物业管理系统源码 物业管理小程序源码+安装视频+文档
Java物业管理小程序源码 物业管理系统源码+安装视频+文档 语言:Java 页面:HTML 项目构建:maven 前端技术:layui 后端:springboot+ssm+shiro+layu ...
- 客户关系管理系统CRM小程序源码
今天给大家带来一个小程序版本的客户关系小程序源码,之前做crm基本都是网页的或者app版本,用小程序的很少,所以就搞了一个小程序的crm毕业设计,基本功能是登录注册,添加客户,跟进客户,最后产生销售 ...
- 计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署
计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署 计算机毕业设计ssm大学生身心健康管理系统的设计与实现d223r系统+程序+源码+lw+远程部署 本源 ...
最新文章
- 8种方法用Python实现线性回归,为你解析最高效选择
- java弧线_数据可视化API之弧线图实现
- 开发WebService两种开源工具CXF和Axis2的比较
- 网络嗅探混杂模式与非混杂模式的区别
- Arthas watch 命令使用指南
- centos 对已有卷扩容_CentOS LVM 新加硬盘,扩容逻辑卷步骤
- 【Python】集合的交、并、补、差集怎么算?
- Nginx-location配置指南
- 关于android的外文论文,关于android的外文文献.doc
- 震惊!三个万引大佬嘴仗,原来是为了他……?
- Mac OSX 安装nvm(node.js版本管理器)
- 如何通过数据分析鉴别假微博大V?
- 用vue语法写html,Vue -- 模板语法
- jquery 遍历 TextBox 输入框求和,求平均值并判断输入内容是否为数字
- react 中组件隐藏显示_React组件开发中常见的陷阱及解决
- 不卖了?这家公司暂停门店销售iPhone!
- windows防护之(一)屏蔽危险端口
- python周志_python第一周总结
- 在线全网音乐搭建源码_支持下载
- java排查full gc_FullGC排查心得