C++学习笔记(6.7 ——6.11)——c++基础入门

目录

c++基础入门

一、C++初识

1、第一个c++程序

2、变量

3、常量

4、关键字(标识符)

5、标识符命名规则

二、数据类型

1.整型

2.sizeof关键字

3.实型(浮点型)

4.字符型  

5.转义字符

6.字符串型

7.布尔类型

8.数据的输入

三、运算符

1.算术运算符

2.赋值运算符(=、+=、-=、*=、/=、%=)

3.比较运算符(==、!=、<、>、<=、>=)

4.逻辑运算符(!、&&、||)

4、程序流程结构(顺序结构、选择结构、循环结构)

4.1选择结构

4.1.1if语句

 4.1.2三目运算符

 4.1.3switch语句

 4.2循环结构

4.2.1while循环语句

 4.2.2 do while循环语句

4.2.3for循环语句

 4.2.4嵌套循环

​ 4.3跳转语句

4.3.1break语句

4.3.2continue语句

4.3.3goto语句

5.数组

5.1一维数组

5.1.1一维数组定义方式

5.1.2一维数组的数组名

 5.1.3一维数组案例(五只小猪称体重、数组元素逆置)

5.1.4冒泡排序

 5.2二维数组

5.2.1二维数组定义方式

5.2.2二维数组数组名

5.2.3二维数组应用举例

6.函数

6.1函数的定义

6.2函数的调用

6.3值传递

6.4函数的常见样式

6.5函数的声明

6.6函数的分文件编写

7.指针

7.1指针的基本概念

7.2 指针变量的定义和使用

7.3指针所占内存空间

7.4空指针和野指针

7.5const修饰指针

7.6指针和数组

7.7指针和函数

 7.8指针、数组、函数

8.结构体

8.1结构体基本概念

8.2结构体定义和使用

 8.3结构体数组

8.4结构体指针

8.5结构体嵌套结构体

8.6结构体做函数参数

8.7结构体中const使用场景

8.8结构体案例

8.8.1案例1

8.8.2案例2


c++基础入门

一、C++初识

1、第一个c++程序

#include <iostream>
using namespace std;

int main()
{
	cout << "hello world" << endl;
	system("pause");
	return 0;
}

2、变量

3、常量

c++定义常量的两种方式

(1)#define 宏常量 #define 常量名 常量值     通常在文件上方定义,表示一个常量

(2)const 修饰的变量  const 数据类型 常量名 常量值

#include <iostream>
using namespace std;

#define day 365

int main()
{
	const int month = 12;
	cout << "一年总共有:"<<month<<"月,也就是"<<day<<"天" << endl;
	system("pause");
	return 0;
}

4、关键字(标识符)

在定义变量或者常量的时候不要用关键字

5、标识符命名规则

1.标识符不能是关键字

2.标识符只能由字母、数字、下划线组成

3.第一个字符必须为下划线

4.标志符中字母区分大小写

二、数据类型

1.整型

2.sizeof关键字

3.实型(浮点型)

(1)单精度 float            4字节           7位有效数字      float f1 = 3.14f;

(2)双精度 double          8字节       15-16位有效数字        double f1 = 3.14;

(3)科学计数法     float f = 3e2;//3*10^2         float f = 3e-2;  //3*0.1^2      

4.字符型  

char ch = 'a';       1字节

5.转义字符

#include <iostream>
using namespace std;
//
//#define day 365

int main()
{
	
	//换行符\n
	cout << "hello world\n";
	//反斜杠  \\
	
	cout << "\\" << endl;

	//水平制表符/t   前面内容+/t带来的空格总共占8个位置,作用:可以整齐输出数据
	cout << "aaa\thello world" << endl;
	cout << "aaaaa\thello world" << endl;
	cout << "a\thello world" << endl;
	cout << "aaaa\thello world" << endl;
	system("pause");
	return 0;
}

6.字符串型

两种风格:

1.c风格字符串  char 变量名[]  = "字符串值"

2.c++风格字符串   string 变量名 = “字符串值”

#include <iostream>
using namespace std;

int main()
{
	
	char str1[] = "hello world";
	cout << str1 << endl;

	string str2 = "hello world";
	cout << str2 << endl;
	system("pause");
	return 0;
}

7.布尔类型

只有两个值: true(真)——1  false(假)——0  1字节

8.数据的输入

cin   cin>>变量

#include <iostream>
using namespace std;

int main()
{
	//1.整型
	int a = 0;
	cout << "请给整型变量a赋值:" << endl;
	cin >> a;
	cout << "整型变量a = " << a << endl;

	//2.浮点型
	float f = 3.14f;
	cout << "请给浮点型变量f赋值:" << endl;
	cin >> f;
	cout << "浮点型变量f = " << f << endl;

	//3.字符型
	char ch = 'a';
	cout << "请给字符型变量ch赋值:" << endl;
	cin >> ch;
	cout << "字符型变量ch = " << ch<< endl;

	//4.字符串型
	string str= "abcd";
	cout << "请给字符串型变量str赋值:" << endl;
	cin >> str;
	cout << "字符型串变量str = " << str<< endl;

	//5.布尔类型
	bool flag = true;
	cout << "请给布尔型变量flag赋值:" << endl;
	cin >> flag;
	cout << "布尔型变量flag = " << flag << endl;

	system("pause");
	return 0;
}

三、运算符

1.算术运算符

+、-、*、/、%(只有两个整型变量可以做取模运算)、前置递增递减、后置递增递减、前置和后置区别

#include <iostream>
using namespace std;

int main()
{
	//1.前置递增
	int a = 10;
	++a;
	cout << "a = " << a << endl;

	//2.后置递增
	int b = 10;
	b++;
	cout << "b = " << b << endl;

	//2.前置和后置的区别
	//前置递增 先让变量+1,然后进行表达式的运算
	int  a2 = 10;
	int b2 = ++a2 * 10;
	cout << "a2 = " << a2 << endl;
	cout << "b2 = " << b2 << endl;

	//后置递增 先进行表达式的运算,后让变量+1
	int  a3 = 10;
	int b3 = a3++ * 10;
	cout << "a3 = " << a3 << endl;
	cout << "b3= " << b3 << endl;

	system("pause");
	return 0;
}

2.赋值运算符(=、+=、-=、*=、/=、%=)

3.比较运算符(==、!=、<、>、<=、>=)

4.逻辑运算符(!、&&、||)

4、程序流程结构(顺序结构、选择结构、循环结构)

4.1选择结构

4.1.1if语句

1.if语句  单行格式、多行格式、多条件的if语句、嵌套if语句

2.选择结构案例:三只小猪称体重

#include <iostream>
using namespace std;

int main()
{
	//三只小猪称体重,判断谁最重

	//1.创建三只小猪体重变量
	int num1 = 0;
	int num2 = 0;
	int num3 = 0;

	//2.让用户输入三只小猪的重量
	cout << "请输入小猪A的体重:" << endl;
	cin >> num1;

	cout << "请输入小猪B的体重:" << endl;
	cin >> num2;

	cout << "请输入小猪C的体重:" << endl;
	cin >> num3;

	cout << "小猪A的体重为:" << num1 << endl;
	cout << "小猪B的体重为:" << num2 << endl;
	cout << "小猪C的体重为:" << num3 << endl;

	//3.判断那只最重
	//先判断A和B的重量
	if (num1 > num2)           //A比B重
	{
		if (num1 > num3)   //A比C重
		{
			cout << "小猪A最重" << endl;
		}
		else              //C比A重
		{
			cout << "小猪C最重" << endl;
		}
	}
	else                   //B比A重
	{
		if (num2 > num3)
		{
			cout << "小猪B最重" << endl;
		}
		else
		{
			cout << "小猪C最重" << endl;
		}
	}
	system("pause");
	return 0;
}

 4.1.2三目运算符

1.语法:表达式1?表达式2:表达式3

2.三目运算结果可以作为右值赋值给变量;也可以作为变量,继续被赋值

 4.1.3switch语句

优点:结构清晰,执行效率高

缺点:判断时只能是整形或字符型,不可以是一个区间

#include <iostream>
using namespace std;

int main()
{
	//switch语句
	//给电影打分
	//10-9  经典
	//9-8   非常好
	//6-5   一般
	//5以下 烂片

	//1.提示用户给电影评分
	cout << "请给电影打分:" << endl;

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

	//3.根据用户的分数提示用户最后的结果
	switch (score)
	{
	case 10:
		cout << "您认为该电影是经典电影!" << endl;
		break;
	case 9:
		cout << "您认为该电影是经典电影!" << endl;
		break;
	case 8:
		cout << "您认为该电影非常好!" << endl;
		break;
	case 7:
		cout << "您认为该电影非常好!" << endl;
		break;
	case 6:
		cout << "您认为该电影是一般电影!" << endl;
		break;
	case 5:
		cout << "您认为该电影是一般电影!" << endl;
		break;
	default:
		cout << "您认为该电影是烂片!" << endl;
		break;
	}
	system("pause");
	return 0;
}

 4.2循环结构

4.2.1while循环语句

案例练习:猜数字

// 添加随机数种子,作用利用当前的系统时间生成随机数,防止每次随机数都一样
    srand((unsigned int)time(NULL));

    //1.系统生成随机数
    int num = rand() % 100+1;  //rand() % 100+1,生成一个0+1-99+1的随机数

#include <iostream>
using namespace std;

int main()
{
	// 添加随机数种子,作用利用当前的系统时间生成随机数,防止每次随机数都一样
	srand((unsigned int)time(NULL));

	//1.系统生成随机数
	int num = rand() % 100+1;  //rand() % 100+1,生成一个0+1-99+1的随机数
	/*cout << num << endl;*/

	//2.玩家进行猜测
	int val = 0;   //玩家输入的数据
	while (1)
	{
		cin >> val;

		//3.判断玩家的猜测

		//猜错 提示猜的结果过大或者过小,重新返回第二步
		if (val > num)
		{
			cout << "猜测过大!" << endl;
		}
		else if (val < num)
		{
			cout << "猜测过小!" << endl;
		}
		else  //猜对,退出游戏
		{
			cout << "猜对了!" << endl;
			break;
		}
	}
	
	system("pause");
	return 0;
}

 4.2.2 do while循环语句

练习案例:水仙花数

#include <iostream>
using namespace std;

int main()
{
	//1.先打印所有的三位数字
	int num = 100;
	do
	{
		//2.从所有的三位数中找到水仙花数
		int a = 0;
		int b = 0;
		int c = 0;

		a = num % 10; //获取num的个位
		b = num / 10 % 10; //获取数字的十位
		c = num / 100; //获取数字的百位

		if (a*a*a + b*b*b + c*c*c  == num)     //如果是水仙花数,打印
		{
			cout << num << endl;
		}
		num++;
	} while (num < 1000);
	

	system("pause");
	return 0;
}

4.2.3for循环语句

案例:敲桌子

#include <iostream>
using namespace std;

int main()
{
	//敲桌子
	//1.先输出1-100数字
	for (int i = 1; i <= 100; i++)
	{
		//2.从100个数字中找到特殊数字,打印“敲桌子”
		//如果是7的倍数、个位有7或者十位有7,打印敲桌子
		if (i%7 == 0 || i%10 == 7 ||i /10 == 7)
		{
			cout << "敲桌子" << endl;
		}
		else
		{
			cout << i << endl;
		}
	}
	
	system("pause");
	return 0;
}

 4.2.4嵌套循环

案例:乘法口诀表

#include <iostream>
using namespace std;

int main()
{
	//乘法口诀表
	for (int i = 1; i <= 9; i++)
	{
		for (int j = 1; j <= 9; j++)
		{
			cout << j << "*" << i << "=" << j * i<<"  ";
		}
		cout << endl;
	}
	
	system("pause");
	return 0;
}

4.3跳转语句

4.3.1break语句

break使用的时机:

1.出现在switch条件语句中,作用是终止case并跳出switch

2.出现在循环语句中,作用是跳出当前的循环语句

3.出现在嵌套循环中,跳出最近的内层循环语句

#include <iostream>
using namespace std;

int main()
{
	//break的使用时机
	//1.出现在switch语句中
	/*cout << "请选择副本的难度:" << endl;
	cout << "1.普通" << endl;
	cout <<"2.中等"<<endl;
	cout <<"3.困难" << endl;

	int select = 0;
	cin >> select;

	switch (select)
	{
	case 1:
		cout << "您选择的是普通难度" << endl;
		break;
	case 2:
		cout << "您选择的是中等难度" << endl;
		break;
	case 3:
		cout << "您选择的是困难难度" << endl;
		break;
	default:
		break;
	}*/

	//2.出现在循环语句中
	//for (int i = 0; i < 10; i++)
	//{
	//	//如果i= =5,退出循环,不再打印
	//	if (i == 5)
	//	{
	//		break;
	//	}
	//	cout << i << endl;
	//}
	//3.出现在嵌套循环语句中
	for (int i = 0; i < 10; i++)
	{
		for (int j = 0; j < 10; j++)
		{
			if (j == 5)
			{
				break;
			}
			cout << "*"  ;
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

4.3.2continue语句

在循环语句中,跳过本次循环中尚未执行的语句,继续执行下一次循环

4.3.3goto语句

语法:goto标记;

#include <iostream>
using namespace std;

int main()
{
//goto语句
	cout << "1.XXXXXXXXX" << endl;
	cout << "2.XXXXXXXXX" << endl;
	cout << "3.XXXXXXXXX" << endl;

	goto FLAG;
	cout << "4.XXXXXXXXX" << endl;
	cout << "5.XXXXXXXXX" << endl;

	FLAG:
	cout << "6.XXXXXXXXX" << endl;
	
	system("pause");
	return 0;
}

5.数组

5.1一维数组

5.1.1一维数组定义方式

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

1.数组类型  数组名[数组长度];

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

3.数组类型 数组名[ ] = {值1,值2,值3......}

5.1.2一维数组的数组名

一维数组名称的用途:

1.可以统计整个数组在内存中的长度,单位为字节

2.可以获取数组在内存中的首地址

#include <iostream>
using namespace std;

int main()
{
	//一维数组名称用途

	//1.可以统计整个数组在内存中的长度  sizeof(数组名称)
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	cout << "整个数组占用的内存空间为:" << sizeof(arr) << endl;
	cout << "每个元素所占的空间为:" << sizeof(arr[0]) << endl;
	cout << "数组中元素的个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;

	//2.可以获取数组在内存中的首地址    
	cout << "数组的首地址为:" << arr << endl;
	cout << "数组中第一个元素的地址为:" << &arr[0] << endl;

	//数组名是常量,因此不可以赋值
	system("pause");
	return 0;
}

 5.1.3一维数组案例(五只小猪称体重、数组元素逆置)

1.五只小猪称体重

#include <iostream>
using namespace std;

int main()
{
	//1.创建五只小猪体重的数组
	int arr[5] = { 300,350,200,400,250 };

	//2.从数组中找到最大值
	int max = 0;//先认定一个最大值为0
	for (int i = 0; i < 5; i++)
	{
		if (arr[i] > max)
			max = arr[i];
	}

	//3.打印最大值
	cout << "最重的小猪体重为:" << max << endl;


	system("pause");
	return 0;
}

2.数组元素逆置

#include <iostream>
using namespace std;

int main()
{
	//实现数组元素的逆置
	
	//1.创建数组
	int arr[5] = { 1,3,2,5,4 };
	cout<< "数组逆置前:" << endl;
	for (int i = 0; i < 5; i++)
	{
		cout << arr[i] << endl;
	}

	//2.实现逆置
	//2.1记录起始下标位置
	//2.2记录结束下标位置
	//2.3起始下标与结束下标的元素互换
	//2.4起始位置++ 结束位置--
	//2.5循环执行2.1的操作,直到起始位置>=结束位置
	int start = 0;        //起始下标
	int end = sizeof(arr) / sizeof(arr[0])-1;        //结束下标

	while (start < end)
	{
		//元素互换
		int 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] << endl;
	}

	system("pause");
	return 0;
}

5.1.4冒泡排序

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个;

2.对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值;

3.重复以上步骤,每次比较次数-1,直到不需要比较;

示例:将数组{4,2,8,0,5,7,1,3,9}进行升序排序

#include <iostream>
using namespace std;

int main()
{
	//利用冒泡排序实现升序排列
	int arr[9] = { 4,2,8,0,5,7,1,3,9 };

	cout << "排序前:" << endl;
	for (int i = 0; i < 9; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	//开始冒泡排序
	//总共排序轮数 = 元素个数-1
	for (int i = 0; i < 9 - 1; i++)
	{
		//内层循环对比 次数 = 元素个数-当前轮数-1
		for (int j = 0; j < 9 - i - 1; j++)
		{
			//如果第一个数字比第二个数字大,交换两个数字
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}

	//排序后结果
	cout << "排序后:" << endl;
	for (int i = 0; i < 9; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	system("pause");
	return 0;
}

 

 5.2二维数组

5.2.1二维数组定义方式

二维数组定义有4种方式:

1.数据类型 数组名[行数][列数];

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

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

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

#include <iostream>
using namespace std;

int main()
{
	//二维数组定义方式

	//1.数据类型 数组名[行数][列数];
	int arr[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;
	}
	//2.数据类型 数组名[行数][列数] = { {数据1,数据2},{数据3,数据4} };
	int arr1[2][3] = { {1,2,3} ,{4,5,6} };
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cout << arr1[i][j] << " ";
		}
		cout << endl;
	}
	//3.数据类型 数组名[行数][列数] = { 数据1,数据2,数据3,数据4 };
	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;
	}
	//4.数据类型 数组名[][列数] = { 数据1,数据2,数据3,数据4 };
	int arr3[][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;
	}
	system("pause");
	return 0;
}

5.2.2二维数组数组名

查看二维数组所占内存空间

获取二维数组首地址

5.2.3二维数组应用举例

#include <iostream>
using namespace std;

int main()
{
	//二维数组案例—考试成绩统计
	//1.创建二维数组
	int scores[3][3] =
	{ {100,100,100},
		{90,50,100},
		{60,70,80}
	};
	string names[3] = { "张三","李四","王五" };

	//2.统计每个人分数总和
	for (int i = 0; i < 3; i++)
	{
		int sum = 0;
		for (int j = 0; j < 3; j++)
		{
			sum += scores[i][j];
		}
		cout << names[i]<< "的总分为:" << sum << endl;
	}

	system("pause");
	return 0;
}

6.函数

6.1函数的定义

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

1.返回值类型

2.函数名

3.参数列表

4.函数体语句

5.return表达式

语法:

返回值类型 函数名(参数列表)

{

函数体语句;

return 表达式;

}

6.2函数的调用

6.3值传递

所谓值传递,就是函数调用时实参将数值传入给形参

值传递时,如果形参发生改变,并不会影响实参

#include <iostream>
using namespace std;

//值传递
	//定义一个函数,实现两个数字进行交换
	//如果函数不需要返回值,声明的时候可以写void
void swap(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;
	return;   //返回值不需要的时候,可以不写return
}
int main()
{
	
	int a = 10;
	int b = 20;
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	//值传递时,如果形参发生改变,并不会影响实参
	swap(a, b);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	system("pause");
	return 0;
}

6.4函数的常见样式

常见的函数样式有四种:1.有参无返 2.无参无返 3.无参有返 4.有参有返

#include <iostream>
using namespace std;

//函数常见样式
//1.无参无返
void test01()
{
	cout << "this is test01" << endl;
}
//2.有参无返
void test02(int a)
{
	cout << "this is test 02 a = " << a << endl;
	return;
}
//3.无参有返
int test03()
{
	cout << "this is test 03" << endl;
	return 1000;
}
//4.有参有返
int test04(int a)
{
	cout << "this is test04 a = " << a << endl;
	return a;
}
	
int main()
{
	//无参无返函数调用
	test01();
	//有参无返函数调用
	test02(10);
	//无参有返函数调用
	int num1 = test03();
	cout << "num1 = " << num1 << endl;
	//有参有返函数调用
	int num2 = test04(10000);
	cout << "num2 = " << num2 << endl;
	system("pause");
	return 0;
}

6.5函数的声明

#include <iostream>
using namespace std;

//函数声明
//比较函数,两个整型数字进行比较,返回较大的值

//函数的声明。提前告诉函数的存在。
int max(int a, int b);
int main(void)
{
	int a = 10;
	int b = 20;
	int result = max(a, b);
	cout << "最大值是:" << result << endl;
	system("pause");
	return 0;
}
int max(int a, int b)
{
	return a > b ? a : b;
}

6.6函数的分文件编写

四个步骤:

1.创建后缀名为.h的头文件

2.创建后缀名为.cpp的源文件

3.在头文件中写函数的声明

4.在源文件中写函数的定义

7.指针

7.1指针的基本概念

指针的作用:可以通过指针间接访问内存

可以利用指针变量记录保存地址

7.2 指针变量的定义和使用

语法:数据类型 *数据名;

#include<iostream>
using namespace std;

int main(void)
{
	//1.定义指针
	int a = 10;
	//指针定义语法 数据类型 *指针变量名;
	int* p;
	//让指针记录变量a的地址
	p = &a;
	cout << "a的地址为:" << p << endl;

	//2.使用指针
	//可以使用通过解引用的方式找到指针指向的内存
	//指针前加*代表解应用,找到指针指向的内存中的数据
	*p = 1000;
	cout << "a = " << a << endl;
	cout << "*p = " << *p << endl;

	system("pause");
	return 0;
}

7.3指针所占内存空间

32位操作系统下,占用4个字节空间,64位下占8个字节空间。不管是什么数据类型。

7.4空指针和野指针

空指针:指针变量指向内存中编号为0的空间。

用途:初始化指针变量

注意:空指针指向的内存是不可以访问的

#include<iostream>
using namespace std;

int main(void)
{
	//空指针
	//1.空指针用于给指针变量进行初始化
	int* p = NULL;
	//2.空指针是不可以进行访问的
	//0~255之间的内存编号是系统占用的,因此不可以访问

	cout << *p << endl;
	
	system("pause");
	return 0;
}
程序崩溃

野指针:指针变量指向非法的内存空间 ,在程序中,应该避免出现野指针。

#include<iostream>
using namespace std;

int main(void)
{
	//野指针
	
	int* p = (int *)0x1100;

	cout << *p << endl;

	system("pause");
	return 0;
}
程序崩溃

总结:空指针和野指针都不是我们申请的空间,因此不要访问。

7.5const修饰指针

const修饰指针有三种情况:

1.const修饰指针——常量指针

特点:指针的指向可以修改,但是指针指向的值不可以改。

const int *p = &a;

*p = 20;  错误,指针指向的值不可以改

p  =  &b;正确,指针指向可以改

2.const修饰常量——指针常量

特点:指针的指向不可以修改,但是指针指向的值可以改。

int *const p = &a;

*p = 20;  正确,指针指向的值可以改

p  =  &b;错误,指针指向不可以改

3.const既修饰指针又修饰常量

特点:指针的指向和指针指向的值都不可以改。

const int* const p = &a;

*p = 20;  错误,指针指向的值不可以改

p  =  &b;错误,指针指向不可以改

#include<iostream>
using namespace std;

int main(void)
{
	//1.const修饰指针  常量指针
	int a = 10;
	int b = 10;

	const int* p = &a;
	//指针指向的值不可以改,指针的指向可以改
	//*p = 20;
	p = &b;

	//2.const修饰常量 指针常量
	//指针的指向不可以改,指针指向的值可以改
	int* const p2 = &a;
	*p2 = 100;//正确的
	//p2 = &b;错误,指针的指向不可以改

	//3.const修饰指针和常量
	const int* const p3 = &a;
	//指针的指向和指针指向的值都不可以改
	//*p3 = 100;
	//p = &b;
}

技巧:看const右侧紧跟的是指针还是常量,是指针就是常量指针,是常量就是指针常量。

看完书后补充:

  1. 对于int age = 39;const int *pt = &age;(常量指针)pt的声明并不意味着它指向的值实际上就是一个常量,而只意味着对于pt而言,这个值是常量。例如, *pt = 20;  //❌但age=20;//✔因为age不是const变量。

7.6指针和数组

作用:利用指针访问数组中元素。

#include<iostream>
using namespace std;

int main(void)
{
	//指针和数组
	//利用指针访问数组中的元素
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	
	int* p = arr;//arr就是数组的首地址
	cout << "利用指针访问第一个元素:" << *p << endl;
	p++;//p++然指针向后偏移4个字节
	cout << "利用指针访问第二个元素:" << *p << endl;

	cout << "利用指针遍历数组:"<<endl;
	int* p2 = arr;
	for (int i = 0; i < 10; i++)
	{
		cout << *p2 << endl;
		p2++;
	}
	system("pause");
	return 0;
}

7.7指针和函数

作用:利用指针作为函数参数,可以修改实参的值

#include<iostream>
using namespace std;

//实现两个数字进行交换
void swap01(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
	cout << "swap01 a = " << a << endl;
	cout << "swap01 b = " << b << endl;
}

void swap02(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
	cout << "swap02 a = " << *p1 << endl;
	cout << "swap02 b = " << *p2 << endl;
}
int main(void)
{
	//指针和函数
	//1.值传递
	int a = 10;
	int b = 20;
	swap01(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	//2.地址传递
	//如果是地址传递,可以修改实参
	swap02(&a, &b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	system("pause");
	return 0;
}

 7.8指针、数组、函数

案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序。

例如,数组int arr[10] = {4,3,6,9,1,2,10,8,7,5}

#include<iostream>
using namespace std;

//冒泡排序函数  参数1 数组的首地址  参数2 数组的长度
void bubbleSort(int* arr,int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			//如果j > j+1,交换两个值
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
	return;
}

//打印数组
void printArray(int *arr,int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
}
int main(void)
{
	//1.创建一个数组
	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
	int len = sizeof(arr) / sizeof(arr[0]);

	//2.创建一个函数实现冒泡排序
	bubbleSort(arr, len);

	//3.打印排序后的数组
	printArray(arr, len);
	system("pause");
	return 0;
}

8.结构体

8.1结构体基本概念

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

8.2结构体定义和使用

语法:struct  结构体名 {结构体成员列表};

(struct关键字创建的时候可以省略,定义的时候不可以省略)

通过结构体创建变量的方式有三种:

1.struct 结构体名 变量名;

2.struct 结构体名 变量名 = {成员1值,成员2值......};

3.定义结构体时,顺便创建变量;

#include<iostream>
using namespace std;

//1.创建一个学生的数据类型:学生包括(姓名,年龄,分数)
	//自定义数据类型,一些类型集合组成的的一个类型
	//语法 struct 类型名称{成员列表};
struct student      //struct不可以省略
{
	//成员列表
	//姓名
	string name;
	//年龄
	int age;
	//分数
	int score;
}s3;

int main(void)
{
	
	//2.通过学生类型创建具体学生
	//2.1 struct student s1;
	struct student s1;            //struct可以省略
	//给s1 属性赋值,通过.访问结构体变量中的属性
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;

	cout << "姓名:   " << s1.name << endl;
	cout << "年龄:   " << s1.age<< endl;
	cout << "分数:   " << s1.score << endl;
	//2.2 struct student s2 = {...};
	struct student s2 = { "李四",19,82 };
	cout << "姓名:   " << s2.name << endl;
	cout << "年龄:   " << s2.age << endl;
	cout << "分数:   " << s2.score << endl;

	//2.3 在定义结构体时,顺便创建结构体变量
	struct student s3 = { "王五",20,60 };
	cout << "姓名:   " << s3.name << endl;
	cout << "年龄:   " << s3.age << endl;
	cout << "分数:   " << s3.score << endl;


	system("pause");
	return 0;
}

 8.3结构体数组

作用:将自定义的结构体放入到数组中方便维护

语法:struct 结构体名  数组名 元素个数{{},{},{}....{}};

#include<iostream>
using namespace std;

// 结构体数组
//1.定义一个结构体
struct student
{
	string name;
	int age;
	int score;

};



int main(void)
{
	//2.创建结构体数组并赋值
	struct student stuArray[3]
	{
		{"张三",18,100},
		{"李四",19,80},
		{"王五",20,60}
	};

	//3.给结构体数组中的元素赋值
	stuArray[2].name = "赵六";
	stuArray[2].age = 22;
	stuArray[2].score = 90;

	//4.遍历输出结构体数组
	for (int i = 0; i < 3; i++)
	{
		cout << "姓名   " << stuArray[i].name << "      年龄   " << stuArray[i].age << "      分数   " << stuArray[i].score << endl;
	}
	system("pause");
	return 0;
}

8.4结构体指针

作用:通过指针访问结构体中的成员

利用操作符->可以通过结构体指针访问结构体属性

#include<iostream>
using namespace std;

// 结构体指针
//1.定义一个结构体
struct student
{
	string name;
	int age;
	int score;
};



int main(void)
{
	//2.创建结构体变量
	struct student s ={"张三",18,100};

	//3.通过指针指向结构体变量
	struct student* p = &s;

	//4.通过指针访问结构体变量的数据
	cout << "姓名:   " << p->name << "      年龄:   " << p->age << "      分数:   " << p->score << endl;
	system("pause");
	return 0;
}

8.5结构体嵌套结构体

作用:结构体中的成员可以是另一个结构体

例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体

#include<iostream>
using namespace std;

// 结构体嵌套结构体

//定义学生结构体
struct student
{
	string name;
	int age;
	int score;
};
//定义老师结构体
struct teacher
{
	int id;              //教师编号
	string name;           //tercher name
	int age;             //teacher age
	struct student stu;   //student
};


int main(void)
{
	//创建一个老师
	teacher t;
	t.id = 10000;
	t.name = "老王";
	t.age = 50;
	t.stu = { "张三",19,100 };

	cout << "老师的姓名:" << t.id << "     老师编号:" << t.id << "     老师年龄:" << t.age<<endl
		<< "老师辅导的学生为:" << t.stu.name << "     学生的年龄为:" << t.stu.age <<
		"     学生的考试分数为:" << t.stu.score << endl;


	system("pause");
	return 0;
}

8.6结构体做函数参数

作用:将结构体作为参数向函数中传递

传递的方式有两种:

1.值传递

2.地址传递

#include<iostream>
using namespace std;

//定义结构体
struct student
{
	string name;
	int age;
	int score;
};

//打印学生信息的函数
//1.值传递
void printstudent1(struct student s)
{
	s.age = 100;
	cout<<"值传递子函数中:"<<endl <<"姓名:" << s.name << "     年龄:" << s.age << "     分数:" << s.age << endl;
}

//2.地址传递
void printstudent2(struct student *p)
{
	p->age = 100;
	cout << "地址传递子函数中:" << endl << "姓名:" << p->name << "     年龄:" << p->age << "     分数:" <<p->age << endl;
}

int main(void)
{
	//结构体做函数参数
	//将学生传入一个参数中,打印学生身上的所有属性
	
	//创建一个结构体变量
	struct student s = { "张三",20,90 };
	cout << "姓名:" << s.name << "     年龄:" << s.age << "     分数:" << s.age << endl;

	printstudent1(s);
	cout << "姓名:" << s.name << "     年龄:" << s.age << "     分数:" << s.age << endl;
	cout << "******************************************" << endl;
	printstudent2(&s);
	cout << "姓名:" << s.name << "     年龄:" << s.age << "     分数:" << s.age << endl;
	system("pause");
	return 0;
}

总结:如果不想修改主函数中的数据,用值传递。反之,用地址传递。

8.7结构体中const使用场景

作用:用const来防止误操作

#include<iostream>
using namespace std;

//const的使用场景

struct student
{
	string name;
	int age;
	int score;
};

//将函数的形参改为指针,可以减少内存空间,而且不会复制新的副本出来,一个指针只占4个字节
void printstudent(const student *s)
{
	s->age = 150;      //错误,因为加入const之后一旦有修改的操作就会报错,可以防止我们的误操作
	cout << "姓名:" << s->name << "     年龄:" << s->age << "     分数:" << s->score << endl;
}
int main(void)
{
	//创建结构体变量
	struct student s = { "张三",15,70};

	//通过函数来打印结构体变量的信息
	printstudent(s);

	system("pause");
	return 0;
}

8.8结构体案例

8.8.1案例1

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

#include<iostream>
#include <ctime>
using namespace std;

//学生的结构体
struct student
{
	string sname;
	int score;
};
//老师的结构体
struct Teacher
{
	//姓名
	string tName;
	//学生数组
	struct student sArray[5];
};
//给老师和学生赋值的函数
void allocateSpace(struct Teacher tArray[],int len)
{
	string nameSeed = "ABCDE";
	for (int i = 0; i < len; i++)
	{
		tArray[i].tName = "Teacher_";
		tArray[i].tName += nameSeed[i];

		//通过循环给每名老师所带的学生赋值
		for (int j = 0; j < 5; j++)
		{
			tArray[i].sArray[j].sname = "Student_";
			tArray[i].sArray[j].sname += nameSeed[j];

			int random = rand() % 61 + 40;   //0+40~60+40

			tArray[i].sArray[j].score = random;

		}
		
	}
}

//打印所有信息
void printInfo(struct Teacher tArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "老师姓名:" << tArray[i].tName << endl;
		for (int j = 0; j < 5; j++)
		{
			cout << "\t学生姓名:" << tArray[i].sArray[j].sname<< 
			"  考试分数:" << tArray[i].sArray[j].score << endl;
		}
	}
}
int main(void)
{
	//随机数种子
	srand((unsigned int)time(NULL));
	//1.创建3名老师的数组
	struct Teacher tArray[3];
	//2.通过函数给3名老师的信息赋值,并给老师带的学生的信息赋值
	int len = sizeof(tArray) / sizeof(tArray[0]);
	allocateSpace(tArray, len);
	//3.打印所有老师以及所带的学生的信息
	printInfo(tArray, len);

	system("pause");
	return 0;
}

8.8.2案例2

案例描述:设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排列,最终打印最后的结果。

五名英雄信息:{“刘备”,23,“男”}{“关羽”,22,“男”}{“张飞”,“20”,“男”}{“赵云”,21,“男”}{“貂蝉”,19,“女”}

#include<iostream>
#include <ctime>
using namespace std;
//1.设计一个英雄的结构体
struct Hero
{
	string name;
	int age;
	string sex;
};

//冒泡排序实现年龄的升序排列
void bubbleSort(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = 0; j < len - i - 1; j++)
		{
			//如果j下标元素年龄大于j+1的元素年龄,就交换这两个元素
			if (heroArray[j].age > heroArray[j + 1].age)
			{
				struct Hero temp = heroArray[j];
				heroArray[j] = heroArray[j + 1];
				heroArray[j+1] = temp;
			}
		}
	}
}

//打印排序后数组信息
void printHero(struct Hero heroArray[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << "姓名: " << heroArray[i].name << "   年龄:"
			<< heroArray[i].age << "   性别: " << heroArray[i].sex << endl;

	}
}
int main(void)
{
	//2.创建一个数组存放5名英雄
	struct Hero heroArray[5] =
	{
		{"刘备",23,"男" },
		{"关羽",22,"男"} ,
		{"张飞",20,"男"},
		{"赵云",21,"男"} ,
		{"貂蝉",19,"女"}
	};
	int len = sizeof(heroArray) / sizeof(heroArray[0]);
	for (int i = 0; i < len; i++)
	{
		cout << "姓名: " << heroArray[i].name << "   年龄:" 
			<< heroArray[i].age << "   性别: " << heroArray[i].sex << endl;

	}
	//3.对数组进行排序,按照年龄进行升序排列
	bubbleSort(heroArray, len);
	cout << "排序后的打印为:" << endl;
	//4.将排序后的结果打印输出
	printHero(heroArray, len);
	system("pause");
	return 0;
}

万能头文件:#include<bits/stdc++.h>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值