目录
1.通讯录的基本框架
C语言版
C++版
2.增加联系人
C语言版
C++版
3.删除联系人
C语言版
C++版
4.查找与打印联系人
C语言版
C++版
5.修改联系人
C语言版
C++版
6.排序联系人
C语言版
C++版
7.其他
8.总结
本文章将对C语言、C++版本的通讯录进行对比实现。其中C++版本引入大量C语言没有的特性。旨在使广大朋友能快速适应,了解,学习C++基础语法。
下面我将把通讯录的增删查改等功能分模块进行对比。(本人为C++初学者,如果大家对文章有任何问题或意见欢迎指出)
1.通讯录的基本框架
C语言版
这里我们无非是打印菜单功能,创建联系人结构体,还有通讯录结构体。我这里就只展示结构体的实现了。这里实现的动态增容版的通讯录所以联系人结构体里放了 sz 表示人数,capacity表示容量。
typedef struct PeoInfo
{
char name[MAX_NAME];
char sex[MAX_SEX];
int age;
char tele[MAX_TELE];
char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{
PeoInfo *date;
int sz;
int capacity;
}Contact;
C++版
在C++版里我选择用类来代替结构体因为这里我想牵强的使用一下C++中的继承语法。相比较与C语言的手动开辟内存,这里我选择用vector来存放通讯录类类型。
class Peo
{
public:
Peo(string n, string a, string s, string t, int age) :name(n), addr(a),
sex(s), tele(t), age(age) {}//构造函数
string name;
string addr;
string sex;
string tele;
int age;
};
class Contact:public Peo
{
public:
Contact(string n, string a, string s, string t, int age) :Peo(n,a,s,t,age){}
//具体没想好父类还可以加些啥成员变量或函数。
};
下面是创建通讯录时代码的区别:
//(C语言版)创建通讯录
Contact con;
InitContact(&con);//初始化
//C++版
vector<Contact>con;
2.增加联系人
C语言版
这里添加联系人需要判断容量是否足够,如果不够需要增容。
void AddContact(Contact* pc)
{
if(pc->sz == pc->capacity)
{
PeoInfo* prev = (PeoInfo*)realloc(pc->date,sizeof(PeoInfo)*(pc->capacity)*2);
if(prev!=NULL)
{
pc->date = prev;
printf("增容成功\n");
}
pc->capacity = pc->capacity*2;
}
//增加一个人信息
printf("请输入名字:>");
scanf("%s",pc->date[pc->sz].name);
printf("请输入年龄:>");
scanf("%d",&(pc->date[pc->sz].age));
printf("请输入性别:>");
scanf("%s",pc->date[pc->sz].sex);
printf("请输入电话:>");
scanf("%s",pc->date[pc->sz].tele);
printf("请输入地址:>");
scanf("%s",pc->date[pc->sz].addr);
pc->sz++;
printf("增加成功\n");
}
C++版
因为C++有了 vector 所以我们就省去了手动判断容量,增容的问题了。
void AddContact(vector<Contact>&con)
{
string name;
string addr;
string sex;
string tele;
int age;
cout << "请输入联系人的姓名:>" ;
cin >> name;
cout << "请输入联系人的住址:>" ;
cin >> addr;
cout << "请输入联系人的性别:>" ;
cin >> sex;
cout << "请输入联系人的电话:>" ;
cin >> tele;
cout << "请输入联系人的年龄:>" ;
cin >> age;
Contact c(name, addr, sex, tele, age);//创建一个Contact类插入容器中
con.push_back(c);
cout << "添加成功" << endl;
shownumContact(con);//显示联系人数量
return;
}
3.删除联系人
C语言版
这里注意删除成功时需要手动把联系人 sz-- 。单独封装了一个FindByName函数
void DelContact(Contact* pc)
{
char name[MAX_NAME] = {0};
if(pc->sz==0)
{
printf("通讯录为空,无需删除\n");
return;
}
printf("请输入要删除人的名字:>");
scanf("%s",name);
//查找要删除的人
int pos = FindByName(pc,name);
if(pos == -1)
{
printf("要删除的不存在\n");
}
//删除
int i = 0;
for(i = pos; i < pc->sz-1; i++)
{
pc->date[i] = pc->date[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
FindByName函数的实现:
int FindByName(Contact* pc,char name[])
{
int i = 0;
for(i = 0;i < pc->sz;i++)
{
if(strcmp(pc->date[i].name,name) == 0)
{
return i;
}
}
return -1;//找不到
}
C++版
这里直接用自带的erase()来删除联系人,同样的需要封装一个搜索联系人函数。
//删除联系人
void dleContact(vector<Contact>& con)
{
auto prev = Search(con);
if (prev == con.end())
{
cout << "查无此人删除失败" << endl;
return;
}
con.erase(prev);
cout << "删除成功" << endl;
shownumContact(con);//显示联系人数
return;
}
搜索联系人用到了迭代器等概念:
vector<Contact>::iterator Search(vector<Contact>& con)//返回一个迭代器类型
{
string delname;
cout << "请输入联系人的姓名";
cin >> delname;
for (auto iter = con.begin(); iter != con.end(); iter++)
{
if (iter->name == delname)
{
return iter;
}
}
return con.end();//返回尾后表示迭代器表示没找到
}
4.查找与打印联系人
这里查找我就不单独拿出来讲了。
C语言版
打印联系人这里循环整个数组就好了:
void PrintContact(const Contact* pc)
{
int i = 0;
//打印标题
printf("%-20s\t %-5s\t %-5s\t %-12s\t %-20s\n","名字","年龄","性别","电话","地址");
for(i = 0;i < pc->sz; i++)
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n",pc->date[i].name,
pc->date[i].age,
pc->date[i].sex,
pc->date[i].tele,
pc->date[i].addr);
}
}
C++版
这里我又引入了两个新的概念范围for循环和运算符重载,这里因为我们没法用一个左移运算符去打印整个类的成员变量所以我们可以重载左移运算符。
void PrintContact(vector<Contact>& con)
{
shownumContact(con);//打印联系人数量
for (auto C : con)
{
cout << C << endl;
}
return;
}
ostream& operator <<(ostream& cout, Contact c){
cout << "姓名:" << c.name << "\t" << "住址:" << c.addr << "\t"
<< "性别:" << c.sex << "\t" << "电话:" << c.tele << "\t"
<< "年龄:" << c.age;
return cout;
}
5.修改联系人
C语言版
这里我们用之前封装的函数找到要修改的联系人,修改信息即可。因为与C++版差别较小就不展示代码了。
C++版
void modifyContact(vector<Contact>& con)
{
auto prev = Search(con);
if (prev == con.end())
{
cout << "要修改的联系人不存在" << endl;
return;
}
cout << "请输入修改后联系人的姓名:>";
cin >> prev->name;
cout << "请输入修改后联系人的住址:>";
cin >> prev->addr;
cout << "请输入修改后联系人的性别:>";
cin >> prev->sex;
cout << "请输入修改后联系人的电话:>";
cin >> prev->tele;
cout << "请输入修改后联系人的年龄:>";
cin >> prev->age;
}
6.排序联系人
C语言版
这里我们按照联系人姓名进行排序,我用的是一个冒泡排序。
void sort(Contact* pc)
{
for(int i = 0;i < pc->sz-1;i++)
{
for(int j = 0;j < pc->sz-1-j;j++)
{
if((strcmp(pc->date[j].name,pc->date[j+1].name))>0)
{
PeoInfo tmp = pc->date[j];
pc->date[j] = pc->date[j+1];
pc->date[j+1] = tmp;
}
}
}
}
C++版
这里我用的是C++里的sort()来进行排序,注意C++的string类型可以直接比较大小
bool cmp(const Contact&a, const Contact&b)
{
return (a.name < b.name);
}
void sortContact(vector<Contact>& con)
{
sort(con.begin(), con.end(), cmp);
cout << "排序成功" << endl;
}
7.其他
在C语言的最后我们需要手动销毁开辟出来的内存。
在C++中我封装了一个打印当前联系人个数的内联函数:
inline void shownumContact(vector<Contact>& con)
{
cout << "当前联系人数为:" << con.size() << endl;
}
8.总结
在C++版里我们总共用的新的概念有:类,vector,运算符重载,范围for循环,迭代器,内联函数等等。
C++源码:
test.cpp
#include "contact.h"
// 菜单
void menu()
{
cout << "*****************************" << endl;
cout << "*****0.Exit 1.add*********" << endl;
cout << "*****2.del 3.search******" << endl;
cout << "*****4.modify 5.sort********" << endl;
cout << "*****6.Print **************" << endl;
cout << "*****************************" << endl;
}
//枚举选项
enum option
{
Exit,
add,
del,
Search,
modify,
Sort,
Print
};
int main()
{
vector<Contact>con;
int input;
do {
menu();
cout << "请选择:>";
cin >> input;
switch (input)
{
case add:
AddContact(con);
break;
case del:
dleContact(con);
break;
case Search:
searchContact(con);
break;
case modify:
modifyContact(con);
break;
case Sort:
sortContact(con);
break;
case Print:
PrintContact(con);
break;
case Exit:
break;
default:
cout << "输入错误" << endl;
break;
}
} while (input);
return 0;
}
contect.cpp
#include "contact.h"
//添加联系人
void AddContact(vector<Contact>&con)
{
string name;
string addr;
string sex;
string tele;
int age;
cout << "请输入联系人的姓名:>" ;
cin >> name;
cout << "请输入联系人的住址:>" ;
cin >> addr;
cout << "请输入联系人的性别:>" ;
cin >> sex;
cout << "请输入联系人的电话:>" ;
cin >> tele;
cout << "请输入联系人的年龄:>" ;
cin >> age;
Contact c(name, addr, sex, tele, age);//创建一个Contact类插入容器中
con.push_back(c);
cout << "添加成功" << endl;
shownumContact(con);//显示联系人数量
return;
}
//重载运算符
ostream& operator <<(ostream& cout, Contact c){
cout << "姓名:" << c.name << "\t" << "住址:" << c.addr << "\t"
<< "性别:" << c.sex << "\t" << "电话:" << c.tele << "\t"
<< "年龄:" << c.age;
return cout;
}
//单独封装一个搜索
vector<Contact>::iterator Search(vector<Contact>& con)//返回一个迭代器类型
{
string delname;
cout << "请输入联系人的姓名";
cin >> delname;
for (auto iter = con.begin(); iter != con.end(); iter++)
{
if (iter->name == delname)
{
return iter;
}
}
return con.end();//返回尾后表示迭代器表示没找到
}
//打印联系人
void PrintContact(vector<Contact>& con)
{
shownumContact(con);//打印联系人数量
for (auto C : con)
{
cout << C << endl;
}
return;
}
//删除联系人
void dleContact(vector<Contact>& con)
{
auto prev = Search(con);
if (prev == con.end())
{
cout << "查无此人删除失败" << endl;
return;
}
con.erase(prev);
cout << "删除成功" << endl;
shownumContact(con);//显示联系人数
return;
}
void searchContact(vector<Contact>& con)
{
auto prev = Search(con);
if (prev == con.end())
{
cout << "查无此人" << endl;
return;
}
cout << *prev;
return;
}
void modifyContact(vector<Contact>& con)
{
auto prev = Search(con);
if (prev == con.end())
{
cout << "要修改的联系人不存在" << endl;
return;
}
cout << "请输入修改后联系人的姓名:>";
cin >> prev->name;
cout << "请输入修改后联系人的住址:>";
cin >> prev->addr;
cout << "请输入修改后联系人的性别:>";
cin >> prev->sex;
cout << "请输入修改后联系人的电话:>";
cin >> prev->tele;
cout << "请输入修改后联系人的年龄:>";
cin >> prev->age;
}
bool cmp(const Contact&a, const Contact&b)
{
return (a.name < b.name);
}
void sortContact(vector<Contact>& con)
{
sort(con.begin(), con.end(), cmp);
cout << "排序成功" << endl;
}
contect.h
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Peo
{
public:
Peo(string n, string a, string s, string t, int age) :name(n), addr(a),
sex(s), tele(t), age(age) {}
string name;
string addr;
string sex;
string tele;
int age;
};
class Contact:public Peo
{
public:
Contact(string n, string a, string s, string t, int age) :Peo(n,a,s,t,age){}
//具体没想好父类还可以加些啥成员变量或函数。
};
//左移运算符重载
ostream& operator <<(ostream& cout, Contact c);
//添加联系人
void AddContact(vector<Contact>&con);
//打印联系人
void PrintContact(vector<Contact>& con);
//删除联系人
void dleContact(vector<Contact>& con);
//查找联系人
void searchContact(vector<Contact>& con);
//修改联系人信息
void modifyContact(vector<Contact>& con);
//按联系人名字排序
void sortContact(vector<Contact>& con);
//显示当前联系人数量(内联函数提高效率)
inline void shownumContact(vector<Contact>& con)
{
cout << "当前联系人数为:" << con.size() << endl;
}
看到这里就点个关注吧~