C++入门笔记(基础版)

此前文章已经整合到这一篇里了,请大家放心阅读

C++基础入门

思维导图:

1.C++初识

1.1 第一个C++程序

编写一个C++程序总共分为4个步骤

  • 创建项目
  • 创建文件
  • 编写代码
  • 运行程序
1.1.1 创建项目

Visual Studio 是我们编写C++程序的主要工具,我们先打开它

点击创建新项目,找到 Visual C++,选择空项目

1.1.2 创建文件

右键源文件,选择添加 -> 新建项

C++入门笔记(基础版)_第1张图片

1.1.3 编写代码
#include 
using namespace std;

int main()
{
    cout << "hello world" << endl;
    system("pause");  //可以选择不写,但是为了美观还是写一下
    return 0;
}

1.2 注释

作用:在代码中加一些说明和解释,方便自己或其他程序员阅读代码

两种格式

  1. 单行注释// 描述信息

    • 通常放在一行代码的上方,或者一条语句的末尾,对该代码说明
  2. 多行注释/* 描述信息 */

    通常放在一段代码的上方,对该代码段做整体说明

提示:编译器在编译代码时,会忽略注释的内容

#include 
using namespace std;

1.单行注释——//

2.多行注释——/* */
int main()
{

     cout << "hello world" << endl; //这是输出hello world的代码
     /*
       main函数是一个程序的路口
	   每个程序都必须有这么一个函数
	   有且仅有一个
     */
	system("pause");
	return 0;
}

1.3 变量

作用:给一段指定的内存空间起名,方便操作这段内容

语法数据类型 变量名 = 初始值;

存在意义:方便我们管理内存空间

示例

#include 
using namespace std;

int main()
{
   //变量创建的语法:数据类型 变量名 = 变量初始值
   int a = 10;

   cout << "a = " << a << endl; //输出结果为10

   system("pause");
   return 0;
}

1.4 常量

作用:用于记录程序中不可更改的数据

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

  1. #define 宏常量:#define 常量名 常量值
    • 通常在文件上方定义,表示一个常量
  2. const 修饰的变量:const 数据类型 变量名 = 常量值
    • 通常在变量定义前加关键字const,修饰该变量为常量,不可修改

示例

//1.#define 宏常量
#define Day 7

int main()
{
    cout << "一周里总共有" << Day << "天" << endl;
    Day = 8;  //报错,宏常量不可以修改
    
    //2.const 修饰的变量
    const int month = 12;
    cout << "一年里总共有 " << month << " 个月份" << endl;
    month = 24;  //报错,常量是不可以修改的
    
    system("pause");
    return 0;
}

1.5 关键字

作用:关键字C++中预先保留的单词(标识符)

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

C++关键字如下:

asm do if return typedef
auto double inline short typeid
bool dynamic_cast int signed typename
break else long sizeof union
case enum mutable static unsigned
catch explicit namespace static_cast using
char export new struct virtual
class extern operator switch void
const false private template volatile
const_cast float protected this wchar_t
continue for public throw while
default friend register true
delete goto reinterpret_cast try

提示:在给变量或者常量起名称的时候,不要用C++的关键字,否则会产生歧义

int main()
{
	//创建变量:数据类型 变量名称 = 变量初始值
	//不能用关键字给变量或者给常量取名
	//如 int int = 10; 是错误的,第二个int是一个关键字,不可以作为变量名称

	system("pause");
	return 0;
}

1.6 标识符命名规则

作用:C++规定给标识符(变量,常量)命名时,有一套自己的规则

  • 标识符不能是关键字
  • 标识符只能由字母,数字,下划线组成
  • 第一个字符必须为字母或者下划线
  • 标识符中的字母区分大小写

建议:给标识符命名时,争取做到见名知意的效果,方便自己和他人阅读

int main()
{
	//1.标识符不可以是关键字
	例如 int int 10;

	//2.标识符是由 字母 数字 下划线 构成
	int abc = 10;
	int _abc = 20;
	int _123abc = 30;
	

	//3.标识符第一个字符只能是字母或下划线,不能是数字
	int 123abc = 40; //报错

	//4.标识符区分大小写
	int aaa = 100;
	cout << "aaa的值 = " << aaa << endl;  //但是第二个aaa换成AAA就不可以了
    cout << "aaa的值 = " << AAA << endl;  //AAA和aaa不是同一个名称

	//建议:给变量取名的时候,最好能够做到见名知意
	int num1 = 10;
	int num2 = 20;
	int sum = num1 + num2;
	cout << "sum = " << sum << endl;

	system("pause");

	return 0;
}

2.数据类型

2.1 整型

作用:整型变量表示的是整数类型的数据

数据类型存在意义:给变量分配合适的内存空间

C++中能够表示整型的类型有以下几种方式,区别在于所占内存空间不同

数据类型 占用空间 取值范围
short(短整型) 2字节 (-2^15 ~ 2^15-1)
int(整型) 4字节 (-2^31 ~ 2^31-1)
long(长整形) Windows为4字节,Linux为4字节(32位),8字节(64位) (-2^31 ~ 2^31-1)
long long(长长整形) 8字节 (-2^63 ~ 2^63-1)
int main()
{
	整型(所占用的内存空间不同)
	//1.短整型(取值范围:-32768 ~ 32767)
	short num1 = 32768;  
    //输出的结果会变成-32768,因为 32768 超出短整型的取值范围,所以编译器重新检索取值范围,跳回到第一个数字

	//2.整型最常用
	int num2 = 10;

	//3.长整型
	long num3 = 10;

	//4.长长整型
	long long num4 = 10;

	cout << "num1 = " << num1 << endl;
	cout << "num2 = " << num2 << endl;
	cout << "num3 = " << num3 << endl;
	cout << "num4 = " << num4 << endl;

	system("pause");
	return 0;
}

2.2 sizeof 关键字

作用:利用sizeof 关键字可以统计数据类型所占内存的大小

语法sizeof(数据类型 / 变量)

示例

int main()
{
	//整型:short(2)  int(4)  long(4)   long long(8)
	//可以利用sizeof求出数据类型所占用的内存大小
	//语法:sizeof(数据类型/变量)
	short num1 = 10;
	cout << "short所占用的内存空间为;" << sizeof(short) << endl;  //结果为2

	int num2 = 10;
	cout << "int所占用的内存空间为;" << sizeof(int) << endl;  //结果为4
    cout << "int所占用的内存空间为:" << sizeof(num2) << endl;  //结果同样为4
    //sizeof的括号里既可以放数据类型,也可以放变量名
    
	//以此类推
	//整型大小比较:short < int <= long <= long long
	system("pause");
	return 0;
}

整型结论:short < int <= long <= long long

2.3 实型数据

作用:用于表示小数

浮点型变量分为两种:

  1. 单精度float
  2. 双精度double

两者的区别在于表示的有效数字范围不同

数据类型 占用空间 有效数字范围
float 4字节 7位有效数字
double 8字节 15~16位有效数字

示例

int main()
{
	//1.单精度  float
	//2.双精度  double
	//默认情况下 输出一个小数,会显示6位有效数字,小数点也是一个数字
	float f1 = 3.1415926f;   //这里的f表示的就是这个数据属于单精度float,如果没有f,那么系统默认的就是双精度
	cout << "f1 = " << f1 << endl;  //输出结果为:3.14159

	double d1 = 3.1415926;
	cout << "d1 = " << d1 << endl;  //输出结果为:3.14159

	//统计float和double所占用的内存空间
	float a = 1;
	cout << "float 所占用的内存空间为:" << sizeof(float) << endl; // 4字节

	double b = 1;
	cout << "double 所占用的内存空间为:" << sizeof(double) << endl; //8字节

	//科学计数法
	float f2 = 3e2;  //3 * 10 ^ 2  这个e就代表10的几次方
	cout << "f2 = " << f2 << endl;
    float f3 = 3e-2;  //3 * 0.1 ^ 2  这个e就代表0.1的几次方

	system("pause");
	return 0;
}

2.4 字符型

作用:字符型变量用于显示单个字符

语法char ch = 'a';

注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号

注意2:单引号内只能有一个字符,不可以时字符串

  • C和C++中的字符型变量只占用一个字节
  • 字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元

示例

int main()
{
	//1.字符型变量的创建方式
	char ch = 'a';
	cout << ch << endl;  //结果为a

	//2.字符型变量所占内存大小
	cout << "char字符型变量所占的内存空间为:" << sizeof(char) << endl;  //结果为1

	//3.字符型变量常见错误
	char ch2 = "b";   //错误,创建字符型变量的时候,要用单引号 ''
	char ch2 = 'abcdef';  //错误,创建字符型变量的时候,单引号内只能有一个字符

	//4.字符型变量所对应的ASCII编码
	//常见的ASCII编码
	//a——97 , A——65
	cout << (int)ch << endl;
    //在输出的字符前 + 括号 + 整型,使字符型变量强制转换成10进制的数字,以此查看此字符的ASCII编码


	system("pause");
	return 0;
}

ASCII码表格

ASCII 控制字符 ASCII 字符 ASCII 字符 ASCII 字符
0 NUT 32 (space) 64 @ 96
1 SOH 33 ! 65 A 97 a
2 STX 34 " 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 , 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DCI 49 1 81 Q 113 q
18 DC2 50 2 82 R 114 r
19 DC3 51 3 83 S 115 s
20 DC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 TB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [ 123 {
28 FS 60 < 92 / 124 |
29 GS 61 = 93 ] 125 }
30 RS 62 > 94 ^ 126 `
31 US 63 ? 95 _ 127 DEL

ASCII码大致由以下两部分组成:

  • ASCII非打印控制字符:ASCII表上的数字 0~31分配给了控制字符,用于控制像打印机等一些外围设备
  • ASCII打印字符:数字 32~126分配给了能在键盘上找到的字符,当查看或打印文档的时候就会出现

2.5 转义字符

作用:用于表示一些不能显示出来的ASCII字符

现阶段我们常用的转义字符有:\n \\ \t

转义字符 含义 ASCII码值(十进制)
\a 警报 007
\b 退格(BS) ,将当前位置移到前一列 008
\f 换页(FF),将当前位置移到下页开头 012
\n 换行(LF) ,将当前位置移到下一行开头 010
\r 回车(CR) ,将当前位置移到本行开头 013
\t 水平制表(HT) (跳到下一个TAB位置) 009
\v 垂直制表(VT) 011
\\ 代表一个反斜线字符"\" 092
\’ 代表一个单引号(撇号)字符 039
\" 代表一个双引号字符 034
? 代表一个问号 063
\0 数字0 000
\ddd 8进制转义字符,d范围0~7 3位8进制
\xhh 16进制转义字符,h范围09,af,A~F 3位16进制

示例

int main()
{
	转义字符
	//1.换行符  \n
	cout << "hello world\n";  //“\n”的效果和“endl”一样

	//2.反斜杠  \\
	
	cout << "\\" << endl;
    //想要输出一个反斜杠,就必须给编译器提示我需要输出一个特殊的符号,也即是引号中的第一个反斜杠
	//第二个反斜杠则代表我要输出的特殊符号

	//3. 水平制表符  \t
	cout << "aaa\tlook" << endl;
	cout << "aaaaaa\tlook" << endl;
	cout << "aaaa\tlook" << endl;
	cout << "aa\tlook" << endl;
    // \t占据8个位置,使得我们输出的结果整齐有序
	// \t相当于管理人员设置了8个空座位,在\t之前出现的字符都将出现在这8个空座位中

	system("pause");
	return 0;
}

制表符的输出结果:

2.6 字符串型

作用:用于表示一串字符

两种风格

  • C风格字符串char 变量名 [] = "字符串值"

示例:

int main()
{
	//字符串的使用,极大的方便简化输出,用一个变量代替多个字符,使检索更加容易
	1.C风格的字符串
	
	注意事项:
    1.变量名后面要加 "[]" 
	2.符号后面要用双引号 把你所要输出或代替的字符串包含起来
	// char 变量名[] = "字符串值"
	 
	char a[] = "hello world";
    cout << a << endl;

	system("pause");
	return 0;
}

注意:C风格的字符串要用双引号括起来

  • C++风格的字符串string 变量名 = "字符串值"

示例

int main()
{
    2.C++风格的字符串
	//对于早期版本的编译器来说,使用string需要在头文件添加 #include 
	string b = "hello world";
	cout << b << endl;
	
	system("pause");
	return 0;
}

注意:C++风格字符串,需要加入头文件==#include ==

2.7 布尔类型 bool

作用:布尔数据类型代表真或假的值

bool 类型只有两个值

  • ture ----- 真(本质是1)
  • false ----- 假(本质是0)

bool 类型占1个字节大小

示例:

int main()
{
	//布尔类型 bool类型的特点:
	//1.只有2个值  true——真(本质是1)/ false——假(本质是0)
	//2.只占1个字节的大小

	//1.创建bool数据类型
	bool a = true;  //代表此变量的值为真
	cout << a << endl;  //输出结果为1
	
    bool b = false;  //代表此变量的值为假
	cout << b << endl;  //输出的结果为0
    
    //本质上 1代表真 0代表假

	//2.查看bool类型所占的内存空间
	cout << "布尔类型所占的内存空间为:" << sizeof(bool) << endl;  //结果为1
	
	system("pause");
	return 0;
}

2.8 数据的输入

作用用于从键盘获取数据

关键字:cin

语法cin >> 变量

示例:

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

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

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

	//4.字符串型
	string a = "hello";
	cout << "a的初始值为:" << a << endl;
	cout << "请给字符串变量a赋值:" << endl;
	cin >> a;
	cout << "字符串型变量a = " << a << endl;

	//5.布尔类型
	bool a = false;
	cout << "a的初始值为:" << a << endl;
	cout << "请给布尔类型变量a赋值:" << endl;
	cin >> a;
	cout << "布尔类型变量a = " << a << endl;  //输出的结果为0
	//bool类型 只要是非0的值都代表真

	system("pause");
	return 0;
}

3.运算符

作用:用于执行代码的运算

本章我们主要讲解以下几类运算符

运算符类型 作用
算术运算符 用于处理四则运算
赋值运算符 用于将表达式的值赋给变量
比较运算符 用于表达式的比较,并返回一个真值或假值
逻辑运算符 用于根据表达式的值返回真值或假值

3.1 算术运算符

作用:用于处理四则运算

算术运算符包括以下符号

运算符 术语 示例 结果
+ 正号 +3 3
- 负号 -3 -3
+ 10 + 5 15
- 10 - 5 5
* 10 * 5 50
/ 10 / 5 2
% 取模(取余) 10 % 3 1
++ 前置递增 a=2; b=++a; a=3; b=3;
++ 后置递增 a=2; b=a++; a=3; b=2;
前置递减 a=2; b=–a; a=1; b=1;
后置递减 a=2; b=a–; a=1; b=2;

示例1:

int main()
{
	//加减乘除
	int a1 = 10;
	int b1 = 3;
	cout << a1 + b1 << endl;
	cout << a1 - b1 << endl;
	cout << a1 * b1 << endl;
	cout << a1 / b1 << endl;   //输出的结果为3
	//为什么?两个整数相除,结果依然是整数,将小数部分去除,不显示小数
	
    int a2 = 10;
	int b2 = 20;
	cout << a2 / b2 << endl;   //输出结果为0

	int a3 = 10;
	int b3 = 0;
	cout << a3 / b3 << endl;   //报错,两个数字相除,无法显示结果,除数不可为0

	//思考:两个小数可以相除吗?
	double d1 = 0.5;
	double d2 = 0.25;
	double d3 = 0.22;
	cout << d1 / d2 << endl;    //输出结果为2
	cout << d1 / d3 << endl;    //运算的结果也可以是小数


	system("pause");
	return 0;
}

总结:在除法运算中,除数不能为0

示例2

int main()
{
	//取模运算的本质,就是求余数
	int a2 = 10;
	int b2 = 3;
	cout << a2 % b2 << endl;  //结果为1

	int a1 = 10;
	int b1 = 20;
	cout << a1 % b1 << endl;  //结果为10

	int a3 = 10;
	int b3 = 0;
	//cout << a3 % b3 << endl;   //两个数相除,除数不可以为0,所以也做不了取模运算
	
	//两个小数之间是不可以做取模运算的
	double d1 = 3.14;
	double d2 = 1.1;
	//cout << d1 % d2 << endl;

	system("pause");
	return 0;
}

总结:只有整型变量才可以进行取模运算

示例3

int main()
{
	//1.前置递增
	int a = 10;
	++a;  //让变量+1
	cout << "a = "<< a << endl;  //11
    
	//2.后置递增
	int b = 10;
	b++;  //让变量+1
	cout << "b = " << b << endl;  //11
	
	//3.前置和后置的区别
	// 前置递增:先让变量+1 然后进行表达式的运算
	int a2 = 10;
	int b2 = ++a2 * 10;
	cout << "a2 = " << a2 << endl;  //11
	cout << "b2 = " << b2 << endl;  //110

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

	system("pause");
	return 0;
}

总结:前置递增先对变量进行++,再计算表达式,后置递增相反

3.2 赋值运算符

作用:用于表达的值赋值给变量

赋值运算符包括以下几个符号:

运算符 术语 示例 结果
= 赋值 a=2; b=3; a=2; b=3;
+= 加等于 a=0; a+=2; a=2;
-= 减等于 a=5; a-=3; a=2;
*= 乘等于 a=2; a*=2; a=4;
/= 除等于 a=4; a/=2; a=2;
%= 模等于 a=3; a%2; a=1;
int main()
{
	//赋值运算符

	// = 
	int a = 10;
	a = 100;     // 使a的值变为100;
	cout << "a = " << a << endl;  //a = 100

	// +=
	a = 10;
	a += 2;      // 该表达式的含义是:a = a + 2
	cout << "a = " << a << endl;  //a = 12
	
	// -=
	a = 10;
	a -= 2;      // 该表达式的含义是:a = a - 2
	cout << "a = " << a << endl;  //a = 8

	// *=
	a = 10;
	a *= 2;      // 该表达式的含义是:a = a * 2
	cout << "a = " << a << endl;  //a = 20

	// /=
	a = 10;
	a /= 2;      // 该表达式的含义是:a = a / 2
	cout << "a = " << a << endl;  //a = 5
	
	
	// %=
	a = 10;
	a %= 2;      // 该表达式的含义是:a = a % 2
	cout << "a = " << a << endl;  //a = 0

	system("pause");
	return 0;
}

3.3 比较运算符

作用:用于表达式的比较,并返回一个真值或假值

比较运算符有以下符号:

运算符 术语 示例 结果
== 相等于 4 == 3 0
!= 不等于 4 != 3 1
< 小于 4 < 3 0
> 大于 4 > 3 1
<= 小于等于 4 <= 3 0
>= 大于等于 4 >= 1 1
int main()
{
	//比较运算符
	// ==
	int a = 10;
	int b = 20;
	cout << (a == b) << endl;    //这里加一个小括号 使它做优先运算,结果为0(假)
	
	// !=
	cout << (a != b) << endl;	//1
	
	// >
	cout << (a > b) << endl;    //0
	
	// <
	cout << (a < b) << endl;    //1
	
	// >=
	cout << (a >= b) << endl;   //0
	
	// <=
	cout << (a <= b) << endl;   //1

	system("pause");
	return 0;
}

注意:C和C++ 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示

3.4 逻辑运算符

作用:用于根据表达式返回真值或假值

逻辑运算符有以下符号:

运算符 术语 示例 结果
! !a 如果a为假,则!a为真; 如果a为真,则!a为假。
&& a && b 如果a和b都为真,则结果为真,否则为假。
|| a || b 如果a和b有一个为真,则结果为真,二者都为假时,结果为假

示例一:逻辑非

int main()
{
	//逻辑运算符 —— 非 !
	int a = 10;
	cout << !a << endl; //输出的结果为0

	//在C++中,除了0 都为真
	cout << !!a << endl; //输出的结果为1

    //非真为假,非假为真
	system("pause");
	return 0;
}

总结:真变假,假变真

示例2

int main()
{
	//逻辑运算符——与 &&
	//只要记住一句话,同真为真,同假为假
	int a = 10;
	int b = 10;

	cout << (a && b) << endl;  //输出结果为1,加小括号的目的是使得做优先级运算

	a = 0;
	b = 10;

	cout << (a && b) << endl;  //输出结果为0

	a = 0;
	b = 0;

	cout << (a && b) << endl;  //输出的结果为0

	system("pause");

	return 0;
}

总结:逻辑与运算符总结:同真为真,其余为假

示例3

int main()
{
	//逻辑运算符——或 ||
	int a = 10;
	int b = 10;

	cout << (a || b) << endl; //输出的结果为1

	a = 0;
	b = 10;

	cout << (a || b) << endl; //输出的结果为1

	a = 0;
	b = 0;

	cout << (a || b) << endl; //输出的结果为0

	//逻辑或:同假为假,其余为真

	system("pause");
	return 0;
}

总结:逻辑或运算符总结:同假为假,其余为真

4.程序流程结构

C/C++ 支持最基本的三种程序运行结构:顺序结构,选择结构,循环结构

  • 顺序结构:程序按顺序执行,不发生跳转
  • 选择结构:依据条件是否满足,有选择的执行相应功能
  • 循环结构:依据条件是否满足,循环多次执行某段代码

4.1 选择结构

4.1.1 if 语句

作用:执行满足条件的语句

if语句的三种形式

  • 单行格式的 if 语句
  • 多行格式的 if 语句
  • 多条件格式的 if 语句

1.单行格式 if 语句:if(条件)(条件满足执行的语句)

C++入门笔记(基础版)_第2张图片

示例

int main()
{
	//if语句的三种形式
	
	//1.单行格式if语句
	//语法:if(条件){条件满足执行的语句}
	//场景:用户输入分数,如果分数大于600,视为考上一本大学,在屏幕上输出
	
    //步骤:1.用户输入分数
	int score = 0; //先创建一个变量用来保存一个分数
		cout << "请输入一个分数:" << endl;
		cin >> score;
	
    //2.打印用户输入的分数
		cout << "您输入的分数为:" << score << endl;

	//3.判断用户的分数是否大于600,如果大于,那么输出
	//注意事项,if条件后面不要加分号,添加分号就意味着此行代码与下面的所有代码都没有联系,进而影响程序执行	
		if (score > 600)
		{
			cout << "恭喜你考上了一本大学" << endl;
		}
	
    system("pause");
	return 0;
}

注意:if 条件表达式后面不要加分号

2.多行格式 if 语句:if(条件){条件满足执行的语句} else {条件不满足执行的语句}

C++入门笔记(基础版)_第3张图片

示例

int main()
{
	//2.多行格式if语句
	//语法:if(条件){条件满足执行的语句} else{条件不满足执行的语句};
	//选择结构 -- 多行if语句
	//场景:用户输入考试分数,如果分数大于600,视为考上一本大学,在屏幕上输出
	//如果没考上一本大学,则打印未考上一本大学

	//1.输入考试分数
	int score = 0;
	cout << "请输入一个考试分数:" << endl;
	cin >> score;

	//2.提示用户输入的分数
	cout << "您输入的分数为:" << score << endl;

	//3.判断 如果大于600,打印考上一本,否则打印未考上一本
	if (score > 600) //大于600分执行下面大括号的内容
	{
		cout << "恭喜你考上一本大学" << endl;
	}
	else  //不大于600分,执行else后大括号中的内容
	{
		cout << "很遗憾你没考上一本大学" << endl;
	}

	system("pause");

	return 0;
}

3.多条件的 if 语句:if(条件1){条件1满足执行的语句} else if(条件2){条件2满足执行的语句}... else {都不满足执行的语句}

C++入门笔记(基础版)_第4张图片

示例

int main()
{
	//多条件的if语句:if(条件1){条件1满足执行的语句}else if(条件2){条件2满足执行的语句}...else{都不满足执行的语句}
	//选择结构 多条件if语句
	//场景:
	//1.输入一个考试的分数,如果大于600分,视为考上一本大学,在屏幕输出
	//2.大于500分,视为考上了二本大学,在屏幕上输出
	//3.大于400分,视为考上了三本大学,在屏幕上输出
	//4.分数小于等于400分,视为未考上本科,屏幕上输出

	
	//1.用户输入分数
	int score = 0;
	cout << "请输入一个考试的分数:" << endl;
	cin >> score;

	//2.提示用户输入的分数
	cout << "您输入的考试分数为:" << score << endl;

	//3.判断
	//如果大于600分,考上一本大学
	//如果大于500分,考上二本大学
	//如果大于400分,考上三本大学
	//前三个条件都没有满足,未考上本科
	if (score > 600)		//第一个条件判断
	{
		cout << "恭喜你考上了一本大学" << endl;
	}
	else if (score > 500)	//第二个条件判断
	{
		cout << "恭喜您考上了二本大学" << endl;
	}
	else if (score > 400)	//第三个条件判断
	{
		cout << "恭喜您考上了三本大学" << endl;
	}
	
    else
	{
		cout << "很遗憾,您没有考上大学,而是考上了大专" << endl;
	}

	system("pause");
	return 0;
}

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

案例需求

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

示例

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) //b比c重
		{
			cout << "小猪b最重" << endl;
		}
		
        else //c比b重
		{
			cout << "小猪c最重" << endl;
		}
	}

	system("pause");

	return 0;
}

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

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

C++入门笔记(基础版)_第5张图片

示例

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) //b比c重
		{
			cout << "小猪b最重" << endl;
		}
		
        else //c比b重
		{
			cout << "小猪c最重" << endl;
		}
	}

	system("pause");

	return 0;
}
4.1.2 三目运算符

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

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

解释

如果表达式1的值为执行表达式2,并返回表达式2的结果

如果表达式1的值为执行表达式3,并返回表达式3的结果

示例

int main()
{
	//三目运算符 a b c
	//将a和b作比较,将变量大的赋值给变量c
	int a = 10;
	int b = 20;
	int c = 0;

	c = (a > b ? a : b); //意思是a如果大于b,则把a的值赋值给c
	                     //否则就把b的值赋值给c

	cout << "c = " << c <<endl;  //20

	//在c++中三目运算符返回的是变量,可以继续赋值
	(a > b ? a : b) = 100; //意思是a如果大于b,则把100赋值给a
	                       //否则就把100赋值给b
	
    cout << "a = " << a << endl;  //10
	cout << "b = " << b << endl;  //100

	
    (a < b ? a : b) = 40;  //意思是a如果小于b,则把40赋值给a
	                       //否则就把40赋值给b
	
    cout << "a = " << a << endl;  //40
	cout << "b = " << b << endl;  //100

	system("pause");
	return 0;
}
4.1.3 switch语句

作用:执行多条件分支语句

语法

switch(表达式)

{
	case 结果1:执行语句;break;

	case 结果2:执行语句;break;

	...

	default:执行语句;break;
}

示例

int main()
{
	//switch语句执行逻辑:
	//根据switch括号后的表达式,选择要进行的条件分支
	
	//场景:给电影进行打分
	//10~9分:经典
	//8~7分:非常好
	//6~5分:一般
	//5分一下:烂片

	//步骤:
	//1.提示用户给电影打分
	cout << "请给电影进行打分:" << endl;

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

	//3.根据用户输入的分数来提示用户最后的结果
	switch (score)  //括号里填的就是 依据 表达式 来 选择 不同的分支
	{
	case 10:
	case 9:
		cout << "您认为这是经典电影" << endl; break;  //退出当前分支
	case 8:
	case 7:
		cout << "您认为这是非常好电影" << endl; break;
	case 6:
	case 5:
		cout << "您认为这是一般电影" << endl; break;
	
    default:
		cout << "您认为这是烂片" << endl; break;
	}

	system("pause");
	return 0;
}

if和switch的区别?
switch 缺点,判断的时候只能是整型或者是字符型,不可以是一个区间
switch 优点,结构清晰,执行效率高

注意1:switch语句中表达式类型只能是整型或者是字符型

注意2:case里如果没有break,那么程序会一直向下执行

总结:与 if 语句比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间

4.2 循环结构

4.2.1 while 循环语句

作用:满足循环条件,执行循环语句

语法while(循环条件){循环语句}

解释只要循环条件的结果为真,就执行循环语句

C++入门笔记(基础版)_第6张图片

示例

int main()
{
	//while循环
	//注意事项:在写循环的时候一定要避免死循环

	//在屏幕中打印0~9这10个数字
	//首先,先创建一个变量0
	int num = 0;

	while (num < 10) //括号中填入循环条件
	{
		cout << num << endl;
		num++;
	}

	system("pause");

	return 0;
}

注意:在执行循环语句的时候,程序必须提供跳出循环的出口,否则出现死循环

while 循环练习案例猜数字

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

在这里插入图片描述C++入门笔记(基础版)_第7张图片

示例

int main()
{
	//1.系统生成随机数
	int num1 = rand() % 100;  //在c++中生成随机数的主要代码是rand,“%”的作用主要是随机数的生成区间
							  //此条代码表示生成 0 ~ 99 随机数
							  //该代码的缺点:每次运行生成的值是固定的

	//因此,为了避免这种情况,我们需要在代码段中添加随机数的种子
	srand((unsigned int)time(NULL));  
    //在课程中需要添加头文件 #inclued 
	//在新版的Microsoft visual studio中可以不需要添加此头文件
	//利用当前系统时间生成随机数,防止每次生成的随机数都一样

	int num2 = rand() % 100 + 1;   //此条代码表示的是生成1 ~ 100的随机数
	cout << num1 << endl;
	cout << num2 << endl;

	//2.玩家进行猜测
	int val = 0; //玩家输入的数据
	cout << "请输入一个 1 ~ 100 的数字:" << endl;

	//3.判断玩家的猜测
	while (1)  //使代码段一直处于运行状态,直到才对了才停止运行
	{   
		cin >> val;
		
		//猜错   提示猜的结果 过大或者过小 重新返回第2步

		if (val > num2) //如果玩家 输入的值 大于 系统随机生成的数字
		{
			cout << "猜测过大" << endl;
		}
		else if (val < num2)
		{
			cout << "猜测过小" << endl;
		}
		
        else
		{
			cout << "猜对了" << endl;  //猜对,退出游戏
			break;  //在break在循环中,可以利用该关键字来退出当前循环
		}
	}

	system("pause");
	return 0;
}
4.2.2 do…while 循环语句

作用:满足循环条件,执行循环语句

语法do {循环语句} while {循环条件}

注意:与while的区别在于do…while会先执行一次循环语句,再判断循环条件
C++入门笔记(基础版)_第8张图片

示例

int main()
{
	//do...while语句
	//在屏幕中输出0 ~ 9这10个数字
	int num = 0;
	do
	{
		cout << num << endl;
		num++;
	} 	while (num < 10);
	
    //do...while和while的循环区别在于 do...while会先执行一次循环语句
	int num = 0;
	do
	{
		cout << num << endl;
		num++;
	} while (num);
	//do...while代码段分析:
	//1.创建变量,并初始化其值为0
	//2.执行do括号中的语句,输出num,运行结果为0,num的值自增1
	//3.while语句判断条件为num的值,此时num已通过代码 num++ 使num的值变成1
	//4.因为在c++中除了0表示假以外其他的数字都表示真,故此代码段将会一直运行下去

	//while循环示例
	int num = 0;
	while (num)
	{
		cout << num << endl;
		num++;
	}
	//while代码段分析:
	//1.while语句判断num是否符合执行循环的条件
	//2.因为num的值为0,所以不符合执行循环的条件,故停止执行

	system("pause");
	return 0;
}

总结:与while 循环的区别在于,do…while 先执行一次循环语句,再判断循环条件

练习案例水仙花数

案例描述:水仙花数是指一个 3 位数,它的每个位上的数字的 3 次幂之和等于它本身

例如:1^3 + 5^3 + 3^3 = 153

请利用do…while语句,求出所有3位数中的水仙花数

示例

int main()
{
	//1.把所有的三位数输出(100 ~ 999)
	int num = 100;
    do
    {
        cout << num << endl;
        num++;
    } while (num < 1000);

	//2.在所有的三位数中找到水仙花数
	//例如以水仙花数:153为例
	
	//1.获取个位 153%10 = 3		表示的是对数字取模于10 获取到个位数字
	//2.获取十位 153/10 = 15 % 10 = 5   在c++中,两个整数相除,不会得到小数,而是会直接舍弃小数位,所以输出的结果为15
	//3.获取百位 153/100 = 1	直接整除100获取百位
	
	//判断:个位^3 + 十位^3 + 百位^3 = 本身

	do
	{
		int a = 0;  //个位
		int b = 0;  //十位
		int c = 0;  //百位

		a = num % 10;  //获取个位
		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.3.3 for循环语句

作用:满足循环条件,执行循环语句

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

示例

int main()
{
	//用for循环从数字0 打印到 数字9
	for (int i = 0; i < 10; i++)
	{
		cout << i << endl;
	}
	//解读代码段含义:
	//for循环,先创建一个变量并对这个变量初始化
	//为了打印 0 ~ 9 这10个数字,添加条件 i < 10,没到10则一直执行语句
	//每次循环过后 i的值自增1

	//其实for括号里的条件是可以拆分到代码段里的
	int i = 0;
	for (; ; )
	{
		if (i >= 10)
		{
			break;
		}
		cout << i << endl;
		i++;
	}
	//注意:for循环中的表达式,要用分号进行分隔
	//总结:while,do...while,for都是开发中常用的循环语句,for循环结构比较清晰,比较常用

	system("pause");
	return 0;
}

详解

在这里插入图片描述

注意:for循环中的表达式,要用分号进行分隔

总结:while,do…while,for 都是开发中常用的循环语句,for 循环结构比较清晰,比较常用

练习案例敲桌子

案例描述:从1开始数到数字100,如果数字个位含有7,或者数字十位含有7,或者该数字是7的倍数,我们打印敲桌子,其余数字直接打印输出
C++入门笔记(基础版)_第9张图片

示例

int main()
{
	//1.先输出 1~100这些数字
	for (int i = 1; i <= 100; i++)
	{
		//2.从这100个数字中找到特殊数字,改为“敲桌子”
		//特殊数字:
		//7的倍数	(7 14 21 28...)% 7 = 0 
		//个位有7	(7 17 27 37...)% 10  = 7
		//十位有7	(70 71 72 73...)/ 10 = 7
		
		if (i % 7 == 0 || i % 10 == 7 || i / 10 ==7)  // || 是“或”的意思
		//如果是特殊数字,打印敲桌子
		{
			cout << "敲桌子" << endl;
		}
		
        else
		{
			cout << i << endl;
		}
	}

	system("pause");
	return 0;
}
4.2.4 嵌套循环

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

例如我们想在屏幕中打印如下图片,就是要利用嵌套循环

image-20210724233517220

示例

int main()
{
	//利用嵌套循环实现星图
	//打印一行星图
	for (int i = 0; i < 10; i++)
	{
		cout << "* ";
	}
	cout << endl;
	
	//打印十行星图 (使用do...while循环)
	int j = 0;
	do
	{
		for (int i = 0; i < 10; i++)
		{
			cout << "* ";
		}
		cout << endl;
		j++;
	} 	while (j < 10);
	
	//打印十行星图 (使用while循环)
	int j = 0;
	while(j < 10)
	{
		for (int i = 0; i < 10; i++)
		{
			cout << "* ";
		}
		cout << endl;
		j++;
	}

	//打印十行星图 (使用for循环)
	//外层执行一次,内层执行一周
	//外层循环
	for(int j = 0; j < 10 ; j++)
	{
		//内层循环
		for (int i = 0; i < 10; i++)
		{
			cout << "* ";
		}
		cout << endl;
	}
	//写代码的时候变量不要起一样的名字

	system("pause");
	return 0;
}

练习案例乘法口诀表

案例描述:利用嵌套循环,实现九九乘法表

C++入门笔记(基础版)_第10张图片

分析

C++入门笔记(基础版)_第11张图片

示例

int main()
{
	//乘法口诀表
	//打印行数
	for (int i = 1; i <= 9; i++)
	{
		//cout << i << endl;
		
		//打印列数
		for (int j = 1; j <= i; j++) //打印的列数要小于等于当前的行数
		{
			cout << j << "*" << i << " = " << j * i << " ";
		}
		cout << endl;
	}

	system("pause");
	return 0;
}

4.3 跳转语句

4.3.1 break 语句

作用:用于跳出选择结构或者循环结构

break 使用的时机:

  • 出现在 switch 条件语句中,作用是终止 case 并跳出 switch
  • 出现在嵌套循环中,作用是跳出当前的循环语句
  • 出现在嵌套循环中,跳出最近的内层循环语句

示例

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.2 continue 语句

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

示例

int main()
{
	// continue 语句
	//作用:在循环语句中,跳过本次循环中余下未执行的语句,继续执行下一次循环
	for (int i = 0; i < 100; i++)
	{
		//如果是奇数输出,偶数则不输出
		if (i % 2 == 0)
		{
			continue;   //可以筛选条件,执行到此就不再向下执行,执行下一次循环
		}
		cout << i << endl;
	}
	//如果换成break,则什么东西都没输出。因为0就是偶数,直接退出循环体
    
	//break和continue的区别:continue并没有使整个循环终止,而break会跳出循环

	system("pause");
	return 0;
}
4.3.3 goto 语句

作用:可以无条件跳转语句

语法goto 标记;

解释:如果标记的名称存在,执行到 goto 语句时,会跳转到标记的位置

示例

int main()
{
    //go to语句
    cout << "1.xxxx" << endl;
    goto FLAG;
    cout << "2.xxxx" << endl;
    cout << "3.xxxx" << endl;
    cout << "4.xxxx" << endl;
    FLAG:
    cout << "5.xxxx" << endl;

    //注意:在程序中不建议使用goto语句,以免造成程序流程的混乱

    system("pause");
    return 0;
}

注意:在程序中不建议使用goto语句,以免造成程序流程的混乱

5.数组

5.1 概述

所谓数组,就是一个舞台,里面存放了相同类型的数据元素

特点1:数组中的每个**数据元素都是相同的数据类型**

特点2:数组是由**连续的内存**位置组成的

C++入门笔记(基础版)_第12张图片

5.2 一维数组

5.2.1 一维数组定义方式

一维数组定义的三种方式

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

示例

int main()
{
    //数组的特点:
    //1.放在一块连续的内存空间中
    //2.数组中每个元素都是相同的数据类型,如整型,浮点型啥的
    //3.下标都是从 0 开始计数的

    //数组:
    
        1.数据类型   数组名[ 数组长度 ]
        2.数据类型   数组名[ 数组长度 ] = {1,值2 ....};
        3.数据类型   数组名[ ] = {1,值2 };
    
    
    //1.数据类型   数组名[数组长度]
    int arr[5];
    
    //给数组中的元素进行赋值
    //注意:数组元素的下标是从0开始索引的
    arr[0] = 10;
    arr[1] = 20;
    arr[2] = 30;
    arr[3] = 40;
    arr[4] = 50;

    //访问数据元素
    
    cout << arr[0] << endl;
    cout << arr[1] << endl;
    cout << arr[2] << endl;
    cout << arr[3] << endl;
    cout << arr[4] << endl;
    

    //2.数据类型   数组名[数组长度] = { 值1,值2 .... }
    //特点:如果在初始化数据的时候,没有全部填写完,会用0来填补剩余数据
    int arr2[5] = { 10,20,30,40,50 };
    int arr3[5] = { 70,80 };
    
    cout << arr2[0] << endl;
    cout << arr2[1] << endl;
    cout << arr2[2] << endl;
    cout << arr2[3] << endl;
    cout << arr2[4] << endl;
    
    //利用循环 来输出数组中的元素
    for (int i = 0; i < 5; i++)
    {
        cout << arr2[i] << endl;
        cout << arr3[i] << endl;
    }
    
    //3.数据类型   数组名[] = { 值1,值2 }
    //定义数组的时候,必须要有初始长度
    int arr4[] = { 90,80,70,60,50,40,30,20,10 }; //系统会根据你定义的初始值来推测数组的长度
    for (int i = 0; i < 9; i++)
    {
        cout << arr4[i] << endl;
    }
    
    //总结1:数组名的命名规则与变量命名规范一致,不要和变量重名
    //总结2:数组中的下标是从0开始索引

    system("pause");
    return 0;
}

总结1:数组名的命名规则与变量命名规范一致,不要和变量重名

总结2:数组中的下标是从0开始索引

5.2.2 一维数组的数组名

一维数组名称的用途

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

示例

int main()
{
    //一堆数组名的用途:
    //1.可以统计整个数组在内存中的长度
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    cout << "整个数组占用的内存空间为:" << sizeof(arr) << endl;  //40
    cout << "每个元素所占的内存空间为:" << sizeof(arr[0]) << endl;  //4
    cout << "数组中元素的个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;  //10
    
    //2.可以获取数组在内存中的首地址
    cout << "数组的首地址为:" << (int)arr << endl;  //1808752
    cout << "数组中第一个元素的地址为:" << (int)&arr[0] << endl;  //1808752
    cout << "数组中第二个元素的地址为:" << (int)&arr[1] << endl;  //1808756
    
    //数组名是常量,不可以进行赋值操作
    arr = 100; //报错,显示表达式必须是可以修改的左值,数组名是常量,因此不可以赋值

    system("pause");
    return 0;
}

注意:数组名是常量,不可以进行赋值操作

总结1:直接打印数组名,可以查看数组所占内存的首地址

总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小

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

案例描述

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

找出并打印最重小猪的体重

示例

int main()
{
    //1.创建5只小猪体重的数组
    int arr[5] = { 300,350,200,400,250 };
    
    //2.从数组中找到最大值
    int max = 0; //先认定一个最大值为0
    for (int i = 0; i < 5; i++)
    {
        //cout << arr[i] << endl;
        //如果访问的数组中的元素比我认定的最大值还要大,则更新最大值
        if (arr[i] > max)
        {
            max = arr[i];
        }
    }
    //3.打印最大值
    cout << "最重的小猪体重为:" << max << endl;

    system("pause");
    return 0;
}

练习案例2:数组元素的逆置

案例描述:请声明一个5个元素的数组,并且将元素逆置

(如原数组元素为:1,3,2,5,4;逆置后输出的结果为:4,5,2,3,1)

编程思路

示例

int main()
{
    //实现数组元素的逆置

    //1.创建数组
    int arr[5] = { 1,3,2,5,4 };
    cout << "数组逆置前:" << endl;
    //1.1 逐个打印数组
    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) 的 临时变量(temp) 赋值 给 结束下标(end)

        //下标更新
        start++;
        end--;
    }

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

    system("pause");
    return 0;
}
5.2.3 冒泡排序

作用:最常用的排序算法,对数组内元素进行排序

  1. 比较相邻的元素,如果第一个比第二个大,就交换他们两个
  2. 对每一行相邻元素做同样的工作,执行完毕后,找到第一个最大值
  3. 重复以上的步骤,每次比较次数-1,直到不需要比较
    在这里插入图片描述
    在这里插入图片描述

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

int main()
{
	//思路:
	//1.比较相邻元素,如果第一个比第二个大,就交换他们两个
	//2.对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值
	//3.重复以上的步骤,每次比较次数-1,直到不需要比较
	//排序的总轮数 = 元素个数 - 1;
	//每轮对比次数 = 元素个数 - 排序轮数 - 1;

	//利用冒泡排序实现升序序列
	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.3 二维数组

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

C++入门笔记(基础版)_第13张图片

5.3.1 二维数组定义方式

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

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

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

示例

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;
	
	//2. 数据类型 数组名[行数][列数] = { {数据1,数据2 } , {数据3,数据4} };(推荐使用)
	int arr2[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};

	//3. 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
	int arr3[2][3] = { 1,2,3,4,5,6 };  //系统自动分辨[3] 为每3个数字为一行
	
	//4. 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
	//定义二维数组的时候,可以省略行数,但是绝对不能省略列数
	int arr4[][3] = { 1,2,3,4,5,6 };  //系统自动分辨[3] 为每3个数字为一行
	
	cout << arr[0][0] << endl;
	cout << arr[0][1] << endl;
	cout << arr[0][2] << endl;
	cout << arr[1][0] << endl;
	cout << arr[1][1] << endl;
	cout << arr[1][2] << endl;
    
    //简化输出代码
	for (int r = 0; r < 2; r++)
	{
		for (int c = 0; c < 3; c++)
		{
			cout << arr[r][c] << endl;
		}
	}

    system("pause");
	return 0;
}

注意:定义二维数组的时候,如果初始化了数据,可以省略行数,但是绝对不能省略列数

5.3.2 二维数组数组名
  • 查看二维数组所占用的内存空间
  • 获取二位数组首地址

示例

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

	//1.可以查看占用内存空间大小
	//整型占4个字节,6个元素占24个字节
	//改成double占8个字节,6个元素占48个字节
	int arr[2][3] =
	{
		{1,2,3},
		{4,5,6}
	};
	cout << "二维数组占用的内存空间为:" << sizeof(arr) << endl;  //24
	cout << "二维数组第一行占用的内存:" << sizeof(arr[0]) << endl;  //12
	cout << "二维数组第一个元素占用的内存为:" << sizeof(arr[0][0]) << endl;  //4
	cout << "二维数组行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;  //2
	cout << "二维数组列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;  //3

	//2.可以查看二维数组的首地址
	cout << "二维数组的首地址为:" << (int)arr << endl;  //与下一行的结果相同
	cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;  //与上一行的结果相同
	cout << "二维数组第二行的首地址为:" << (int)arr[1] << endl;  //与上一行差12,因为第一行所占空间为12
	cout << "二维数组第一个元素的首地址:" << (int)&arr[0][0] << endl;  //与输出第一行的结果相同
	cout << "二维数组第二个元素的首地址:" << (int)&arr[0][1] << endl;  //与上一行代码相差4

    // & 是取址符
    
	system("pause");
	return 0;
}

总结1:二维数组名就是这个数组的首地址

总结2:对二维数组名进行sizeof时,可以获取整个二维数组占用的内存空间大小

5.3.3 二维数组应用案例

考试成绩统计

案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表。请分别输出三名同学的总成绩

语文 数学 英语
张三 100 100 100
李四 90 50 100
王五 60 70 80

编程思路

C++入门笔记(基础版)_第14张图片

参考答案

int main()
{
	//二维数组案例-考试成绩统计

	//1.创建一个二维数组
	int scores[3][3] =
	{
		{100,100,100},
		{90,50,100},
		{60,70,80}
	};

	string names[3] = { "张三","李四","王五" };

	//2.统计每个人的总和分数
	for (int hang = 0; hang < 3; hang++)
	{
		int sum = 0;  //统计分数总和的变量
		for (int lie = 0; lie < 3; lie++)
		{
			sum += scores[hang][lie];
			//cout << scores[hang][lie] << " ";
		}
		cout << "第" << hang + 1 << "个人的总分为:" << sum << endl;
		cout << names[hang] << "的总分为:" << sum << endl;
	}
	//输出结果为:300,240,210

	system("pause");
	return 0;
}

6.函数

6.1 概述

作用:将一段经常使用的代码封装起来减少重复代码

一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能

6.2 函数的定义

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

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

定义函数步骤示例

语法

返回值类型 函数名 (参数列表)
{
    
    函数体语句
        
    return 表达式
        
}
  • 返回值类型:一个函数可以返回一个值,在函数定义中
  • 函数名:给函数起个名称
  • 参数列表:使用该函数时,传入的数据
  • 函数体语句:花括号内的代码,函数内需要执行的语句
  • return 表达式:和返回值类型挂钩,函数执行完后,返回值相应的数据

示例:定义一个加法函数,实现两个数相加

//函数的定义
//语法:
//返回值类型 函数名 (参数列表) {函数体语句; return 表达式;}

int add(int num1, int num2)
{
	int sum = num1 + num2;
	return sum;  //把两个数的相加结果做一个返回
}

6.3 函数的调用

功能:使用定义好的函数

语法函数名(参数)

示例

int add(int num1, int num2)  //在函数定义的时候 num1和num2 并没有实际的值,它只是一个形式上的参数,简称形参
    						 //当调用函数的时候,实参的值会传递给形参
{
	int sum = num1 + num2;
	return sum;
}

int main()
{
	//main函数中调用add函数
	int a = 10;
	int b = 20;

	//函数调用的语法:函数名称 (参数) 
	int c = add(a, b);
	cout << "c = " << c << endl;  //30

	a = 100;
	b = 500;
	c = add(a, b);  //a和b称为 实际参数 简称实参,因为a,b有实际的数值
	cout << "c = " << c << endl;  //600

	system("pause");
	return 0;
}

总结:函数定义里的小括号称为形参,函数调用时传入的参数称为实参

6.4 值传递

  • 所谓值传递,就是函数调用时实参将数值传入给形参
  • 值传递时,如果形参发生,并不会影响实参

示例

//定义函数,实现两个数字进行交换的函数
//如果函数不需要返回值,声明的时候可以写void,void代表着无类型
void swap(int num1, int num2)
{
	cout << "交换前:" << endl;
	cout << "num 1 = " << num1 << endl;  //10
	cout << "num 2 = " << num2 << endl;  //20

	int temp = num1;
	num1 = num2;
	num2 = temp;
	cout << "交换后:" << endl;
	cout << "num 1 = " << num1 << endl;  //20
	cout << "num 2 = " << num2 << endl;  //10

	return;  //返回值不需要的时候,可以不写return
}

int main()
{
	int a = 10;
	int b = 20;
	cout << "a = " << a << endl;  //10
	cout << "b = " << b << endl;  //20

	//当我们做值传递的时候,函数的形参发生改变,并不会影响实参
	swap(a, b);
	cout << "a` = " << a << endl;  //10
	cout << "b` = " << b << endl;  //20

	system("pause");
	return 0;
}

值传递原理详解

C++入门笔记(基础版)_第15张图片

总结:值传递时,形参是修饰不了实参的

6.5 函数的常见样式

常见的函数样式有4种

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

示例

//函数的常见样式
//1. 无参无返
void test01()  //无参,没有参数列表; 无返,没有返回值,所以用void
{
	cout << "this is test01" << endl;
}

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

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

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

int main()
{
	//无参无返的函数调用
	test01();  //输出 this is test01

	//有参无返的函数调用
	test02(1000);  //输出1000

	//无参有返的函数调用
	int num1 = test03();  //定义一个变量来接收返回值
	cout << "num1 = " << num1 << endl;  //1000

	//有参有返的函数调用
	int num2 = test04(10000);  //this is test04 b = 10000
	cout << "num2 = " << num2 << endl;  //10000

	system("pause");
	return 0;
}

输出结果

C++入门笔记(基础版)_第16张图片

6.6 函数的声明

作用:告诉编译器函数名称及如何调用函数,函数的实际主体可以单独定义

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

示例

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

//提前告诉编译器这个函数的存在,可以利用的函数的声明
//函数的声明
//只有 函数类型,函数名和参数列表
//声明可以写多次,但是定义只能写一次
int max(int a, int b);  //在vs 2019中,已经可以不需要声明就可以运行代码了

//定义
int max(int a, int b)
{
	return a > b ? a : b;  //三目运算符:如果a>b,则返回a,否则返回b
}

int main()
{
	int a = 10;
	int b = 20;

	cout << max(a, b) << endl;  //20

	system("pause");
	return 0;
}

6.7 函数的分文件编写

作用:让代码结构更加清晰

函数分文件编写一般有4个步骤:

  1. 创建后缀名为 .h 的头文件(同时也要加上我们编写程序的框架)
  2. 创建后缀名为 .cpp 的源文件(为了告诉编译器我的程序和swap是配套的,要在源文件里包含#include “swap.h”)
  3. 在头文件中写函数的声明
  4. 在源文件中写函数的定义

示例

//swap.h文件
#include 
using namespace std;

//实现两个数字交换的函数声明
void swap(int a, int b);
//swap.cpp文件
#include "swap.h"  //双引号表示的是自定义的头文件

//函数的定义
void swap(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;

	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
}
//main函数文件
#include "swap.h"
int main()
{
	int a = 10;
	int b = 20;
	swap(a, b);
    
	system("pause");
	return 0;
}
//需要用函数的时候只要在程序里加上#include "swap.h"就行了

7.指针

7.1 指针的基本概念

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

  • 内存编号是从 0 开始记录的,一般用十六进制数字表示
  • 可以利用指针变量保存地址

7.2 指针变量的定义和作用

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

示例

int main()
{
	//指针其实就是地址
	//1.定义一个指针
	int a = 10;
	//指针定义的语法:数据类型 * 指针变量名;
	int* p;  //p代表point,意思为指针
	//让指针记录变量a的地址
	p = &a;  //&是取址符号,意思是取变量a的地址,然后让p记录地址
	cout << "a的地址为:" << &a << endl;
	cout << "指针p = " << p << endl;


	//2.使用指针
	//可以通过 解引用的方式来找到指针指向的内存
	//指针前加一个 * 代表解引用,找到指针指向的内存中的数据
	*p;  //指针p对a中的数值进行访问
	cout << "访问后a = " << a << endl;  //10
	*p = 1000;  //指针p对a中的数值进行访问且修改a中的数值
	cout << "再次访问后a = " << a << endl;  //1000
	cout << "* p = " << *p << endl;  //1000

	system("pause");
	return 0;
}

7.3 指针所占内存空间

提问:指针也是种数据类型,那么这种数据类型占用多少内存空间?

C++入门笔记(基础版)_第17张图片

示例

int main()
{
	//指针所占内存空间
	int a = 10;
	//int* p;
	//p = &a;
	//简化代码:
	int* p = &a;

	//在x86下运行的都是4,在x64下运行的都是8
	//在32位操作系统下,指针是占4个字节空间大小,不管是什么数据类型
	//在64位操作系统下,指针是占8个字节空间大小
	cout << "sizeof (int *) = " << sizeof(int*) << endl;  //4,括号里也可以写 p
	cout << "sizeof (int *) = " << sizeof(float*) << endl;  //4
	cout << "sizeof (int *) = " << sizeof(double*) << endl;  //4
	cout << "sizeof (int *) = " << sizeof(char*) << endl;  //4

	system("pause");
	return 0;
}

7.4 空指针和野指针

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

用途:初始化指针变量

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

试图访问并修改空指针

示例1

int main()
{
	//空指针
	//1.空指针用于给指针变量进行初始化操作
	int* p = NULL;  //这代表指针指向的地址编号为0,NULL意思就是0

	//2.空指针是不可以进行访问的
	// 0 ~ 255 之间的内存编号是系统占用的,因此不可以访问
	*p = 100;  //程序崩了

	system("pause");
	return 0;
}

野指针:指针变量指向非法的内存空间

试图访问野指针

示例2

int main()
{
	//野指针
	//在程序中,尽量避免野指针的出现
	//指针变量p指向内存地址编号为0x1100的空间
	int* p = (int*)0x1100;

	//访问野指针报错
	cout << *p << endl;

	system("pause");
	return 0;
}

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

7.5 const修饰指针

const修饰指针有三种情况:

  1. const修饰指针 — 常量指针
  2. const修饰常量 — 指针常量
  3. const既修饰指针,又修饰常量

示例

int main()
{
	//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;  //错误
	p3 = &b;  //错误

	system("pause");
	return 0;
}

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

7.6 指针和数组

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

示例

int main()
{
	//指针和数组
	//利用指针访问数组中的元素
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	cout << "第一个元素为:" << arr[0] << endl;  //1

	int* p = arr;  //arr就是数组的首地址
	cout << "利用指针来访问第一个元素:" << *p << endl;  //1
	p++;  //让指针向后偏移4个字节
	cout << "利用指针来访问第二个元素:" << *p << endl;  //2

	cout << "利用指针来遍历数组:" << endl;
	int* p2 = arr;  //创建指针变量指向数组arr
	for (int i = 0; i < 10; i++)
	{
		cout << *p2 << " ";
		p2++;  //使指针做完解引用后偏移4个字节
	}

	system("pause");
	return 0;
}

7.7 指针和函数

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

示例

//实现两个数字进行交换
//值传递
void swap(int num1, int num2)
{
	int temp = num1;
	num1 = num2;
	num2 = temp;
	cout << "swap num1 = " << num1 << endl;
	cout << "swap num2 = " << num2 << endl;
}

//地址传递
void swap02(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

int main()
{
	//1.值传递
	//swap
	int a = 10;
	int b = 20;
	swap(a, b);  //值传递不会改变实参
	cout << "a = " << a << endl;  //10
	cout << "b = " << b << endl;  //20
	
	//2.地址传递
	//如果是地址传递,可以修饰实参
	//swap02
	swap02(&a, &b);  //地址传递会改变实参
	cout << "地址传递后a = " << a << endl;  //20
	cout << "地址传递后b = " << b << endl;  //10

	system("pause");
	return 0;
}

总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递

7.8 指针,数组,函数

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

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

示例

//冒泡排序函数 数组首地址 数组的长度
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;
			}
		}
	}
}

//打印数组
void printarray(int* arr, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
}

int main()
{
	//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 结构体名 变量名
  • struct 结构体名 变量名 = { 成员1值,成员2值… }
  • 定义结构体时顺便创建变量

示例

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

}s3;  //结构体变量创建方式3

//2.通过学生类型创建具体学生,有三种方法
//2.1 struct Student s1
//2.2 struct Student s2 = { ... }
//2.3 在定义结构体时,顺便创建结构体变量

int main()
{
	//struct 创建可以省略
	//创建方式1 struct Student s1
	struct Student s1;  //struct 去掉仍然可以运行
	
    //给s1的属性赋值,通过 . 来访问结构体变量中的属性
	s1.name = "张三";
	s1.age = 18;
	s1.score = 100;
	cout << "姓名:" << s1.name << " 年龄:" << s1.age << " 分数:" << s1.score << endl;
	//在vs 2019中,string可以不需要添加头文件也可以运行

	//创建方式2 struct Student s2 = { ... }
	struct Student s2 = { "李四" , 19 , 80 };
	cout << "姓名:" << s2.name << " 年龄:" << s2.age << " 分数:" << s2.score << endl;
	
	//创建方式3 在定义结构体时,顺便创建结构体变量(不建议使用)
	//看开头结构体的尾部,定义了s3
	s3.name = "王五";
	s3.age = 20;
	s3.score = 60;
	cout << "姓名:" << s3.name << " 年龄:" << s3.age << " 分数:" << s3.score << endl;

	system("pause");
	return 0;
}

总结1:定义结构体的关键字是struct,不可省略

总结2:创建结构体变量时,关键字struct可以省略

总结3:结构体变量利用操作符 “.” 访问成员

8.3 结构体数组

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

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

示例

//结构体数组

//1.定义结构体
struct Student
{
	string name;  //姓名
	int age;  //年龄
	int score; //分数
};

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

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

	//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 结构体指针

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

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

示例

//结构体指针
//1.定义学生结构体
struct Student
{
	string name;  //姓名
	int age;      //年龄
	int score;    //分数
};

int main()
{
	//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 结构体嵌套结构体

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

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

图例

示例

//定义学生结构体struct student{	string name;	//学生姓名	int age;		//学生年龄	int score;		//学生分数};//定义老师结构体struct teacher{	int id;             //职工编号	string name;        //教师姓名	int age;            //教师年龄	struct student stu; //辅导学生};int main(){	//结构体嵌套结构体	//创建老师	struct teacher t;	t.id = 007;	t.age = 22;	t.name = "吴签";		//创建学生	t.stu.name = "坤坤";	t.stu.age = 20;	t.stu.score = 48;	cout << " 老师姓名:" << t.name		 << " 老师编号:" << t.id		 << " 老师年龄:" << t.age << endl;	    cout << " 辅导学生姓名:" << t.stu.name		 << " 辅导学生年龄:" << t.stu.age		 << " 辅导学生分数:" << t.stu.score << endl;	system("pause");	return 0;}

总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题

8.6 结构体做函数参数

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

传递方式有两种:

  • 值传递
  • 地址传递

示例

//定义学生结构体
struct student
{
	string name;	//姓名
	int age;		//年龄
	int score;		//分数
};

值传递

//打印学生信息函数
void printStudent1(struct student s)
{
	s.age = 50;  //对张三的年龄进行修改
	
	cout << "在子函数中打印学生信息" << endl;
	cout << " 姓名:" << s.name
		 << " 年龄:" << s.age		//结果为50,此时张三的年龄在子函数中已经被修改
		 << " 分数:" << s.score << endl;
}
int main()
{
	//结构体做函数参数
	//将学生传入到一个参数中,打印学生身上的所有信息

	//创建结构体变量
	struct student s;
	s.name = "张三";
	s.age = 20;
	s.score = 80;
	
	printStudent1(s);  //值传递
    //传统输出方法
	cout << "在main函数中打印学生信息" << endl;
	cout << " 姓名:" << s.name
		 << " 年龄:" << s.age		//结果为20,张三的年龄存放在实参中,值传递不影响实参的值
		 << " 分数:" << s.score << endl;

	system("pause");
	return 0;
}

地址传递

//打印学生信息函数
void printStudent2(struct student * p)
{
	p->age = 70;  //对张三的年龄进行修改
	
	cout << "在子函数2中打印学生信息" << endl;
	cout << " 姓名:" << p->name
		 << " 年龄:" << p->age	//结果为70,此时张三的年龄在子函数2中已经被修改
		 << " 分数:" << p->score << endl;
}
int main()
{
	//结构体做函数参数
	//将学生传入到一个参数中,打印学生身上的所有信息

	//创建结构体变量
	struct student s;
	s.name = "张三";
	s.age = 20;
	s.score = 80;
	
	printStudent2(&s);  //地址传递
	//传统输出方法
	cout << "在main函数中打印学生信息" << endl;
	cout << " 姓名:" << s.name
		 << " 年龄:" << s.age		//结果为70,张三的年龄存放在实参中,地址传递可以影响实参的值
		 << " 分数:" << s.score << endl;

	system("pause");
	return 0;
}

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

8.7 结构体中 const 使用场景

作用:用 const 来防止误操作

示例

//const使用场景
//定义一个学生结构体变量
struct student
{
	string name;	//姓名
	int age;		//年龄
	int score;		//分数
};

//打印学生信息的函数
//将函数中的形参改为指针,可以减少内存空间,而且不会复制一个新的副本出来
void printStudents(student s)  //原本的值传递方式
void printStudents(const student * s)  //修改后的函数
{
	s->age = 200;  //报错,const修饰的指针变为常量指针,无法修改数值,但是可以访问
	cout << " 姓名:" << s->name
		 << " 年龄:" << s->age
		 << " 分数:" << s->score << endl;
}

int main()
{
	//创建结构体变量
	struct student s = { "张三",15,70 };

	//通过函数打印结构体变量信息
	printStudents(&s);  //向void函数传入实参的首地址
    
	system("pause");
	return 0;
}

代码详细解读

void printStudents(student s)  //值传递
{
    s.age = 10;  //假设我对age模块的数值进行修改,那么在子函数中输出的就是修改后的数值
}

int main()
{
    printStudents(s);  //传入实参数值
    cout << "main函数中的age" << s.age << endl;  //输出后发现main函数中的age仍然维持修改前的数值
    
    为什么?因为值传递是通过拷贝数据到 void 函数里的 student s中,系统为 student s存放实参的数据(见下图)
    相当于拷贝了一份数据,所以为了节省空间,通常把形参改为指针变量
}

void printStudents(student * s)  //地址传递
修改为指针后 void 函数只占4个字节大小的空间(相当于指针大小)
{
    s->age = 10;  //假设我对age模块的数值进行修改,那么在子函数中输出的就是修改后的数值
}

int main()
{
    printStudents(&s);  //传入实参的首地址
    cout << "main函数中的age" << s.age << endl;  //输出后发现main函数中的age变更为修改后的数值
    现在我不想在打印信息的时候修改数值,为了防止误操作修改数值
    我们引入 const 来限定此数值为不可修改的数值,以此达到无法修改数值的目的
    这就是 const 使用的场景
}

值传递原理

C++入门笔记(基础版)_第18张图片

8.8 结构体案例

8.8.1 案例1

案例描述

学校在做毕设项目,每名老师带领5个学生,总共有3名老师,需求如下

设计学生和老师的结构体,其中在老师的结构体中,有老师姓名和一个存放5名学生的数组作为成员

学生的成员有姓名,考试分数,创建数组存放3名老师,通过函数给每个老师及所带的学生赋值

最终打印出老师数据以及老师所带的学生数据。

示例

//学生的结构体定义
struct student
{
	string sname;
	int score;
};

//老师的结构体定义
struct teacher
{
	string tname;
	struct student sarray[5];
};

//给老师和学生赋值的函数
void setspace(struct teacher tarray[],int len)  //开辟空间,传入数组和数组长度
{
	//添加名字种子,方便反复使用
	string nameseed = "ABCDE";
	//给老师的信息进行赋值
	for (int i = 0; i < len; i++)
	{
		tarray[i].tname = "teacher_";     //对老师起名
		tarray[i].tname += nameseed[i];
		//相当于 tarray[i].tname = tarray[i].tname + nameseed[i]
		//当 i=0 时,"teacher_" 后会追加 nameseed[0]中的元素 "A"
		
		//通过循环给每名老师所带的学生赋值
		for (int j = 0; j < 5; j++)
		{
			tarray[i].sarray[j].sname = "student_";  //给第i位老师所带的第j位学生起名
			tarray[i].sarray[j].sname += nameseed[j];

			int random = rand() % 60 + 40;		//设定一个伪随机数,取值范围在 0+40 ~ 59+40之间
			tarray[i].sarray[j].score = 60;			 //给学生赋分,初始值都是60
			tarray[i].sarray[j].score = random;
		}
	}
}

//打印所有信息的函数
void printalldata(struct teacher tarray[], int len)
{
	//遍历老师
	for (int t = 0; t < len; t++)
	{
		cout << "老师姓名:" << tarray[t].tname << endl;

		//遍历学生
		for (int s = 0; s < 5; s++)
		{
			cout << "\t学生姓名:" << tarray[t].sarray[s].sname		//加\t是为了输出结果更好看
				 << " 考试分数:" << tarray[t].sarray[s].score << endl;
		}
	}
}

int main()
{
	//随机数种子
	srand((unsigned int)time(NULL));  //还要包含一个头文件 #include ,在vs 2019里面不要

	//创建3名老师的数组
	struct teacher tarray[3];

	//通过函数给3名老师的信息赋值,并给老师带的学生信息赋值
	int len = sizeof(tarray) / sizeof(tarray[0]);
	setspace(tarray, len);

	//打印所有老师及所带的学生信息
	printalldata(tarray, len);


	system("pause");
	return 0;
}
8.8.2 案例2

案例描述

设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄

通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果

五名英雄信息如下:

		{"刘备",23,"男"},
		{"关羽",22,"男"},
		{"张飞",20,"男"},
		{"赵云",21,"男"},
		{"貂蝉",19,"女"},

示例

//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下标的元素的年龄,交换2个元素
			if (heroarray[j].age > heroarray[j + 1].age)
			{
				struct hero temp = heroarray[j];
				heroarray[j] = heroarray[j + 1];
				heroarray[j + 1] = temp;

			}
		}
	}
}

//打印排序后数组中的信息
void printheroarray(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()
{
	//2.创建数组存放5名英雄
	struct hero heroarray[5] =
	{
		{"刘备",23,"男"},
		{"关羽",22,"男"},
		{"张飞",20,"男"},
		{"赵云",21,"男"},
		{"貂蝉",19,"女"}
	};

	//先测试一下代码,对上述数组进行输出
	int len = sizeof(heroarray) / sizeof(heroarray[0]);  //计算可动数组的长度
	cout << "排序前的输出结果:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << " 姓名:" << heroarray[i].name
			 << " 年龄:" << heroarray[i].age
			 << " 性别:" << heroarray[i].sex << endl;
	}

	cout << "排序后的输出结果:" << endl;

	//3.对数组进行排序,按照年龄进行升序排序
	Bubblesort(heroarray, len);

	//4.将排序后的结构打印输出
	printheroarray(heroarray,len);
	
	system("pause");
	return 0;
}

你可能感兴趣的:(C++,学习笔记,c++,开发语言)