前言
最近因工作需要学习C++,决定开创一个养成系的博客,目标是分享我的C++的学习过程和学习经验。之后会把学习过程中的所有代码写入这篇博客里,由于这一想法是在中途出现,所以更新内容会从中间开始,之后会陆续补充完善全部内容。
(代码学习取自bilibili:黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难)
通讯录管理系统
//封装函数显式该界面 如void showMenu()
//在main函数中调用封装好的函数
#include<iostream>
#include<string>
#define MAX 1000 //最大人数
using namespace std;
//联系人结构体
struct Person
{
string m_Name;//姓名
int m_Sex;//性别:1男 2女
int m_Age;//年龄
string m_Phone;//电话
string m_Addr;//住址
};
//通讯录结构体
struct Addressbooks
{
struct Person personArray[MAX];//通讯录中保存的联系人数组
int m_Size;//通讯录中人员个数
};
//菜单界面
void shouMenu()
{
cout << " ***** ***** ***** *****" << endl;
cout << "***** 1、添加联系人 *****" << endl;
cout << "***** 2、显式联系人 *****" << endl;
cout << "***** 3、删除联系人 *****" << endl;
cout << "***** 4、查找联系人 *****" << endl;
cout << "***** 5、修改联系人 *****" << endl;
cout << "***** 6、清空联系人 *****" << endl;
cout << "***** 0、退出通讯录 *****" << endl;
}
//1、添加联系人
void addPerson(Addressbooks *abs)
{
//判断通讯录是否已满,如果满了,将不再添加
if (abs->m_Size == MAX)
{
cout << "通讯录已满,无法添加" << endl;
return;
}
else
{
//添加具体联系人
//姓名
string name;
cout << "请输入姓名:" << endl;
cin >> name;
abs->personArray[abs->m_Size].m_Name=name;
//性别
cout << "请输入性别:" << endl;
cout << "1--- 男" << endl;
cout << "2--- 女" << endl;
int sex = 0;
while (true)
{
//如果输入的是1 或者 2 可以退出循环,因为输入的是正确值
//如果输入有误,重新输入
cin >> sex;
if (sex == 1 || sex == 2)
{
abs->personArray[abs->m_Size].m_Sex = sex;
break;
}
cout << "输入有误,请重新输入" << endl;
}
//年龄
cout << "请输入年龄:" << endl;
int age = 0;
while (true)
{
if (age > 0 || age < 150)
{
cin >> age;
abs->personArray[abs->m_Size].m_Age = age;
break;
}
cout << "输入有误,请重新输入" << endl;
}
//电话
cout << "请输入联系电话:" << endl;
string phone;
cin >> phone;
abs->personArray[abs->m_Size].m_Phone = phone;
//住址
cout << "请输入家庭住址:" << endl;
string address;
cin >> address;
abs->personArray[abs->m_Size].m_Addr = address;
//更新通讯录人数
abs->m_Size++;
cout << "添加成功" << endl;
system("pause");//请按任意键继续
system("cls");//清屏操作
}
}
//2、显式所有联系人
void showPerson(Addressbooks *abs)
{
//判断通讯录中人数是否为0,如果为0,提示记录为空
//如果不为0,显式记录的联系人信息
if (abs->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_Addr << endl;
}
}
system("pause");//按任意键继续
system("cls");//清屏
}
//3、检测联系人是否存在,如果存在,返回联系人所在数组中的具体位置,不存在返回-1
//参数1 通讯录 参数2 对比姓名
int isExist(Addressbooks* abs, string name)
{
for (int i = 0; i < abs->m_Size; i++)
{
//找到用户输入的姓名了
if (abs->personArray[i].m_Name == name)
{
return i;
}
}
return -1;//如果遍历结束都没有找到,返回-1
}
//3、删除指定联系人
void deletePerson(Addressbooks *abs)
{
cout << "请输入您要删除的联系人" << endl;
string name;
cin >> name;
//ret==-1 未查到
//ret !=-1 查到了
int ret=isExist(abs, name);
if (ret != -1)
{
//查找到人,要进行删除操作
for (int i = ret; i < abs->m_Size; i++)
{
//数据前移
abs->personArray[i] = abs->personArray[i + 1];
}
abs->m_Size--;//更新通讯录中的人员数
cout << "删除成功" << endl;
}
else
{
cout << "查无此人" << endl;
}
system("pause");
system("cls");
}
//4、查找指定联系人信息
void findPerson(Addressbooks *abs)
{
cout << "请输入您要查找的联系人" << endl;
string name;
cin >> name;
//判断指定的联系人是否存在通讯录中
int ret = isExist(abs, name);
if (ret != -1)//找到联系人
{
cout << "姓名:" << abs->personArray[ret].m_Name << "\t";
cout << "性别:" << abs->personArray[ret].m_Sex << "\t";
cout << "年龄:" << abs->personArray[ret].m_Age << "\t";
cout << "电话:" << abs->personArray[ret].m_Phone << "\t";
cout << "住址:" << abs->personArray[ret].m_Addr << endl;
}
else //未找到联系人
{
cout << "查无此人" << endl;
}
//任意键按下后 清屏
system("pause");
system("cls");
}
//5、修改指定联系人信息
void modifyPerson(Addressbooks* abs)
{
cout << "请输入您要修改的联系人" << endl;
string name;
cin >> name;
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;
}
cout << "输入有误,请重新输入" << endl;
}
//年龄
cout << "请输入年龄:" << endl;
int age = 0;
cin >> age;
abs->personArray[ret].m_Age = age;
//电话
cout << "请输入联系电话:" << endl;
string phone;
cin >> phone;
abs->personArray[ret].m_Phone = phone;
//电话
cout << "请输入家庭住址:" << endl;
string address;
cin >> address;
abs->personArray[ret].m_Addr = address;
cout << "修改成功" << endl;
}
else //未找到联系人
{
cout << "查无此人" << endl;
}
system("pause");
system("cls");
}
//6、清空所有联系人
void cleanPerson(Addressbooks* abs)
{
abs->m_Size = 0;//将当期记录联系人数量置为0,做逻辑清空操作
cout << "通讯录已清空" << endl;
//按任意键后清屏
system("pause");
system("cls");
}
int main()
{
//创建通讯录结构体变量
Addressbooks abs;
//初始化通讯录中当前人员个数
abs.m_Size = 0;
int select = 0;//创建用户选择输入的变量
while(true)
{
//菜单调用
shouMenu();
cin >> select;
switch (select)
{
case 1://1、添加联系人
addPerson(&abs);
break;
case 2://2、显式联系人
showPerson(&abs);
break;
case 3://3、删除联系人
/*{
cout << "请输入删除联系人姓名:" << endl;
string name;
cin >> name;
if (isExist(&abs, name) == -1)
{
cout << "查无此人" << endl;
}
else
{
cout << "找到此人" << endl;
}
}*/
deletePerson(&abs);
break;
case 4://4、查找联系人
findPerson(&abs);
break;
case 5://5、修改联系人
modifyPerson(&abs);
break;
case 6://6、清空联系人
cleanPerson(&abs);
break;
case 0://0、退出通讯录
cout << "欢迎下次使用" << endl;
system("pause");
return 0;
break;
default:
break;
}
}
system("pause");
return 0;
}
栈区
面向对象
#include<iostream>
using namespace std;
//全局变量
int g_a = 10;
int g_b = 10;
//const修饰的全局变量,全局常量
const int c_g_a = 10;
const int c_g_b = 10;
int main() {
//全局区
//全局变量、静态变量、常量
//创建普通局部变量
int a = 10;
int b = 10;
cout << "局部变量a的地址为:" << (int)&a << endl;
cout << "局部变量b的地址为:" << (int)&b << endl;
cout << "全局变量g_a的地址为:" << (int)&g_a << endl;
cout << "全局变量g_b的地址为:" << (int)&g_b << endl;
//静态变量 在普通变量前面加static,属于静态变量
static int s_a = 10;
static int s_b = 10;
cout << "静态变量s_a的地址为:" << (int)&s_a << endl;
cout << "静态变量s_b的地址为:" << (int)&s_b << endl;
//常量
//字符串常量
cout << "字符串常量的地址为:" << (int)&"hello world" << endl;
//const修饰的变量
//const修饰的全局变量,const修饰的局部变量
cout << "全局常量 c_g_a的地址为:" << (int)&c_g_a << endl;
cout << "全局常量 c_g_b的地址为:" << (int)&c_g_b << endl;
const int c_l_a = 10;// c const g_global 1-local
const int c_l_b = 10;
cout << "局部常量 c_l_a的地址为:" << (int)&c_l_a << endl;
cout << "局部常量 c_l_b的地址为:" << (int)&c_l_b << endl;
system("pause");
return 0;
}
栈区
#include<iostream>
using namespace std;
//栈区数据注意事项 ---不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放
int* func(int b)//形参数据也会放在栈区
{
b = 100;
int a = 10;//局部变量
return &a;//返回局部变量地址
}
int main() {
//接受func函数的返回值
int* p = func(1);
cout << *p << endl;//第一次可以打印正确的数字,是因为编译器做了保留
cout << *p << endl;//第二次这个数据就不再保留了
system("pause");
return 0;
}
堆区
堆区
#include<iostream>
using namespace std;
int* func1()
{
//利用new关键字 可以将数据开辟到堆区
//指针 本质也是局部变量,放在栈上,指针保存的数据是放在堆区
int *p=new int(10);
return p;
}
int main1() {
//在堆区开辟数据
int* p = func1();
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
new操作符
#include<iostream>
using namespace std;
//1、new的基本语法
int* func()
{
//在堆区创建整型数据
//new返回是 该数据类型的指针
int* p = new int(10);
return p;
}
void test01()
{
int* p = func();
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
//堆区的数据 由程序员管理开辟,程序员管理释放
//如果想释放堆区的数据,利用关键字delete
delete p;
cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错
}
//2、在堆区利用new开辟数组
void test02()
{
//创建10整型数据的数组,在堆区
int * arr=new int[10];//10代表数组有10个元素
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;//给10个元素赋值 100^109
}
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
//释放堆区数组
//释放数组的时候,要加[]才可以
delete[] arr;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
引用
引用
#include<iostream>
using namespace std;
int main() {
//1、应用必须初始化
int a = 10;
//创建引用
int& b = a;
//2、应用在初始化后,不可以改变
int c = 20;
b = c;//赋值操作,而不是更改引用
//引用基本语法
//数据类型 &别名=原名
cout <<"a="<< a << endl;//??? 也是20
cout << "b=" << b << endl;
cout << "c=" << c << endl;
system("pause");
return 0;
}
引用的本质
#include<iostream>
using namespace std;
//引用的本质在c++内部实现是一个指针常量
//发现是引用,转换为int *const ref=&a;
void func(int& ref) {
ref = 100;//ref是引用,转换为*ref=100
}
int main() {
int a = 10;
//自动转换为 int* const ref=&a;指针常量是指针指向不可改,也说明为什么引用不可更改
int& ref = a;
cout << &ref << endl;
cout << ref << endl;
ref = 20;//内部发现ref是引用,自动帮我们转换为:*ref=20;
cout << &ref << endl;
cout << ref << endl;
system("pause");
return 0;
}
引用做函数参数
#include<iostream>
using namespace std;
//交换函数
//1、值传递
void mySwap01(int a, int b)
{
int temp = a;
a = b;
b = temp;
/*cout << "swap01a=" << a << endl;
cout << "swap01b=" << b << endl;*/
}
//2、地址传递
void mySwap02(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
//3、引用传递
void mySwap03(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 10;
int b = 20;
//mySwap01(a, b);//值传递,形参不会修饰实参
//mySwap02(&a, &b);//地址传递,形参会修饰实参
mySwap03(a, b);//引用传递,形参会修饰实参的
cout << "a=" << a << endl;
cout << "b=" << b << endl;
system("pause");
return 0;
}
引用做函数返回值
#include<iostream>
using namespace std;
//引用做函数的返回值
//1、不要返回局部变量的引用
int& test01()
{
int a = 10;//局部变量存放在四区中的 栈区
return a;
}
//2、函数的调用可以作为左值
int& test02()
{
static int a = 10;//静态变量,存放在全局区,全局区上的数据在程序结束后系统释放
return a;
}
int main() {
//int& ref = test01();
//cout << "ref=" << ref << endl;//第一次结果正确,是因为编译器做了保留
//cout << "ref=" << ref << endl;//第二次结果错误,因为a的内存已经释放
int& ref2 = test02();
cout << "ref2=" << ref2 << endl;
cout << "ref2=" << ref2 << endl;
cout << "ref2=" << ref2 << endl;
test02() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
cout << "ref2=" << ref2 << endl;
cout << "ref2=" << ref2 << endl;
system("pause");
return 0;
}
常量引用
#include<iostream>
using namespace std;
//常量引用主要用来修饰形参,防止误操作
//打印数据函数
void showValue(const int &val)
{
//val = 1000;
cout << "val=" << val << endl;
}
int main() {
//常量引用
//使用场景:用来修饰形参,防止误操作
//int a = 10;
//加上const之后 编译器将代码修改 int temp=10;const int& ref =temp
//int& ref = 10;//错误,引用必须引一块合法的内存空间
//const int& ref = 10;
//ref = 10;//错误 加入const之后变为只读,不可修改
int a = 100;
showValue(a);
cout << "a=" << a << endl;
system("pause");
return 0