C++养成教程(从入门到精通)

前言

最近因工作需要学习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
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深渊潜航

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值