IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++入门编程学习笔记(二) -> 正文阅读

[C++知识库]C++入门编程学习笔记(二)

请添加图片描述

C++入门编程学习笔记(二)

一、程序流程结构

  • C++支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构
  • 顺序结构:程序安书序执行,不发生跳转
  • 选择结构:依据条件是否满足,有选择的执行相应功能
  • 循环结构:依据条件是否满足,循环多次执行某段代码

1.1 选择结构

1.1.1 if 语句

  • if语句的作用是执行满足条件的语句
  • if语句有三种形式:单行格式if语句、多行格式if语句、多条件的if语句

代码:

/*********************************************************************
    程序名:选择结构
    作者: Sweitena
    日期: 2021-03-17 16:05
    说明:if语句的三种结构
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//单行格式if语句
	//如果成绩大于90,输出成绩优秀
	cout << "①单行if语句" << endl;
	int score1 = 0;
	cout << "请输入一个分数:" << endl;
	cin >> score1;

	if (score1 > 90) {
		cout << "成绩优秀" << endl;
	}

	//多行格式if语句
	//如果成绩大于60,输出及格;反之,输出不及格
	cout << "②if - else结构" << endl;
	int score2 = 0;
	cout << "请输入一个分数:" << endl;
	cin >> score2;

	if (score2 < 60) {
		cout << "不及格" << endl;
	} else {
		cout << "及格" << endl;
	}

	//多条件的if语句
	/*如果成绩小于60,输出成绩不及格;60~80,输出成绩一般;
	  80~90,成绩不错;大于90,成绩优秀*/
	cout << "③if - else if - else结构" << endl;
	int score3 = 0;
	cout << "请输入一个分数:" << endl;
	cin >> score3;

	if (score3 > 90) 
	{	
	    cout << "成绩优秀" << endl; //注意:if里面也是按顺序依次执行的
	} 
	else if (score3 > 80) 
	{	
	    cout << "成绩不错" << endl;  //所以先把大的写前面
    } 
	else if (score3 > 60) 
	{	
	    cout << "成绩一般" << endl;
	} 
	else 
	{	
	    cout << "成绩不及格" << endl;
	}


	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.1.2 嵌套 if 语句

  • 在 if 语句中,可以嵌套使用 if 语句,达到更精确的条件判断

案例描述

  • 提示用户输入一个高考考试分数,根据分数做出如下判断;
  • 分数如果大于600视为考上一本,大于500分视为考上二本,大于400考上三本,其余视为未考上本科;
  • 在一本分数中,如果大于700分,考上北大,大于650分,考上清华,大于600分,考入人大。

代码:

/*********************************************************************
    程序名:选择结构
    作者: Sweitena
    日期: 2021-03-17 16:05
    说明:嵌套if语句
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int score = 0;
	cout << "请输入一个高考分数:" << endl;
	cin >> score;
	cout << "您输入的分数是:" << score << endl;

	if (score > 600)          //如果大于600 一本
	{	
	    cout << "恭喜您考入一本大学" << endl;
		if (score > 700)  
		{	cout << "恭喜您考入北大" << endl;} 
		else if (score > 650)  
		{	cout << "恭喜您考入清华" << endl;}
		cout << "恭喜您考入人大" << endl;
	} 
	else if (score > 500)     //如果大于500 二本
	{	
	    cout << "恭喜您考入二本大学" << endl;
	} 
	else if (score > 400)     //如果大于400 三本
	{	
	    cout << "恭喜您考入三本大学" << endl;
	} 
	else                     //其余情况 未考上本科
	{	
	    cout << "很抱歉,您未考上本科" << endl;
	}

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习:三只小猪称体重

案例描述

  • 有三只小猪ABC,请分别输入三只小猪的体重,并且判断那只小猪最重

代码:

/*********************************************************************
    程序名:选择结构案例练习01
    作者: Sweitena
    日期: 2021-03-18 09:15
    说明:三只小猪称重
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//1.创建三只小猪的体重变量
    int a, b, c;
	a = 0;
	b = 0;
	c = 0;
    //2.让用户输入三只小猪的重量
    cout <<"请输入小猪A的体重:"<< endl;
    cin >> a;
    cout <<"请输入小猪B的体重:"<< endl;
    cin >> b;
    cout <<"请输入小猪C的体重:"<< endl;
    cin >> c; 
    //3.判断哪只最重
    //先判断A和B
    if(a > b)   //a>b
    {     
         if(a > c)  //a>c
	     {cout << "小猪A最重" << a << endl;}
         else      //a<c
	     {cout << "小猪C最重" << c << endl;}    
    }
    else       //a<b
    {     
	     if(b > c) //b>c
	     {cout << "小猪B最重" << b << endl;}
         else      //b<c
	     {cout << "小猪c最重" << c << endl;}
    }

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述

  • 引申:比较输入的三个数的大小,并按照降序排列

代码:

/*********************************************************************
    程序名: 选择结构案例练习02
    作者: Sweitena
    日期: 2021-03-18 09:20
    说明: 比较输入的三个数大小,并进行排序
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int a, b, c, t;
	a = 0;
	b = 0;
	c = 0;
	t = 0;
	cout << "请分别输入三只小猪的重量:" << endl;
	cin >> a;
	cin >> b;
	cin >> c;

	if (a > b) 
	{
		t = a;
		if (c > t)
		{
			t = c;
			cout << "③> ①> ②" << endl;
		} 
		else 
		{
			//已知a>c 且 a>b 不确定b和c的关系
			if (b > c) 
			{cout << "①> ②> ③" << endl;} 
			else 
			{cout << "①> ③> ②" << endl;}
		}
	} 
	else 
	{ //已知a<b 不确定a与c的关系
		t = b;
		if (c > t) 
		{
			t = c;
			cout << "③> ②> ①" << endl;
		} 
		else 
		{
			//已知c<b 且 a<b 不确定a与c的关系
			if (a > c) 
			{cout << "②> ①> ③" << endl;} 
			else 
			{cout << "②> ③> ①" << endl;}
		}
	}

	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


1.1.3 三目运算符

  • 作用:通过三目运算符实现简单判断

代码:

/*********************************************************************
    程序名: 选择结构_三目运算符
    作者: Sweitena
    日期: 2021-03-18 09:30
    说明: 【作用】通过三目运算符实现简单判断
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int a, b, c;
	a = 10;
	b = 20;
	c = 0;
	//使用三目运算符比较a和b,返回较大值
	c = a > b ? a : b;
	cout << "c = " << c << endl;

	//C++中三目运算符返回的是变量,可以继续赋值
	( a > b ? a : b ) = 100;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.1.4 switch 结构

  • 作用:switch结构可以执行多条件分支语句

案例描述

  • 给电影打分,分三个等级:
  • A级:4.5~5.0分,电影非常好
  • B级:3.0~4.5分,电影一般
  • C级:3.0分一下,烂片

代码:

/*********************************************************************
    程序名: 选择结构_switch结构
    作者: Sweitena
    日期: 2021-04-01 09:35
    说明: 【作用】执行多条件分支语句
         【案例需求】给电影打分,分三个等级,A级:4.5-5.0分;B级:3.0-4.5分;C级:3.0分以下
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//1.提示用户给电影打分
	cout << "请给电影打分(0~5):" << endl;

	//2.用户开始进行打分
	float  score;
	char flag;
	score = 0;
	cin >> score;
	cout << "您打的分数为:" << score << endl;

	//3.根据用户输入的分数来提示用户最后的结果
	flag = (score > 4.5 || score == 4.5) ? 'A' : (score >  3.0 || score == 3.0) ? 'B' : 'C';

	switch (flag) {

		case 'A':
			cout << "A级-您认为电影非常好" << endl;
			break;
		case 'B':
			cout << "B级-您认为电影一般" << endl;
			break;
		case 'C':
			cout << "C级-您认为是个烂片" << endl;
			break;
	}

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.2 循环结构

1.2.1 while 语句

  • while语句:只要循环条件的结果为真,就执行循环
  • 语法:while (循环条件){ 循环语句 }
  • 无限循环:while(1) { 循环语句 }

案例描述

  • 实现从0累加到n,求和并返回n个数的和

代码:

/*********************************************************************
    程序名: 循环结构_while语句
    作者: Sweitena
    日期: 2021-04-01 11:07
    说明: 【作用】满足循环条件,执行循环语句
         【案例需求】实现从0累加到n,求和
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int i, n, S;
	i = 0;
	n = 0;
	S = 0;
	cout << "请输入一个n:" << endl;
	cin >> n;

	while (i < n) {
		i = i + 1; // i++;
		S = S + i;
	}

	cout << n << "个数做和为:" << S << endl;
	system("pause");

	return 0;
}

运行结果图
在这里插入图片描述


?案例练习01:猜数字

  • 注意:生成随机数时,可以引入< ctime >头文件,添加随机数种子

案例描述

  • 系统随机生成一个1到100之间的数字,玩家进行猜测;
  • 如果猜错,提示玩家数字过大或过小;
  • 如果猜对,恭喜玩家胜利,并且退出游戏。

代码:

/*********************************************************************
    程序名: 循环结构案例练习01
    作者: Sweitena
    日期: 2021-04-01 11:26
    说明: 猜数字
*********************************************************************/
#include <iostream>
using namespace std;
#include <ctime>//系统头文件

int main() {
	//添加随机数种子,作用:利用当前系统时间生成随机数
	srand((unsigned int)time(NULL));

	int num;
	int val;
	val = 0;
	num = rand() % 100 + 1; //生成0-100的随机数
	//cout << num << endl;

	while (1) {
		cout << "请输入一个数" << endl;
		cin >> val;

		if (val == num) 
        {
			cout << "恭喜您猜对了!" << endl;
			break;      //跳出循环,即退出游戏
		} 
        else if (val > num) 
        {
			cout << "大了" << endl;
		} 
        else 
        {
			cout << "小了" << endl;
		}
	}

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.2.2 do…while 语句

  • 与 while 的区别在于do…while 会先执行一次循环语句,再判断循环条件
  • 语法:do { 循环语句 } while (循环条件) ;
  • 无限循环:do { 循环语句 } while (1) ;

案例描述

  • 实现从0累加到n,求和并返回n个数的和

代码:

/*********************************************************************
    程序名: 循环结构_do...while
    作者: Sweitena
    日期: 2021-04-03 19:20
    说明: 【作用】满足循环条件,执行循环语句
         【案例需求】实现从0累加到n,求和
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int i, n, S;
	i = 0;
	n = 0;
	S = 0;
	cout << "请输入一个n:" << endl;
	cin >> n;

	do {
		i = i + 1;// i++;
		S = S + i;
	} while (i < n);

	cout << n << "个数做和为:" << S << endl;
	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习02:水仙花数

案例描述

  • 水仙花数是指一个3位数,它的每个位上的数字的3次幂之和等于它本身
  • 例如:13+53+33=153
  • 请利用 do…while 语句,求出所有3位数中的水仙花数

案例分析
在这里插入图片描述

代码:

/*********************************************************************
    程序名: 循环结构案例练习02
    作者: Sweitena
    日期: 2021-04-03 19:36
    说明: 找到所有3位的水仙花数
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int bai, shi, ge, num;
	bai = 0;
	shi = 0;
	ge = 0;
	num = 100;

	do 
    {
		//cout << num <<endl;
		ge = num % 10;
		shi = (num / 10 ) % 10;
		bai = num / 100;

		if (ge * ge * ge + shi * shi * shi + bai * bai * bai == num) 
        {cout << num << endl;}
		
		num++;

	} while (num < 1000);

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.2.3 for 循环语句

  • 语法:for (起始表达式; 条件表达式; 末尾循环体) { 循环语句;}
  • 无限循环:for ( ; ; ) { 循环语句;}

代码:

/*********************************************************************
    程序名: 循环结构-for
    作者: Sweitena
    日期: 2021-04-03 20:30
    说明: 【作用】满足循环条件,执行循环语句
         【案例需求】实现从0累加到n,求和
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//for(起始表达式; 条件表达式; 末尾循环体) {循环语句;}
	int i, n, S;
	i = 0;
	n = 0;
	S = 0;
	cout << "请输入一个n:" << endl;
	cin >> n;

	for (; i < n + 1; i++) 
	{
		//注意这里的判断条件变成n+1了
		S = S + i;
	}

	cout << n << "个数做和为:" << S << endl;

	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


?案例练习03:敲桌子

案例描述

  • 从1开始数到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出。

案例分析

在这里插入图片描述
代码:

/*********************************************************************
    程序名: 循环结构案例练习03
    作者: Sweitena
    日期: 2021-04-03 20:41
    说明: 从1到100,个位数或者十位数含有7,或者是7的倍数就打印敲桌子,其余数字直接输出
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int num, b, c;
	num = 1;
	b = 0;
	c = 0;

	for ( ; num < 101; num++ ) 
	{
		//cout << num << endl;
		b = num / 10; //十位的数字
		c = num % 10; //个位的数字

		if ((num % 7 == 0 ) || (b == 7 ) || (c == 7)) 
		{cout << "敲桌子" << endl;} 
		else 
		{cout << num << endl;}
	}

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


1.2.4 嵌套循环

  • 作用:在循环体中再嵌套一层循环,解决一些实际问题

代码:

/*********************************************************************
    程序名: 循环结构-嵌套循环
    作者: Sweitena
    日期: 2021-04-03 21:31
    说明: 打印10*10的矩阵形式的星星
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	cout << "方法一:利用for循环,先打印一行星图,再嵌套" << endl;
	int i, j;
	//利用for循环,先打印一行星图
	for (i = 0; i < 10; i++) 
	{  //外层循环
		for (j = 0; j < 10; j++) 
		{  //内层循环
			cout << "* " ; //打印出来一行
		}
		cout << endl;
	} //然后再设置一个循环把“打印一行”的代码,循环10次


	cout << "方法二:不用嵌套也可以实现星图" << endl;
	int k;
	for (k = 0; k < 5; k++) 
	{cout << "* * * * * * " << endl; } //打印出来一行

	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


?案例练习04:乘法口诀表

案例描述

  • 利用嵌套循环,实现九九乘法表

案例分析

在这里插入图片描述

代码:

/*********************************************************************
    程序名: 循环结构案例练习04
    作者: Sweitena
    日期: 2021-04-04 08:57
    说明: 打印乘法口诀表
*********************************************************************/
#include <iostream>
using namespace std;


int main() {

	int r, c, product;
	product = 0;

	for (r = 1; r <= 9; r++) 
	{
		//cout << r;
		for (c = 1; c <= r; c++) 
		{
			//cout << c;
			product = c * r;
			cout << c << "x" << r << "=" << product << " ";
		}
		cout << endl;  //换行
	}

	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


1.2.5 跳转语句:3种

  • 作用:更改执行的正常序列。当执行离开一个范围时,所有在该范围中创建的自动对象都会被销毁。

1. break 语句

  • 作用:用于跳出选择结构或者循环结构
  • 出现在 switch 条件语句中,作用是终止 case 并跳出 switch
  • 出现在循环语句中,作用是跳出当前的循环语句
  • 出现在嵌套循环中,跳出最近的内层循环语句

在这里插入图片描述

2. continue 语句

  • 作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
    在这里插入图片描述

3. goto 语句

  • 作用:可以无条件跳转语句
  • 语法:goto 标记;
  • 如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
    【注意】在任何编程语言中,都不建议使用 goto 语句

二、数组

  • 所谓数组,就是一个集合,里面存放了相同类型的数据元素
  • 特点1:数组中的每个数组元素都是相同的数据类型
  • 特点2:数组是由连续的内存位置组成的

2.1 一维数组

2.1.1 定义

一维数组定义的三种方式:

  1. 数据类型 数组名 [ 数组长度 ] ;
  2. 数据类型 数组名 [ 数组长度 ] = { 值1,值2,… };
  3. 数据类型 数组名 [ ] = { 值1,值2,…};

代码:

/*********************************************************************
    程序名: 一维数组
    作者: Sweitena
    日期: 2021-04-04 14:33
    说明: 数组的定义
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	/********** 三种定义形式:********************
	1.数据类型  数组名[数组长度];
	2.数据类型  数组名[数据长度] = {值1, 值2, ...};
	3.数据类型  数组名[ ] = {值1, 值2, ...};
	**********************************************/
	//①第一种定义方式
	cout << "第一种定义方式:" << endl;
	int arr[5];
	arr[0] = 10;// 给数组元素赋值
	arr[1] = 20;
	arr[2] = 30;
	arr[3] = 40;
	arr[4] = 50;
	cout << arr[0] << " "; // 访问数组元素
	cout << arr[1] << " ";
	cout << arr[2] << " ";
	cout << arr[3] << " ";
	cout << arr[4] << " ";
	cout << endl;
	
	//②第二种定义方式
	cout << "第二种定义方式:" << endl;
	int arr2[5] = {10, 20, 30, 40};
	int i;
	for (i = 0; i < 5; i++) 
	{
		cout << arr2[i] << " ";
	}
	cout << endl;
	
	//③第三种定义方式
	cout << "第三种定义方式:" << endl;
	int arr3[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
	int j;
	for (j = 0; j < 10; j++) 
	{
		cout << arr3[j] << " ";
	}
	cout << endl;
	
	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


2.1.2 数组名用途

一维数组名称的用途:

  1. 可以统计整个数组在内存中的长度
  2. 可以获取数组在内存中的首地址

代码:

/*********************************************************************
    程序名: 一维数组
    作者: Sweitena
    日期: 2021-04-04 14:38
    说明: 数组名的用途
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//数组名用途:
	int arr3[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
	
	//1.可以通过数组名统计整个数组或元素占用内存的大小
	cout << "整个数组占用内存大小为:" << sizeof(arr3) << endl;
	cout << "元素占用内存大小为:" << sizeof(arr3[0]) << endl;
	cout << "数组中元素的个数:" << sizeof(arr3) / sizeof(arr3[0]) << endl;
	
	//2.可以用过数组名查看数组首地址
	cout << "数组首地址为:" << arr3 << endl;
	cout << "数组首地址为:" << (int)arr3 << endl; //16进制转10进制
	cout << "数组中第一个元素的地址为:" << &arr3[0] << endl;
	cout << "数组中第一个元素的地址为:" << (int)&arr3[0] << endl; //16进制转10进制
	cout << "数组中第二个元素的地址为:" << (int)&arr3[1] << endl;

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习01:五只小猪称体重

案例描述

  • 在一个数组中记录了五只小猪的体重
  • 例如:int arr[5] = { 300 , 350 , 200 , 400 , 250 };
  • 找出并打印最重的小猪体重

代码:

/*********************************************************************
    程序名:一维数组案例练习01
    作者: Sweitena
    日期: 2021-04-04 15:30
    说明: 五只小猪称体重,找出并打印最重的小猪的体重
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	int arr[] = {300, 350, 200, 400, 250};
	int max = 0;  //先设置一个最大值
	int num = 0;

	for (int i = 0; i < 5; i++) 
	{
		if (arr[i] > max)
		{
			max = arr[i];  //更新最大值
			num = i;
		}
	}
	cout << "第" << num + 1 << "只小猪最重,体重为:" << max << endl;
	
	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习02:元素逆置

案例描述

  • 请声明一个5个元素的数组,并且将元素逆置
  • 例如:原数组元素为:1,3,2,5,4; 逆置后输出结果为:4,5,2,3,1;

案例分析
在这里插入图片描述
代码:

/*********************************************************************
    程序名: 一维数组案例02
    作者: Sweitena
    日期: 2021-04-04 16:11
    说明: 数组元素逆置,首尾元素交换
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	/*****1.创建数组*****/
	int arr[] = {1, 3, 2, 5, 4};
	cout << "数组逆置前:" << endl;
	for (int i = 0; i < 5; i++) 
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	
	/*****2.实现逆置******/
	//2.1记录起始下标位置
	//2.2记录末尾下标位置
	//2.3起始下标与末尾下标的元素互换
	//2.4起始位置++,末尾位置--
	//循环执行2.1-2.4操作,直到起始位置>=末尾位置
	int start = 0; //起始元素下标
	int end = sizeof(arr) / sizeof(arr[0]) - 1; //末尾元素下标
	//定义一个临时内存
	int temp;
	//交换起始元素和末尾元素
	while (start < end) 
	{
		temp = arr[start];  //实现元素互换
		arr[start] = arr[end];
		arr[end] = temp;
		start++;   //下标更新,往中间聚拢
		end--;
	}

	/******3.打印逆置后的数组*******/
	cout << "数组元素逆置后:" << endl;
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
	
	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习03:冒泡排序法

案例描述

  • 作用:最常用的排序算法,对数组内元素进行排序
  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
  • 重复以上的步骤,每次比较次数-1,直到不需要比较。
  • 示例:将数组{ 4,2,8,0,5,7,1,3,9 }进行升序排序

案例分析
在这里插入图片描述

代码:

/*********************************************************************
    程序名: 一维数组案例03
    作者: Sweitena
    日期: 2021-04-04 19:14
    说明: 冒泡排序法实现数组元素升序排列
*********************************************************************/
#include <iostream>
using namespace std;

int main() {

	//1.创建数组
	int arr[] = {4, 2, 8, 0, 5, 7, 1, 3, 9};
	int num = sizeof(arr) / sizeof(arr[0]); //确定元素有几个
	cout << "排序前:" << endl;
	for (int i = 0; i < num; i++) 
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	//2.开始冒泡排序
	//2.1 先对相邻的两个元素比较并交换位置:每轮对比次数 = 元素个数 - 排序轮数 - 1
	//2.2 排序总轮数 = 元素个数 - 1
	for (int j = 0; j < num - 1; j++)  //外层循环 做几轮比较 9个元素 需要比较8轮
	{  
		for (int i = 0; i < num - j - 1; i++)  //内层循环 每轮需要比较几次
		{  
			if (arr[i] > arr[i + 1]) 
			{
				//交换两个元素位置
				int temp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = temp;
			}
		}
	}
	
	//3.打印排序后的数组
	cout << "排序后:" << endl;
	for (int i = 0; i < num; i++) 
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


2.2 二维数组

2.2.1 定义

  • 二维数组就是在一维数组上多加一个维度

  • 二维数组定义的四种方式:

    1. 数据类型 数组名 [ 行数 ] [ 列数 ] ;
    2. 数据类型 数组名 [ 行数 ] [ 列数 ] = { {数据1,数据2},{数据3,数据4} };
    3. 数据类型 数组名 [ 行数 ] [ 列数 ] = {数据1,数据2,数据3,数据4};
    4. 数据类型 数组名 [ ] [ 列数 ] = {数据1,数据2,数据3,数据4};

    (建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性

代码:

/*********************************************************************
    程序名: 二维数组
    作者: Sweitena
    日期: 2021-04-06 08:55
    说明: 数组的定义
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	//二维数组的定义
	/****
	    1.数据类型 数组名[ 行数 ][ 列数 ];
	    2.数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2},{数据3,数据4} };
	    3.数据类型 数组名[ 行数 ][ 列数 ] ={ 数据1,数据2,数据3,数据4 };
	    4.数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
	****/
	//第①种定义方式
	cout << "第一种定义方式:" << endl;
	int arr[2][3];  //2行3列
	arr[0][0] = 1;
	arr[0][1] = 2;
	arr[0][2] = 3;
	arr[1][0] = 4;
	arr[1][1] = 5;
	arr[1][2] = 6;
	for (int i = 0; i < 2; i++)    //外层循环表示行
	{ 
		for (int j = 0; j < 3; j++)   //内层循环表示列
		{ 
			cout << arr[i][j] << " ";
		}
		cout << endl;
	}

	//第②种定义方式
	cout << "第二种定义方式:" << endl;
	int arr2[2][3] = {{1, 2, 3}, {4, 5, 6}};
	for (int i = 0; i < 2; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			cout << arr2[i][j] << " ";
		}
		cout << endl;
	}

	//第③种定义方式
	cout << "第三种定义方式:" << endl;
	int arr3[2][3] = {1, 2, 3, 4, 5, 6};
	for (int i = 0; i < 2; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			cout << arr3[i][j] << " ";
		}
		cout << endl;
	}

	//第④种定义方式
	cout << "第四种定义方式:" << endl;
	int arr4[ ][3] = {1, 2, 3, 4, 5, 6};
	for (int i = 0; i < 2; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			cout << arr4 [i][j] << " ";
		}
		cout << endl;
	}
	
	system("pause");

	return 0;
}

运行结果图:
在这里插入图片描述


2.2.2 数组名用途

二维数组名称的用途:

  1. 可以统计整个数组在内存中的长度
  2. 可以获取数组在内存中的首地址

代码:

/*********************************************************************
    程序名: 二维数组
    作者: Sweitena
    日期: 2021-04-06 08:58
    说明: 数组名的用途
*********************************************************************/
#include <iostream>
using namespace std;

int main() {

	//二维数组名称用途
	int arr4[ ][3] = {1, 2, 3, 4, 5, 6};

	//1.可以查看占用内存大小
	cout << "二维数组占用内存空间为:" << sizeof(arr4) << endl;
	cout << "二维数组第一行占用内存为:" << sizeof(arr4[0]) << endl;
	cout << "二维数组第一个元素占用内存为:" << sizeof(arr4[0][0]) << endl;
	cout << "二维数组行数:" << sizeof(arr4) / sizeof(arr4[0]) << endl;
	cout << "二维数组列数:" << sizeof(arr4[0]) / sizeof(arr4[0][0]) << endl;

	//可以查看二维数组的首地址
	cout << "二维数组的首地址为:" << arr4 << endl;
	cout << "二维数组的首地址为:" << (int)arr4 << endl;
	cout << "二维数组第一行首地址为:" << arr4[0] << endl;
	cout << "二维数组第一行首地址为:" << (int)arr4[0] << endl;

	system("pause");

	return 0;
}

运行结果图:

在这里插入图片描述


?案例练习:考试成绩统计

案例描述

  • 有三名同学(张三、李四、王五),在一次考试中的成绩分别如下表
  • 请分别输出三名同学的总成绩

在这里插入图片描述

代码:

/*********************************************************************
    程序名: 二维数组案例
    作者: Sweitena
    日期: 2021-04-06 11:00
    说明: 考试成绩统计,分别输出每名同学的总成绩
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>


int main() {
	//创建二维数组
	int scores[3][3] = {{100, 100, 100}, {90, 50, 100}, {60, 70, 80}} ; //第二种定义方式
	int sum = 0;
	string names[3] = {"张三", "李四", "王五"}; //创建名字的一维数组

	//让每一行的数据相加
	for (int i = 0; i < 3; i++) 
	{
		for (int j = 0; j < 3; j++) 
		{
			sum = scores[i][j] + sum;  //相当于sum += score[i][j];
		}
		cout << names[i] << "的总成绩为:" << sum << endl;
	}
	
	system("pause");
	return 0;
}

运行结果图:

在这里插入图片描述


三、函数

  • 作用:将一段经常使用的代码封装起来,减少重复代码。
  • 一个较大的程序一般分为若干个程序块,每个模块实现特定的功能。

3.1 函数定义

  • 函数的定义一般主要有5个步骤:

    1. 返回值类型
    2. 函数名
    3. 参数表列
    4. 函数体语句
    5. return表达式
  • 语法:

返回值类型 函数名(参数列表)
{
   
   函数体语句;
   
   return 表达式;
}
  • 举例分析:

在这里插入图片描述


3.2 函数声明

  • 作用:告诉编译器函数名称及如何调用函数

  • 函数的声明可以多次,但是函数的定义只能有一次

  • 举例分析:

针对上面的加法函数add(),以下是函数声明:

int add(int num1, int num2);

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:

int add(int, int);

3.3 调用函数

  • 作用:使用定义好的函数。
  • 语法:函数名 ( 参数 )

代码:

/*********************************************************************
    程序名: 函数定义、声明、调用
    作者: Sweitena
    日期: 2021-04-06 11:19
    说明: 以加法函数为例
*********************************************************************/
#include <iostream>
using namespace std;
//函数声明
int add(int num1, int num2); //加法函数的声明

int main() {
	int a, b, c;
	a = 5;   
	b = 10;
    //调用函数
	c = add(a, b);  //调用加法函数
	cout << c << endl;

	system("pause");

	return 0;
}

//函数定义
/****************实现一个加法函数****************/
/***功能:传入两个整型数据,计算相加结果并返回***/
int add(int num1, int num2)      
{ 
	int sum = num1 + num2;
	return sum;
}

运行结果图:

在这里插入图片描述


3.4 函数参数

3.4.1 向函数传递参数的方式

  • 如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

  • 形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

  • 当调用函数时,有三种向函数传递参数的方式:

    1. 传值调用
      该方法把参数的实际值赋值给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响
    2. 指针调用
      该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数
    3. 引用调用
      该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数

【注意】本章只介绍第一种值传递方式,后两种在指针和引用那两章里有详细解释。


3.4.1.1 传值调用

举例说明:修改函数内的形式参数对实际参数没有影响
在这里插入图片描述
代码:

/*********************************************************************
    程序名: 函数参数-值传递
    作者: Sweitena
    日期: 2021-04-09 19:54
    说明: 定义一个实现两个数字进行交换的函数
*********************************************************************/
#include <iostream>
using namespace std;
//函数声明
void swap(int num1, int num2); //交换函数

int main() 
{
	int a, b;
	a = 10;
	b = 20;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	/***********************************************************
	      当我们做值传递时,函数的形参发生变化,并不影响实参
	***********************************************************/
	cout << "调用swap()函数" << endl;
	swap(a, b);   //调用函数
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	system("pause");

	return 0;
}

//函数定义
/******************交换函数*******************/
/***功能:传入两个整型数据,交换2个数并返回***/
void swap(int num1, int num2)   //函数不需要返回值,所以写void
{   
	cout << "交换前:" << endl;
	cout << "num1 = " << num1 << endl;
	cout << "num2 = " << num2 << endl;

	int temp = num1;
	num1 = num2;
	num2 = temp;

	cout << "交换后:" << endl;
	cout << "num1 = " << num1 << endl;
	cout << "num2 = " << num2 << endl;
}

运行结果图:
在这里插入图片描述


3.4.1.2 指针调用

4.5.1节。


3.4.1.3 引用调用

5.3.1节。


3.4.2 函数的常见样式

常见的函数样式有4种:

  1. 无参无返
  2. 有参无返
  3. 无参有返
  4. 有参有返

代码:

/*********************************************************************
    程序名: 函数的常见样式
    作者: Sweitena
    日期: 2021-04-09 20:09
    说明: 1无参无返 2有参无返 3无参有返 4有参有返
*********************************************************************/
#include <iostream>
using namespace std;

//1.无参无返
void test01() 
{
	cout << "this is test01 for 无参无返" << endl;
}

//2.有参无返
void test02(int a) 
{
	cout << "this is test02 for 有参无返 a =" << a << endl;
}

//3.无参有返
int test03() 
{
	cout << "this is test03 for 无参有返" << endl;
	return 200;
}

//4.有参有返
int test04(int b)
{
	cout << "this is test04 for 有参有返 b=" << b << endl;
	return b;
}

int main()
{
	test01();     //无参无返调用
	test02(100);  //有参无返调用
	int num1 = test03();      //无参有返调用
	int num2 = test04(3000);  //有参有返调用
	
	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


3.5 Lambda 函数

  • C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。
  • Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
  • Lambda 表达式本质上与函数声明非常类似。
  • 在 lambda 函数的定义式中,参数列表和返回类型都是可选部分,而捕捉列表和函数体都可能为空,C++ 中最简单的 lambda 函数只需要声明为:[]{};
  • 语法:[ capture ]( parameters ) mutable -> return-type{ statement }

其中:

  1. [capture]:捕捉列表。捕捉列表总是出现在 lambda 表达式的开始处。事实上,[] 是 lambda 引出符。编译器根据该引出符判断接下来的代码是否是 lambda 函数。捕捉列表能够捕捉上下文中的变量供 lambda 函数使用。
  2. (parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号 () 一起省略。
  3. mutable:mutable 修饰符。默认情况下,lambda 函数总是一个 const 函数,mutable 可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
  4. ->return_type:返回类型。用追踪返回类型形式声明函数的返回类型。出于方便,不需要返回值的时候也可以连同符号 -> 一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
  5. {statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

【注意】详细解释将在后面的笔记介绍,目前对于基础知识部分有点超纲了吧。


3.6 函数的分文件编写

  • 作用:让代码结构更加清晰
  • 函数分文件编写一般有4个步骤:
    1. 创建.h后缀名的头文件
    2. 创建.cpp后缀名的源文件
    3. 在头文件中写函数的声明
    4. 在源文件中写函数的定义
  • 分文件编写的过程举例,依据3.4.1节提到的swap()代码:

step1: 创建项目

  • 步骤:文件 —— 新建… —— 项目… —— 基本 —— 控制台应用程序 —— C++项目 —— 名称(测试分文件编写swap) —— 确定。
  • 观察到此时项目名称下已经包含main.cpp文件。

在这里插入图片描述


step2: 创建swap.h的头文件,包含函数声明

  • 右键单击“测试分文件编写swap”(项目名称) —— 新建单元 —— 弹出的新文件重命名为swap.h

在这里插入图片描述
在这里插入图片描述


step3: 创建swap.cpp的源文件,包含函数定义

  • 步骤同上:右键单击“测试分文件编写swap”(项目名称) —— 新建单元 —— 弹出的新文件重命名为swap.cpp

在这里插入图片描述
在这里插入图片描述


step4: 在main.cpp文件中,可以调用swap()函数

  • 注意文件之间的关联关系。
  • 源文件swap.cppmain.cpp中都需要包含swap.h文件,即#include "swap.h"
  • 头文件swap.h和源文件main.cpp中都需要包含C++的原始框架,即#include <iostream>using namespace std;

在这里插入图片描述


step5: 最后,编译运行main.cpp
在这里插入图片描述


四、指针

4.1 指针的基本概念

  • 作用:可以通过指针间接访问内存。
  • 指针是一个变量,其值为另一个变量的地址,即:内存位置的直接地址。
  • 可以理解为:指针就是一个地址,可以通过指针来保存一个地址。

4.1.1 指针变量的定义和使用

  • 指针变量定义语法:数据类型 * 变量名;

代码:

/*********************************************************************
    程序名: 指针的定义和使用
    作者: Sweitena
    日期: 2021-04-12 10:47
    说明: 【作用】可以通过指针间接访问内存
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	/************************************************/
	/*************   1.定义指针   *******************/
	/************************************************/
	int a = 10;  //实际变量的声明:一个整型的变量
	int *p;      //指针变量的声明:一个整型的指针
	p = &a;      //在指针变量p中存储变量a的地址
	cout << "a的地址 &a = " << &a << endl;
	cout << "指针变量 p = " << p << endl;
	/************************************************/
	/*************   2.使用指针   *******************/
	/************************************************/
	cout << "访问指针中地址的值 *p = " << *p << endl; //通过解引用的方式找到指针指向的内存
	*p = 1000;   //指针前加*代表解引用,找到指针指向的内存中的数据
	cout << "更改之后的 *p = " << *p << endl;
	cout << "更改之后的 a = " << a << endl;

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


4.1.2 指针所占内存空间

  • 指针也是一种数据类型。
  • 所有指针的值的实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同

代码:

/*********************************************************************
    程序名: 指针所占的内存空间
    作者: Sweitena
    日期: 2021-04-12 14:08
    说明: 根据指针所指向的变量的数据类型定义不同数据类型的指针;
          在32位操作系统下,指针所占的内存空间都是4个字节。
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	int a = 10;
	int *p;
	p = &a;
	cout << "指针p所占用的内存空间为:" << sizeof(p) << endl;
	cout << "整型指针int *所占用的内存空间为:" << sizeof(int *) << endl;
    cout << "浮点型指针float *所占用的内存空间为:" << sizeof(float *) << endl;
    cout << "字符型指针char *所占用的内存空间为:" << sizeof(char *) << endl;

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


4.2 const 修饰指针

  • const修饰指针有三种情况:
    1. const 修饰指针——常量指针指针指向的值不可以改,指针指向可以改);
    2. const 修饰常量——指针常量指针指向的值可以改,指针指向不可以改);
    3. const既修饰指针,又修饰常量(指针指向的值不可以改,指针指向不可以改)。

4.2.1 常量指针 const int *p = &a

//初始代码:
int a = 10;  //a的地址:0x0011
int b = 10;  //b的地址:0x0022
int *p = &a; //将a的地址存储到p中,让p指向a

在这里插入图片描述


4.2.2 指针常量 int *const p = &a

//初始代码:
int a = 10;  //a的地址:0x0011
int b = 10;  //b的地址:0x0022
int *p = &a; //将a的地址存储到p中,让p指向a

在这里插入图片描述


4.2.3 既修饰指针又修饰常量 const int *const p = &a;

//初始代码:
int a = 10;  //a的地址:0x0011
int b = 10;  //b的地址:0x0022
int *p = &a; //将a的地址存储到p中,让p指向a

在这里插入图片描述


4.3 空指针和野指针

4.3.1 空指针

  • 定义:空指针指向内存中编号为0的空间
  • 作用:空指针用于给指针向量初始化
  • 【注意】空指针指向的内存是不可以访问的
    在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
  • C++11标准后,用nullptr来表示空指针。

代码:

/*********************************************************************
    程序名: 空指针
    作者: Sweitena
    日期: 2021-04-12 14:15
    说明: NULL 指针是一个定义在标准库中的值为零的常量
*********************************************************************/
#include <iostream>
using namespace std;

int main() {
	/**********定义一个整型指针**********/
	int a = 10; 
	int *g = &a;     //整型指针变量g指向a的地址
	cout << "g的值为:" << g << endl;
	/**********定义一个空指针**********/
	int *p = NULL;  //指针p是值为0的常量,空指针用于给指针变量进行初始化
	cout << "p的值为:" << p << endl;
	/*
	    //不能访问空指针,内存编号0-255为系统占用内存,不允许用户访问
	    *p = 100;
		cout << *p << endl;
	*/
	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述

  • 如需检查一个空指针,可以使用 if 语句,如下所示:
if(p)     /* 如果 p 非空,则完成... */
if(!p)    /* 如果 p 为空,则完成... */

4.3.2 野指针

  • 定义:指针变量指向非法的内存空间,野指针指向的位置是不可知的。
/*********************************************************************
    程序名: 野指针
    作者: Sweitena
    日期: 2021-04-12 14:22
    说明: 在程序中,尽量避免出现野指针
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	//指针变量p指向内存地址编号位0x1100的空间
	int *p = (int *) 0x1100;
	//访问野指针会报错,但是野指针不是我们申请的空间,因此不要访问
	//cout << *p << endl; //没有输出,是空的

	system("pause");
	return 0;
}

4.4 指针的运算

4.4.1 指针的算术运算

  • 指针是一个用数值表示的地址,可以对指针执行算术运算。可以对指针进行四种算术运算:++、–、+、-。

4.4.1.1 递增一个指针

  • 假设 p 是一个指向地址1000整型指针,是一个 32 位的整数,让我们对该指针执行下列的算术运算:p++
  • 在执行完上述的运算之后,p 将指向位置 1004,因为 p 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果 p 指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001

代码:

/*********************************************************************
    程序名: 指针递增运算
    作者: Sweitena
    日期: 2021-04-12 14:25
    说明: 习惯使用指针代替数组,变量指针可以递增,而数组不能递增
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	int arr[3] = {1, 2, 3};  //定义一个名为arr的一维数组
	int *p;                  //定义一个名为p的整型指针  
	p = &arr[0];             //令整型指针p指向数组首地址
	/*** 【补充】数组名是数组的首地址,所以也可以写成 p = &arr ***/

	for (int i = 0; i < 3; i++) 
	{
		cout << "第" << i << "个元素的地址是:" << p << endl;
		cout << "\t   值是:" << *p << endl;
		p++;  //移动到下一个元素的位置
	}

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


4.4.1.2 递减一个指针

  • 同样地,对指针进行递减运算,即把值减去其数据类型的字节数。

代码:

/*********************************************************************
    程序名: 指针递减运算
    作者: Sweitena
    日期: 2021-04-12 14:28
    说明: 与递增相反的去理解,指针往回走
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	int arr[3] = {1, 2, 3};  //定义一个名为arr的一维数组
	int *p;                  //定义一个名为p的整型指针
	p = &arr[3 - 1];         //令整型指针p指向数组最后一个元素的地址
	/***【补充】一共有3个元素,用“元素个数-1”表示取到该数组的最后一个元素 ***/

	for (int i = 0; i < 3; i++) 
	{
		cout << "第" << i << "个元素的地址是:" << p << endl;
		cout << "\t   值是:" << *p << endl;
		p--;  //移动到下一个元素的位置
	}

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


4.4.2 指针的比较运算

  • 指针可以用关系运算符进行比较,如 ==、< 和 >。
  • 如果 p1 和 p2 指向两个相关的变量,比如:同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较。

代码:

/*********************************************************************
    程序名: 指针比较运算
    作者: Sweitena
    日期: 2021-04-12 14:29
    说明: 可以比较指针中存储的地址的大小
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	int arr[3] = {1, 2, 3};  //定义一个名为arr的一维数组
	int *p1, *p2, *p3;       //定义三个名为p1、p2、p3的整型指针
	p1 = &arr[0];            //令指针p1指向数组第一个元素的地址
	p2 = &arr[1];            //令指针p2指向数组第二个元素的地址
	p3 = &arr[2];            //令指针p2指向数组第三个元素的地址

	if (p1 <= p3)            //指针p1中的地址是否小于指针p3中的地址
	{
		p1++;    //指针指向下一个位置,p1会指向第二个元素,相当于p2
		cout << "此时p1的地址为:" << p1 << endl;
		cout << "p1指向的元素为:" << *p1 << endl;
	}

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


4.5 指针和数组

4.5.1 指针数组

  • 当我们想要让数组存储指向 int 或其他数据类型的指针时,可以使用指针数组。
  • 指针数组的语法:数据类型 * 变量名 [ 数组长度 ];

代码片段:

//下面是一个指向整数的指针数组的声明:
int *p[max];
//在这里,把 p 声明为一个数组,由max个整数指针组成。因此,p中的每个元素,都是一个指向int值的指针。
//也就是说p[0]存放的是一个指针,这个指针指向数组的第一个元素,可以用解引用*p[0]得出元素的值。

代码:

/*********************************************************************
    程序名: 指针数组
    作者: Sweitena
    日期: 2021-04-16 10:08
    说明: 【举例】将三个整数存放在指针数组中
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	int arr[3] = {1, 2, 3};     //定义一个名为arr的一维数组,包含3个元素
	int *p[3];                  //定义一个名为p的指针数组,长度为3
	
	for (int i = 0; i < 3; i++) //用for循环将数组中元素的地址存放在指针中
	{
		p[i] = &arr[i];          
	}

	for (int j = 0; j < 3; j++) //用for循环打印数组
	{
		cout << "原数组:" << "arr[" << j << "]=" << arr[j] << endl;
		cout << "地址:" << p[j] << endl;
		cout << "通过指针数组显示原数组:" << "*p[" << j << "]=" << *p[j] << endl;
	}

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述

  • 也可以用一个指向字符的指针数组来存储一个字符串列表,代码如下。
    【 这是菜鸟教程里的笔记的内容: char *p[3]是指针数组,它的本质是存储指针的数组,即存储char类型的指针的数组,数组内的每个元素都是一个指针,指向一个存储char类型的地址。】

代码:

#include <iostream>
using namespace std;

int main() 
{
	const char *p[3] = {"zara", "hina", "nuha"}; //用一个指向字符的指针数组来存储一个字符串列表

	cout << "输出p[i]如下:" << endl;
	cout << "p[0]=" << p[0] << " ";
	cout << "p[1]=" << p[1] << " ";
	cout << "p[2]=" << p[2] << " ";
	cout << endl;
	cout << endl;
	cout << "输出&(p[i])如下:" << endl;
	cout << "&(p[0])=" << &(p[0]) << " ";
	cout << "&(p[1])=" << &(p[1]) << " ";
	cout << "&(p[2])=" << &(p[2]) << " ";
	cout << endl;
	cout << endl;
	cout << "输出*p[i]如下:" << endl;
	cout << "*p[0]=" << *p[0] << " ";
	cout << "*p[1]=" << *p[1] << " ";
	cout << "*p[2]=" << *p[2] << " ";
	cout << endl;
	cout << endl;
	cout << "输出&(*p[i])如下:" << endl;
	cout << "&(*p[0])=" << &(*p[0]) << " ";
	cout << "&(*p[1])=" << &(*p[1]) << " ";
	cout << "&(*p[2])=" << &(*p[2]) << " ";
	cout << endl;
	cout << endl;
	cout << "输出p[0][i]如下:" << endl;
	cout << "p[0][0]=" << p[0][0] << " ";
	cout << "p[0][1]=" << p[0][1] << " ";
	cout << "p[0][2]=" << p[0][2] << " ";
	cout << "p[0][3]=" << p[0][3] << " ";
	cout << endl;
	cout << endl;
	cout << "输出&(p[0][i])如下:" << endl;
	cout << "&(p[0][0])=" << &(p[0][0]) << " ";
	cout << "&(p[0][1])=" << &(p[0][1]) << " ";
	cout << "&(p[0][2])=" << &(p[0][2]) << " ";
	cout << "&(p[0][3])=" << &(p[0][3]) << " ";
	cout << endl;
	cout << endl;
	cout << "输出*p[0]+i如下:" << endl;
	cout << "*p[0] + 1 =" << *p[0] + 1 << " ";
	cout << "*p[0] + 2 =" << *p[0] + 2 << " ";
	cout << "*p[0] + 3 =" << *p[0] + 3 << " ";
	cout << endl;
	cout << endl;

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述
请添加图片描述


4.5.2 指向数组的指针

  • 利用指针访问数组元素,下面给出了一个指向 int 型的指针,它可以存储一个 int 类型的变量。一旦我们有了 p 中的地址,*p 将给出存储在 p 中相应地址的值。

代码:

/*********************************************************************
    程序名: 指向数组的指针
    作者: Sweitena
    日期: 2021-04-16 10:12
    说明: 【作用】利用指针访问数组元素
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	//1.创建数组
	int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

	//2.正常输出数组元素
	for (int i = 0; i < 10; i++) 
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	//3.用指针访问数组元素
	int *p = arr; //arr是数组的首地址
	for (int j = 0; j < 10; j++) 
	{
		cout << *p << " " ;
		p++;   //指针指向下一个位置
	}
	cout << endl;

	system("pause");
	return 0;
}

运行结果图:

在这里插入图片描述

  • 使用数组名作为常量指针是合法的,因此,*( arr + 4)是一种访问arr[4]数据的合法方式。一旦把第一个元素的地址存储在p中,可以使用*p 、 *(p+1) 、 *(p+2)等来访问数组元素。

代码:

/*********************************************************************
    程序名: 指向数组的指针
    作者: Sweitena
    日期: 2021-04-16 10:14
    说明: 【举例】针对一个含有5个double型变量的数组,用指针指向该数组
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	//创建 数组 和 指向数组的指针
	double arr[] = {0.1, 3.14, 17.3, 102.4, 5.8};
	double *p;   //定义一个名为p的双精度浮点型指针

	p = arr;
	// 两种方式输出数组中每个元素的值
	for (int i = 0; i < 5; i++) 
    {
		cout << "*(p + " << i << ")" << "=" << *(p + i) << endl;
		cout << "*(arr +" << i << ") " << "=" << *(arr + i) << endl;
	}

	system("pause");
	return 0;
}

运行结果图:

在这里插入图片描述


4.6 指针和函数

4.6.1 指针调用(地址传递)

  • 指针调用:该方法把参数的地址赋值给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数
  • 作用:利用指针作函数参数,可以修改实参的值。

代码:

/*********************************************************************
    程序名: 值传递vs地址传递
    作者: Sweitena
    日期: 2021-04-16 10:25
    说明: 如果是地址传递,可以修改实参
*********************************************************************/
#include <iostream>
using namespace std;

//函数声明
void swap01(int num1, int num2);//实现两个数字交换的函数:值传递
void swap02(int *p1, int *p2);  //实现两个数字交换的函数:地址传递

int main() 
{
	int a, b;
	a = 10;
	b = 20;
	//1.值传递
	cout << "entering 值传递函数:" << endl;
	swap01( a, b );
	cout << "swap01中的a = " << a << endl;
	cout << "swap01中的b = " << b << endl;
	//2.地址传递
	cout << "entering 地址传递函数:" << endl;
	swap02( &a, &b );
	cout << "swap02中的a = " << a << endl;
	cout << "swap02中的b = " << b << endl;

	system("pause");
	return 0;
}

/********** 实现两个数字交换的函数:值传递 **********/
void swap01(int num1, int num2) 
{
	cout << "交换前:" << endl;
	cout << "num1 = " << num1 << endl;
	cout << "num2 = " << num2 << endl;
	int temp = num1;
	num1 = num2;
	num2 = temp;
	cout << "交换后:" << endl;
	cout << "num1 = " << num1 << endl;
	cout << "num2 = " << num2 << endl;
}

/********** 实现两个数字交换的函数:地址传递 **********/
void swap02(int *p1, int *p2) 
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

运行结果图:
在这里插入图片描述


4.7 指针配合数组和函数

4.7.1 从函数返回数组或指针

  • C++ 不允许返回一个完整的数组作为函数的参数。(但是数组其实就是指针,所以可以让函数返回指针来实现~)
  • 可以通过指定不带索引的数组名来返回一个指向数组的指针。
  • 如果想要从函数返回一个一维数组,必须声明一个返回指针的函数,如下:
int * myFunction()
{
.
.
.
}

案例描述

  • 生成 10 个随机数,并使用数组来返回它们。
int *getRandom( ) 
{
	static int  arr[10];
	
	srand( (unsigned)time( NULL ) ); //添加随机数种子,作用:利用当前系统时间生成随机数

	for (int i = 0; i < 10; ++i) 
    {
		arr[i] = rand();  //生成10个随机数,默认情况下生成的是一个五位数
		cout << arr[i] << endl;  //打印输出10个随机数
	}
	
	return arr;  //返回数组名
}

代码:

/*********************************************************************
    程序名: 从函数返回数组
    作者: Sweitena
    日期: 2021-07-25 17:57
    说明: C++不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。
*********************************************************************/
#include <iostream>
#include <ctime>  //系统头文件
using namespace std;


/************************************************/
/*************  函数名:getRandom( ) ************/
/************ 功能:生成和返回随机数 ************/
/************************************************/
int *getRandom( ) 
{
	static int  arr[10];
	
	srand( (unsigned)time( NULL ) ); //添加随机数种子,作用:利用当前系统时间生成随机数

	for (int i = 0; i < 10; ++i) 
    {
		arr[i] = rand();  //生成10个随机数,默认情况下生成的是一个五位数
		cout << arr[i] << endl;  //打印输出10个随机数
	}
	
	return arr;  //返回数组名
}

int main() 
{
	int *p; //定义一个指向整数的指针

	p = getRandom();  //相当于 p = arr;  通过指针,让函数返回数组

	for ( int i = 0; i < 10; i++ ) 
    {
		cout << "*(p + " << i << ") : " << *(p + i) << endl;
	}

	system("pause");
	return 0;
}


运行结果图:
在这里插入图片描述


4.7.2 传递数组给函数

  • C++ 中可以通过指定不带索引的数组名来传递一个指向数组的指针。
  • 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。
  • 如果想要在函数中传递一个一维数组作为参数,必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。同样地,也可以传递一个多维数组作为形式参数。
  1. 方式1: 形式参数是一个指针
void myFunction(int *parameter)
{
.
.
.
}
  1. 方式2: 形式参数是一个已定义大小的数组
void myFunction(int parameter[10])
{
.
.
.
}
  1. 方式3: 形式参数是一个未定义大小的数组
void myFunction(int parameter[])
{
.
.
.
}

案例描述

  • 函数功能:把数组作为参数,同时传递另一个参数,根据所传的参数,返回数组中各元素的平均值。
double getAverage(int arr[], int size)  //形式参数是一个未定义大小的数组
{
  int sum = 0;       
  double avg;          
 
  for (int i = 0; i < size; i++)
  {
    sum += arr[i];  //相当于sum = sum + arr[i];
   }
 
  avg = double(sum) / size;
 
  return avg;      //返回平均值
}

代码:

/*********************************************************************
    程序名:传递数组给函数
    作者: Sweitena
    日期: 2021-07-23 07:45
    说明: 返回数组中的平均值
*********************************************************************/
#include <iostream>
using namespace std;

/************************************************/
/************ 函数名:getAverage(  ) ************/
/************ 功能:返回数组的平均值 ************/
/************************************************/
double getAverage(int arr[], int size) 
{
	int sum = 0;
	double avg;

	for (int i = 0; i < size; i++) 
	{
		sum += arr[i];  //相当于sum = sum + arr[i];累加数组的元素
	}

	avg = double(sum) / size;

	return avg;      //返回平均值
}

int main () 
{
	int balance[5] = {1000, 2, 3, 17, 50};  //定义一个带有5个元素的整型数组

	double avg;    //定义双精度的浮点型变量avg,作为数组的平均值

	avg = getAverage( balance, 5 ) ;        //传递一个指向数组的指针作为参数

	cout << "平均值是:" << avg << endl;    //输出返回值

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习:冒泡排序法

案例描述

  • 封装一个函数,利用冒泡排序,实现对整型数组的升序排列
  • 例如数组:`int arr[] = {4, 3, 6, 9, 1, 2, 10, 8, 7, 5};

案例分析

  1. 首先,创建数组
  2. 创建函数,实现冒泡排序
  3. 打印排序后的数组

代码:

/*********************************************************************
    程序名: 指针、数组、函数
    作者: Sweitena
    日期: 2021-04-18 13:47
    说明: 封装一个函数,利用冒泡排序,实现对整型数组的升序排列
*********************************************************************/
#include <iostream>
using namespace std;

//函数声明
void BubbleSort(int *arr, int num); //冒泡排序函数
void PrintArray(int *arr, int num); //打印数组函数


int main() 
{
	//1.先创建数组
	int arr[] = {4, 3, 6, 9, 1, 2, 10, 8, 7, 5};
	int num = sizeof(arr) / sizeof(arr[0]);  //确定数组的长度
	cout << "排序前:" << endl;              //打印原始数组
	PrintArray(arr, num);

	//2.创建函数,实现冒泡排序
	BubbleSort(arr, num);                   //调用冒泡排序函数

	//3.打印排序后的数组
	cout << "排序后:" << endl;             //打印排序后的数组
	PrintArray(arr, num);

	system("pause");
	return 0;
}

/************函数名:BubbleSort(int *arr, int num)*************/
/***********功能:冒泡排序,实现对整型数组的升序排列***********/
/*******形式参数:【参数1】数组首地址,【参数2】数组长度*******/
void BubbleSort(int *arr, int num) 
{
	for (int j = 0; j < num - 1; j++) //外层循环 做几轮比较 9个元素 需要比较8轮
    {  
		for (int i = 0; i < num - j - 1; i++) //内层循环 每轮需要比较几次
        {  
			if (arr[i] > arr[i + 1]) 
            {
				//交换两个元素位置
				int temp = arr[i];
				arr[i] = arr[i + 1];
				arr[i + 1] = temp;
			}
		}
	}
}
/************函数名:PrintArray(int *arr, int num)*************/
/***********************功能:打印数组*************************/
/*******形式参数:【参数1】数组首地址,【参数2】数组长度*******/
void PrintArray(int *arr, int num) 
{
	for (int i = 0; i < num; i++) 
    {
		cout << arr[i] << " ";
	}
	cout << endl;
}

运行结果图:

在这里插入图片描述


五、引用

5.1 引用的基本概念

  • 作用:引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。
  • 一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

5.1.1 引用的定义和使用

  • 引用变量定义语法:数据类型 & 变量名;

代码:

/*********************************************************************
    程序名:引用的定义和使用
    作者: Sweitena
    日期: 2021-08-01 20:56
    说明: 引用在创建时就要被初始化
*********************************************************************/
#include <iostream>
using namespace std;

int main() 
{
	//声明简单的变量
	int    i = 5;
	double d = 11.7;

	//声明引用变量
	int & r1 = i;
	double & r2 = d;

	//输出
	cout << "i = " << i << endl;
	cout << "& i = " << r1 << endl;
	cout << "d = " << d << endl;
	cout << "& d = " << r2 << endl;


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


5.2 引用vs指针

  • 引用很容易与指针混淆,它们之间有三个主要的不同

    1. 不存在空引用。引用必须连接到一块合法的内存。
    2. 重新赋值问题:一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
    3. 初始化问题:引用必须在创建时被初始化,指针可以在任何时间被初始化。

代码片段1:

int a = 3;
int *p;       //可以不被初始化
int &r = a;   //必须在创建时被初始化

查看汇编代码:
在这里插入图片描述

代码片段2:

int a = 3, b = 6;
//指针
int *p = &a;  //让指针指向a,p里面存放的是a的地址
p = &b;       //让指针指向b,p里面存放的是b的地址
//引用
int &r = a;   //r指向a,r是a的引用
r = b;        //相当于a = b;是把b赋值给a,r始终是a的引用,一切对r的操作实际上是对a的操作

代码片段3:

//承接上面的代码2
p++;  //在数组中,会指向下一个元素
r++;  //相当于a++,此时a的值为4

代码片段4:

class A  //定义一个类
{
   int a;
   int b;
   int c;
   int d;
}

A a;
A *ap = a;   //定义一个指针
A &ar = a;   //定义一个引用

printf(sizeof(ap));  //指针所占内存是4个字节
printf(sizeof(ar));  //引用是16个字节,因为类A中有4个int型的变量

5.3 引用和函数

5.3.1 引用调用(地址传递)

  • 作用:使用引用来实现调用函数。
  • 该方法把参数的引用赋值给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数

代码:

/*********************************************************************
    程序名:使用引用调用函数
    作者: Sweitena
    日期: 2021-08-03 18:27
    说明: 对比之前学过的使用指针调用函数
*********************************************************************/
#include <iostream>
using namespace std;

//函数声明
void swap03(int &r1, int &r2);  //实现两个数字交换的函数

int main() 
{
	int a, b;
	a = 10;
	b = 20;
    //使用引用调用函数
	swap03( a, b );
	cout << "swap03中的a = " << a << endl;
	cout << "swap03中的b = " << b << endl;

	system("pause");
	return 0;
}

/********** 实现两个数字交换的函数:地址传递 **********/
void swap03(int &r1, int &r2) 
{
	int temp = r1;
	r1 = r2;
	r2 = temp;
}

运行结果图:
在这里插入图片描述


5.4 引用配合数组和函数

5.4.1 从函数返回数组或引用

  • 通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护。C++ 函数可以返回一个引用,方式与返回一个指针类似。
  • 当函数返回一个引用时,则返回一个指向返回值的隐式指针。这样,函数就可以放在赋值语句的左边。

代码:

/*********************************************************************
    程序名:从函数返回数组或引用
    作者: Sweitena
    日期: 2021-08-03 19:06
    说明: 与4.7.2节对应着去理解,和指针的用法类似
*********************************************************************/
#include <iostream>
using namespace std;

double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};  //定义一个浮点型数组

/************************************************/
/*************  函数名:setValues( ) ************/
/********** 功能:改变数组中第i个元素 ***********/
/************************************************/
double &setValues(int i) 
{
	double &ref = vals[i];  //ref是一个引用变量,ref引用vals[i]
	return ref;   
}

int main() 
{
	//1、输出调用函数前的数组
    cout << "改变前的值" << endl;
	for ( int i = 0; i < 5; i++ ) 
    {
		cout << "vals[" << i << "] = " << vals[i] << endl;
	}
    
    //2、调用函数改变元素的值
	setValues(1) = 20.23; // 改变第 2 个元素
	setValues(3) = 70.8;  // 改变第 4 个元素
    
    //3、输出改变后的数组
	cout << "改变后的值" << endl;
	for ( int i = 0; i < 5; i++ ) 
    {
		cout << "vals[" << i << "] = " << vals[i] << endl;
	}

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


六、结构体

6.1 结构体的基本概念

  • 作用:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。

6.1.1 结构体的定义和使用

  • 语法:struct 结构体名 { 结构体成员列表 };
  • 通过结构体创建变量的方式有三种:
    1. struct 结构体名 变量名
    2. struct 结构体名 变量名 = { 成员1值,成员2值…}
    3. 定义结构体时顺便创建变量

代码:

/*********************************************************************
    程序名: 结构体定义和使用
    作者: Sweitena
    日期: 2021-04-18 14:37
    说明: [定义]结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
          [注意]在使用时可以不写struct,直接写Student s1...
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/
//1. 创建学生数据类型,包括(姓名、年龄、分数)
struct Student 
{
	//成员列表
	string name;    //学生姓名
	int age;        //学生年龄
	int score;      //学生分数
} s3;

/******************结构体使用*******************************/
int main() 
{
// 2.通过学生类型创建具体学生
// 2.1 第一种方式:struct Student s1
	struct Student s1;
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;
	cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;

// 2.2 第二种方式:struct Student s2 = { ..., ..., ... }
	struct Student s2 = {"李四", 19, 80};
	cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;

// 2.3 第三种方式:在定义结构体时顺便创建结构体变量
	s3.name = "王五";
	s3.age = 20;
	s3.score = 70;
	cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl;

	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


6.2 结构体数组

  • 作用:将自定义的结构体放入到数组中方便维护。
  • 语法:struct 结构体名 数组名 [ 元素个数 ] = { { } , { } , . . . { } }

代码:

/*********************************************************************
    程序名: 结构体数组
    作者: Sweitena
    日期: 2021-05-09 15:56
    说明: 先有结构体定义,再去创建结构体数组
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/
//1. 创建学生数据类型,包括(姓名、年龄、分数)
struct Student 
{
	//成员列表
	string name;
	int age ;
	int score;
};

/******************结构体使用*******************************/
int main() 
{
//2.创建结构体数组,包含三个学生
	struct Student stuarr[3] = 
    {
		{"张三", 18, 100},
		{"李四", 19, 80},
		{"王五", 20, 70}
	};

//3.遍历结构体数组,实现信息输出
	for (int i = 0; i < 3; i++) 
    {
		cout << "姓名:" << stuarr[i].name << " 年龄:" << stuarr[i].age << " 分数:" << stuarr[i].score << endl;
	}
	cout << endl;

//4.给结构体数组中的元素赋值
	stuarr[2].name = "赵六";
	cout << "修改某一元素后输出:" << endl;  
	for (int i = 0; i < 3; i++)  
    {
		cout << "姓名:" << stuarr[i].name << " 年龄:" << stuarr[i].age << " 分数:" << stuarr[i].score << endl;
	}
	cout << endl;


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


6.3 结构体指针

  • 作用:通过指针访问结构体中的成员。
  • 利用操作符->可以通过结构体指针访问结构体属性。

代码:

/*********************************************************************
    程序名: 结构体指针
    作者: Sweitena
    日期: 2021-05-09 16:32
    说明:利用操作符" -> "可以通过结构体指针访问结构体属性
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/
//1. 创建学生数据类型,包括(姓名、年龄、分数)
struct Student 
{
	//成员列表
	string name;
	int age ;
	int score;
};

/******************结构体使用*******************************/
int main() 
{
//2、创建学生结构体变量
	Student s;
	s = {"张三", 18, 100};

//3、直接输出结构体变量中的数据
	cout << "常规输出方式:" << endl;
	cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl;

//4、通过指针指向结构体变量
	Student *p = &s;

//5、通过指针访问结构体变量中的数据
	cout << "使用指针输出:" << endl;
	cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


6.4 结构体嵌套结构体

  • 作用:结构体的成员可以是另一个结构体。
  • 例如:每个老师辅导一个学生,则一个老师的结构体中记录一个学生的结构体。

代码:

/*********************************************************************
    程序名: 结构体嵌套结构体
    作者: Sweitena
    日期: 2021-05-09 16:45
    说明:【作用】结构体中的成员可以是另一个结构体
         【例子】每个老师辅导一个学生,一个老师的结构体中记录一个学生的结构体
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>


/******************结构体定义*******************************/
//学生结构体定义,包括(姓名、年龄、分数)
struct Student 
{
	//成员列表
	string name;
	int age ;
	int score;
};

//老师结构体定义,包含(ID、姓名、年龄)以及学生结构体
struct Teacher 
{
	//成员列表
	int id;       //职工编号
	string name;  //教师姓名
	int age ;     //教师年龄
	struct Student stu; //子结构体 学生
};

/******************结构体使用*******************************/
int main() 
{
//1、创建老师结构体变量
	Teacher t1;
	t1.id = 200112;
	t1.name = "老王";
	t1.age = 75;

//2、子结构体赋值
	t1.stu.name = "小付";
	t1.stu.age = 23;
	t1.stu.score = 100;

//3、输出老师结构体变量中的数据
	cout << "老师姓名:" << t1.name << endl;
	cout << "老师编号:" << t1.id << endl;
	cout << "老师年龄:" << t1.age << endl;
	cout << "老师辅导的学生姓名:" << t1.stu.name << endl;
	cout << "学生年龄:" << t1.stu.age << endl;
	cout << "学生分数:" << t1.stu.score << endl;


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


6.5 结构体做函数参数

  • 作用:将结构体作为参数向函数中传递。
  • 传递方式:
    1. 值传递
    2. 地址传递

代码:

/*********************************************************************
    程序名: 结构体做函数参数
    作者: Sweitena
    日期: 2021-05-12 10:10
    说明: ①值传递:形参改变,实参不变
          ②地址传递:形参改变,实参也变
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/

//学生结构体的定义,包括(姓名、年龄、分数)
struct student 
{
	//成员列表
	string name;
	int age;
	int score;
};

/******************结构体使用*******************************/

/********* 函数名:Printstudent_1(struct student s) *********/
/************** 功能:值传递方式——打印学生信息 **************/
/************ 形式参数:【参数1】学生结构体变量 *************/
void Printstudent_1(struct student s) 
{
	cout << "值传递函数中:" << endl;
	cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl;
}

/********* 函数名:Printstudent_2(struct student *p) **********/
/************** 功能:地址传递方式——打印学生信息 **************/
/******** 形式参数:【参数1】指向学生结构体变量的指针 *********/
void Printstudent_2(struct student *p) 
{
	//p->age = 90;  //会改变实参
	cout << "地址传递函数中:" << endl;
	cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;
}

int main() 
{
//1、创建学生结构体变量,并赋值
	student s = {"张三", 18, 100};

//2、在主函数中打印结构体变量中的数据
	cout << "主函数中:" << endl;
	cout << "姓名:" << s.name << " 年龄:" << s.age << " 分数:" << s.score << endl;

//3、通过值传递方式打印
	Printstudent_1(s);   //值传递

//4、通过地址传递方式打印
	Printstudent_2(&s);  //地址传递


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


6.6 结构体中const的使用

  • 作用:用const来防止误操作

代码:

/*********************************************************************
    程序名: 结构体中const使用场景
    作者: Sweitena
    日期: 2021-05-12 10:47
    说明:【作用】在地址传递过程中,为防止误操作修改实参,可以加入const
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/

//学生结构体的定义,包括(姓名、年龄、分数)
struct student 
{
	//成员列表
	string name;
	int age;
	int score;
};

/******************结构体使用*******************************/

/********* 函数名:Printstudent(const student *p) **********/
/*************** 功能:打印结构体中的数据 ******************/
/***** 形式参数:【参数1】指向学生结构体变量的常量指针 *****/
void Printstudent(const student *p) 
{
	//p->age = 90;  //会改变实参,但是加入const之后,一旦有修改的操作就会报错,防止误操作
	cout << "姓名:" << p->name << " 年龄:" << p->age << " 分数:" << p->score << endl;
}

int main() 
{
//1、创建学生的结构体变量
	struct student s = {"张三", 18, 100};

//2、调用函数打印结构体中的数据
	Printstudent(&s);


	system("pause");
	return 0;
}

运行结果图:
请添加图片描述

?案例练习01:嵌套结构体

案例描述

  • 学校正在做毕设项目,每名老师带领5个学生,总共有3名老师。
  • 需求:设计学生和老师的结构体,其中在老师的结构体中,有2个成员:①姓名、②一个存放5名学生的数组。在学生的结构体中,有2个成员:①姓名、②考试分数。
  • 创建数组存放3名老师,通过函数给每个老师及所带的学生赋值,最终打印出老师数据以及老师所带的学生数据。

案例分析
在这里插入图片描述

代码:

/*********************************************************************
    程序名: 结构体案例01
    作者: Sweitena
    日期: 2021-05-12 14:02
    说明: 【案例描述】学校正在做毕设项目,每名老师带领5个学生,总共有3名老师,
          需求如下:设计学生和老师的结构体,其中在老师的结构体中,有老师姓名
          和存放5个学生的数组作为成员,学生的成员有姓名、考试分数,创建数组
          存放3名老师,通过函数给每个老师及所带的学生赋值,最终打印出老师数据
          以及老师所带的学生数据。
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>  //字符串
#include <ctime>   //系统时间

/******************结构体定义*******************************/

//学生结构体的定义,包括(姓名、考试分数)
struct student 
{
	//成员列表
	string sname;            //学生姓名
	int score;               //考试分数
};

//老师结构体的定义,包括(姓名、存放5名学生的数组)
struct teacher 
{
	//成员列表
	string tname;            //教师姓名
	struct student sarr[5];  //学生数组
};

/******************结构体使用*******************************/

/****************** 函数名:allocateSpace( ) *******************/
/*************** 功能:给老师和学生赋值的函数 ******************/
/****** 形式参数:【参数1】老师的数组、【参数2】数组长度 *******/
void allocateSpace(struct teacher tarr[], int len)   //传递数组给函数:这是4.7.2节提到的方式3
{
	string nameSeed = "ABCDE";
	 
	for (int i = 0; i < len; i++)        //外侧循环:给老师赋值
    {
		tarr[i].tname = "Teacher_";
		tarr[i].tname += nameSeed[i]; //相当于在Teacher_后,追加了一个nameSeed

		for (int j = 0; j < 5; j++)     //内侧循环:给每名老师所带的学生赋值
        {
			tarr[i].sarr[j].sname = "Student_";
			tarr[i].sarr[j].sname += nameSeed[j];
			int randomnum = rand() % 61 + 40; //生成40~100的随机数
			tarr[i].sarr[j].score = randomnum;
		}
	}
}

/******************** 函数名:printInfo( ) *********************/
/***************** 功能:打印所有信息的函数 ********************/
/****** 形式参数:【参数1】老师的数组、【参数2】数组长度 *******/
void printInfo(struct teacher tarr[], int len) 
{
	for (int i = 0; i < len; i++)     //外侧循环:输出老师的信息
    {
		cout << "老师的姓名:" << tarr[i].tname << endl;
		
        for (int j = 0; j < 5; j++)   //内侧循环:输出老师所带学生的信息
        {
			cout << "\t学生的姓名:" << tarr[i].sarr[j].sname << " 分数:" << tarr[i].sarr[j].score << endl;
		}
		cout << endl;
	}
}


int main() 
{
	srand((unsigned int)time(NULL));  //随机数种子

//1、创建3名老师的数组
	struct teacher tarr[3];

//2、通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(tarr) / sizeof(tarr[0]);  //求出老师的数组长度
	allocateSpace(tarr, len);

//3、打印所有老师及所带学生的信息
	printInfo(tarr, len);


	system("pause");
	return 0;
}

运行结果图:
在这里插入图片描述


?案例练习02:冒泡排序法

案例描述

  • 设计一个英雄的结构体,成员包括:①姓名、②年龄、③性别;
  • 创建结构体数组,数组中存放5名英雄;
  • 通过冒泡排序法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
  • 例如:5名英雄信息已给出
    请添加图片描述

代码:

/*********************************************************************
    程序名:结构体案例02
    作者: Sweitena
    日期: 2021-05-12 16:20
    说明: 【案例描述】设计一个英雄的结构体,包括成员姓名,年龄,性别;
           创建结构体数组,数组中存放5名英雄。通过冒泡排序的算法,将
           数组中的英雄按照年龄进行升序排列,最终打印排序结果。
*********************************************************************/
#include <iostream>
using namespace std;
#include <string>

/******************结构体定义*******************************/

//英雄结构体的定义,包括(姓名、年龄、性别)
struct hero 
{
	//成员列表
	string name;
	int age;
	string sex;
};

/******************结构体使用*******************************/

/******************** 函数名:bubbleSort( ) *********************/
/************** 功能:冒泡排序-实现年龄升序排列 *****************/
/******* 形式参数:【参数1】英雄的数组、【参数2】数组长度 *******/
void bubbleSort(struct hero arr[], int len)   //冒泡排序法的应用 
{
	for (int i = 0; i < len - 1; i++) 
	{
		for (int j = 0; j < len - i - 1; j++) 
		{
			if (arr[j].age > arr[j + 1].age) 
			{
				//交换位置
				struct hero temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
/******************** 函数名:printHero( ) *********************/
/***************** 功能:打印数组信息的函数 ********************/
/****** 形式参数:【参数1】英雄的数组、【参数2】数组长度 *******/
void printHero(struct hero arr[], int len) 
{
	for (int i = 0; i < len; i++) 
	{
		cout << "\t姓名:" << arr[i].name << " 年龄:" << arr[i].age << " 性别:" << arr[i].sex << endl;
	}
}


int main() 
{
//1、创建数组存放5名英雄
	struct hero arr[5] = 
	{
		{"刘备", 23, "男"},
		{"关羽", 22, "男"},
		{"张飞", 20, "男"},
		{"赵云", 21, "男"},
		{"貂蝉", 19, "女"}
	};
	int len = sizeof(arr) / sizeof(arr[0]);  //求出英雄数组的长度
	cout << "原来数组信息:" << endl;
	printHero(arr, len);

//2、对数组进行排序,按照年龄进行升序排序
	bubbleSort(arr, len);

//3、将排序后的结果打印输出
	cout << "排序后数组信息:" << endl;
	printHero(arr, len);


	system("pause");
	return 0;
}

运行结果图:

在这里插入图片描述


  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 15:54:00  更:2021-08-06 15:54:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 0:40:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码