<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg>
讯享网
讯享网
代码解读
- 第一行 :这是头文件,我们需要iostream这个库,它包含输入输出信息流。
- :这是命名空间,要去哪里执行任务的意思。
- :这是主函数,花括号包围的部分就是函数体,里面是我们编写的指令。
- 【注意】:程序的执行始于对 main 函数的调用。当你运行一个C++程序时,操作系统会加载程序到内存中,然后跳转到 main 函数的开始处,并从此处开始执行程序。这个过程是由操作系统和运行时环境来控制的,而不是由C++语言本身自动完成的。
- cout:输出
结果:

讯享网
- cin:输入
讯享网
假如键盘输入6,结果:

- 连续输入输出
假如键盘输入2,回车再输入8,结果:

0.变量名的规则
- 【规则1】:变量名包含字母、数字、下划线,但数字不能在变量名首位,例如以下变量名:
a(合法)、a123(合法)、_xyz(合法)、2b(不合法,不能以数字开头)
- 【规则2】:具有特殊含义的单词不能作为变量名,否则会报错,因为它们在C++中已经代表了特定的意思,例如以下单词:
while, int, if, char, long, bool 等等。
1.变量的声明
- 想要使用变量,必须先做“声明”,也就是告诉计算机要用到的数据叫什么名字。变量声明的标准语法可以写成:
讯享网
结果:

2.变量的声明且赋值
3.全局变量和局部变量
讯享网

4.常量
常量:一旦创建后,则不能修改它的值,否则会报错。语法:
5.交换两个变量的值
讯享网
结果:

- C++支持丰富的数据类型,它内置了一套基本数据类型,主要包括算术类型和空类型(void)。算术类型又包含了整型和浮点型;而空类型不对应具体的值,只用在一些特定的场合,比如一个函数如果不返回任何值,我们可以让void作为它的返回类型。
C++定义的整型包括以下几种:

结果:

- 数据类型转换
讯享网
结果:

- 数据类型转换规则总结如下:
- 非布尔类型的算术值赋给布尔类型,初始值为0则结果为 false , 否则结果为true ;
- 布尔值赋给非布尔类型,初始值为 false 则结果为0,初始值为 true 则结果为1;
- 浮点数赋给整数类型,只保留浮点数中的整数部分,会带来精度丢失;
- 整数值赋给浮点类型,小数部分记为0。如果保存整数需要的空间超过了浮点类型的容量,可能会有精度丢失。
1.算术运算符
- C++中有5种算术运算符:

结果:

- 以上5种算术运算符优先级顺序如下:
讯享网
结果:

- 算术表达式:由算术运算符和数字组成的式子,例如a + 1,a + b * c等等。
3.赋值运算符
- 在C++中,用等号“=”表示一个赋值操作,这里的“=”就是赋值运算符。
结果:

4.复合赋值运算符

讯享网
结果:

5.自增自减运算符
- “自增”用两个加号“++”表示,表示“对象值加一,再赋值给原对象”;“自减”则用两个减号“–”表示。
- 自增自减运算符各自有两种形式:“前置”和“后置”,也就是说写成“++a”和“a++”都是可以的。它们都表示“a = a + 1”,区别在于表达式返回的结果不同:
- 前置时,对象先加1,再将更新之后的对象值作为结果返回;
- 后置时,对象先将原始值作为结果返回,再加1;
讯享网
结果:

6.关系运算符
- 关系运算符:两个表达式可以使用关系运算符进行比较,运算结果是布尔类型值:true或false。

注意:在C++语法中一个等号“=”表示的是赋值,两个等号“==”才是真正的“等于”。
7.逻辑运算符
- 逻辑运算符:一个关系运算符的结果是一个布尔类型(ture或者false),就可以表示一个条件的判断;如果需要多个条件的叠加,就可以用逻辑“与或非”将这些布尔类型组合起来。这样的运算符叫做“逻辑运算符”。
- 逻辑非(!):将运算对象的值取反后返回;
- 逻辑与(&&):两个运算对象都为true时结果为true,否则结果为false;
- 逻辑或(||):两个运算对象只要有一个为true结果就为true,都为false则结果为false;
讯享网
- 逻辑与和逻辑或有两个运算对象,在计算时都是先求左侧对象的值,再求右侧对象的值;如果左侧对象的值已经能决定最终结果,那么右侧就不会执行计算:这种策略叫做“短路求值”;看下面例子:
8.条件运算符
- “条件运算符”:由“?”和“:”两个符号组成,需要三个运算表达式,形式如下:
讯享网
条件运算符的含义是:计算条件判断表达式的值,如果为true就执行表达式1,返回求值结果;如果为false则跳过表达式1,执行表达式2,返回求值结果。
注意:条件运算符的优先级比较低,所以输出的时候需要加上括号。事实上,条件运算符等同于流程控制中的分支语句if…else…,只用一条语句就可以实现按条件分支处理,这就让代码更加简洁。
9.总结:运算符的优先顺序
- if 语句主要就是判断一个条件是否为真(true),如果为真就执行下面的语句,如果为假则跳过。具体形式可以分为两种:一种是单独一个if,一般称为“单分支”;另一种是if
… else …,称为“双分支”。
1.单分支
讯享网
结果:

2.双分支
- 双分支就是在if分支的基础上,加了else分支;条件为真就执行if后面的语句,条件为假就执行else后面的语句。
结果:

3.多层嵌套分支if … else …
讯享网
结果:

4.多层嵌套分支if … else if…
嵌套分支如果比较多,代码的可读性会大幅降低。所以还有一种更加简单的嵌套分支写法,那就是if … else if …,具体形式如下:
结果:

练习:输入3个数,输出三个数中的最大值
- C++中的循环语句,有while、do while和for三种。
1.while循环
- while只需要给定一个判断条件,只要条件为真,就重复地执行语句。语法如下:
讯享网
需求1:输出1~3之间所有的整数,并用空格隔开。
结果:

分析代码:拆解以上while循环的执行过程
讯享网
需求2:计算出1~10之间所有整数的和。
结果:

2.do while循环
do while和while非常类似,区别在于do while是先执行循环体中的语句,然后再检查条件是否满足。所以do while至少会执行一次循环体。do while语法如下:
讯享网
需求1:输出1~10之间所有的整数,并用空格隔开。
结果:

3.for循环
- for循环的经典语法形式是:
讯享网
- for循环的执行顺序:
for语句头中有三部分,用分号分隔,主要作用是:
- 初始化语句负责初始化一个变量,这个变量值会随着循环迭代而改变,一般就是“循环变量”。
- 中间的条件是控制循环执行的关键,为真则执行下面的循环体语句,为假则退出。
- 最后的表达式会在本次循环完成之后再执行,一般会对循环变量进行更改;
这三个部分并不是必要的,根据需要都可以进行省略。如果省略某个部分,需要保留分号表示这是一个空语句。
需求1:输出1~3之间所有的整数,并用空格隔开。
结果:

分析代码:拆解以上for循环的执行过程
执行顺序示意图:

讯享网
需求2:计算出1~10之间所有整数的和。
结果:

4.循环嵌套
- 循环语句和分支语句一样,也是可以进行嵌套的。具体可以while循环中嵌套while,可以for循环中嵌套for,也可以while、do while和for混合嵌套。因为for的循环变量定义更明确,所以一般用双for循环嵌套会多一些。
讯享网
结果:

分析代码:拆解以上循环嵌套的执行过程
练习:九九乘法表
- 在流程控制语句中还有一类“跳转语句”,主要用来中断当前的执行过程。C++中有四种跳转语句:break,continue,goto以及return。这里主要讲 break 和 continue。
1.break
- 当代码中遇到break时,会直接中断距离最近的循环,跳转到外部继续执行。
讯享网
结果:

2.continue
- continue语句表示“继续”执行循环,也就是中断循环中的本次迭代,并开始执行下一次迭代。
结果:

- 枚举的定义:根据所需解决问题的条件,把该问题所有可能的解,一一列举出来,并逐个检验出问题真正解的方法。枚举法也称穷举法。
(1)判断水仙花数
水仙花数:指一个 n 位数(n≥3),它的每个位上的数字的 n 次幂之和等于它本身。例如,153是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。
题目:找出100~999整数中的所有水仙花数.
- 方法一:使用while循环
讯享网

(2)鸡兔同笼
有一个笼子,里面有鸡和兔子。我们知道总共有7个头和18只脚,我们要找出有多少只鸡和多少只兔子。
假设笼子里有 x 只鸡和 y 只兔子。根据题目,我们可以建立以下方程:
- 头的总数是 x + y = 7(鸡和兔子的头数加起来)。
- 脚的总数是 2x + 4y = 18(鸡有2只脚,兔子有4只脚,总脚数就是2倍的鸡脚数加上4倍的兔脚数)。
现在我们要来解这个方程组,找出 x 和 y 的值。计算结果为: {x: 5, y: 2}。所以,笼子里有 5 只鸡和 2 只兔子。
以上我们用的是数学中列举方程的形式求解,我们也可以利用枚举法,通过代码帮我们计算最终的结果。
- 枚举的思路如图所示:一一列举,最终得到总的脚数量为18的组合,答案即为5 只鸡和 2 只兔子。
结果:

(3)因式分解
题目:有两个两位数,他们的乘积等于1691,求这两个数分别是多少?
讯享网

思考:以上结果为何会输出两遍?代码能否进行优化呢?
代码优化:

1.数组
数组:在程序中为了处理方便,常常需要把具有相同类型的数据对象按有序的形式排列起来,形成“一组”数据,这就是“数组”(array)。

数组中的数据,在内存中是连续存放的,每个元素占据相同大小的空间,就像排好队一样。
1.数组的定义
数组的定义形式如下:
讯享网
数组定义的规则:
- 1.首先需要声明类型,数组中所有元素必须具有相同的数据类型;
- 2.数组名是一个标识符;后面跟着中括号,里面定义了数组中元素的个数,也就是数组的“长度”;
- 3.元素个数也是类型的一部分,所以必须是确定的;
2.数组的初始化
讯享网
重点:
- 1.对数组做初始化,要使用花括号{}括起来的数值序列;
- 2.如果做了初始化,数组定义时的元素个数可以省略,编译器可以根据初始化列表自动推断出来;
- 3.初始值的个数,不能超过指定的元素个数;
- 4.初始值的个数,如果小于元素个数,那么会用列表中的值初始化靠前的元素;剩余元素用默认值填充,整型的默认值就是0;
- 5.如果没有做初始化,数组中元素的值都是未定义的;这一点和普通的局部变量一致;
以上重点中的第四点,举例如下:
结果:

3.数组的访问
(1)访问数组元素
数组元素在内存中是连续存放的,它们排好了队之后就会有一个队伍中的编号,称为“索引”,也叫“下标”;通过下标就可以快速访问每个元素了,具体形式为:
讯享网
例如下面这a1个数组:

注意:
- 1.数组的下标从0开始;
- 2.因此a[2]访问的并不是数组a的第2个元素,而是第三个元素;
- 3.合理的下标,不能小于0,也不能大于 (数组的长度 - 1);否则就会出现数组下标越界;
(2)数组的大小
数组所占据空间大小的计算遵循下面的简单公式:

讯享网
这里为了获取数组的长度,我们使用了sizeof运算符,它可以返回一个数据对象在内存中占用的大小(以字节为单位);数组总大小,除以每个数据元素的大小,就是元素个数。
(3)遍历数组
讯享网
结果:

- 扩展
- 问题:标准数组可以删除数组中的元素吗?
- 回答:标准数组的大小在声明后是固定的,不能改变。但是,我们可以通过一些技巧来模拟删除操作,这些技巧并不会改变数组的实际大小。
举例:
- 结果:

- 总结:在 C++ 中,如果你需要真正删除数组元素并改变数组的大小,可以考虑使用动态数组或容器类,如 std::vector,它是一个动态数组,它允许你在运行时动态地改变数组的大小,提供了插入、删除和查找等操作的便利方法。
4.数组的排序算法
(1)冒泡排序
思路:
- 1.比较所有相邻的元素,如果第一个比第二个大,则交换他们。
- 2.一轮下来,可以保证最后一个数是最大的。
- 3.以此类推,执行n-1轮,就可以完成排序。
- 动画演示:

代码参考:
讯享网
- 思考:以上代码能否进行优化呢?内层循环需要每次都遍历0~len-1次吗??
- 回答:不需要,因为随着外层循环次数的增加,数组末尾的排序会依次确定好位置,例如,第一轮会确定6的位置,第二轮会确定5的位置。所以,内层循环不需要每次都遍历0~len-1次,只需要遍历len-1-i 次就够了。
优化后的代码:
(2)选择排序
思路:
- 1.找到数组中的最小值,把他更换到列表中的第一位。(具体做法:先假设第一数为最小值,记录它的索引值,将第一数和第二个数作比较,如果第一个数大于第二个数,将最小索引值记录为第二个数,依次循环比较,一轮比较下来,最小值所在的索引位置就会被找到,并且把他更换到最开头的位置。
- 2.接着找到第二小的值,把他更换到数组中的第二位。
- 3.以此类推,执行n-1轮,就可以完成排序。
- 动画演示:

参考代码:
讯享网
(3)插入排序
思路:
- 从第二个数开始往前比。
- 如果第二个数比第一个数小,则需要交换他们的位置;再让第三个数和前两个数依次比较(从第二个数开始对比),如果第三个数比其中任何一个数小,则同样需要交换位置。
- 以此类推,进行到最后一个数。
5.数组的查找算法
(1)顺序查找
思路:
- 1.遍历数组。
- 2.找到跟目标值相等的元素,就输出他的下标。
- 3.遍历结束后,如果没有搜索到目标值,就输出-1。
讯享网
(2)二分查找
【注意】:二分查找的前提是数组是排序好的。
思路:
- 1.从数组的中间元素开始,如果中间元素正好是目标值,则搜索结束。
- 2.如果目标值大于或者小于中间元素,则在大于或小于中间元素的那一半数组中搜索。
6.二维数组
(1)二维数组的初始化
讯享网
(2)访问二维数组的大小和元素
结果:

(3)遍历二维数组
讯享网
结果:

2.字符串
- C++的标准库中,提供了一种用来表示字符串的数据类型string,这种类型能够表示长度可变的字符序列,使用它必须包含string头文件。
(1)字符串的定义
讯享网
(2)访问字符串元素
- 字符串同样是通过索引访问内部的每个字符,索引从0开始。
- 获取字符串的长度:str.size()
结果:

(3)遍历字符串
讯享网
3.指针
(1)指针基础
- 指针的定义语法形式为:
这里的类型就是指针所指向的数据类型,后面加上星号“*”,然后跟指针变量的名称。例如:
讯享网

- 流程图解析:

- 总结:指针的本质,其实就是一个数表示的内存地址。

- 再举个例子:
(2)指针用途
- 简单的指针运算
讯享网

- 数组指向

- 遍历数组元素
讯享网
- 可作为函数的参数和返回值
(3) const修饰指针
const修饰指针有三种情况
- const修饰指针 — 常量指针
- const修饰常量 — 指针常量
- const即修饰指针,又修饰常量
讯享网
- 总结:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量
(4)指针和函数详解
总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
(5)实战演练
- 案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序
- 例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
讯享网
4.结构体
结构体的特点:一个结构体类型,可以包含多个成员(类似数组元素),每个成员类型不限。可以做到一批不同类型的数据,混装在一个结构体内。
(1)结构体的基本应用:
(2)结构体成员的默认值
【注意】:结构体成员的默认值,需要编译器支持C++11或更高版本。
讯享网

(3)结构体数组
- 两种写法:

- 第一种:
- 第二种:
讯享网
结果:

(4)结构体指针


- 总结:结构体指针可以通过 -> 操作符 来访问结构体中的成员
(5)结构体指针数组

讯享网

(6)结构体嵌套结构体
- 作用: 结构体中的成员可以是另一个结构体
- 例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
示例:

(7)结构体做函数参数
- 作用:将结构体作为参数向函数中传递
- 传递方式有两种:1、值传递 2、 地址传递
示例:
讯享网
- 总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
(8)实战演练
案例描述:
- 设计一个英雄的结构体,包括成员姓名,年龄,性别;创建结构体数组,数组中存放5名英雄。
- 通过冒泡排序的算法,将数组中的英雄按照年龄进行升序排序,最终打印排序后的结果。
五名英雄信息如下:
讯享网

5.模板类vector
(1)简介
- “容器”vector是对数组功能进行扩展的一个标准库类型。顾名思义,vector“容纳”着一堆数据对象,其实就是一组类型相同的数据对象的集合。
- 注意:vector是标准库的一部分。要想使用vector,必须在程序中包含头文件,并使用std命名空间。
(2)用法
- 在vector后面跟一个尖括号<>,里面填入具体类型信息。
小试牛刀:
题目:使用vector,往数组中添加10—1倒序的元素,并打印出来
讯享网
(3)vector和数组的区别
- 数组是更加底层的数据类型;长度固定,功能较少,安全性没有保证;但性能更好,运行更高效;
- vector是模板类,是数组的上层抽象;长度不定,功能强大;缺点是运行效率较低;
- 除了vector之外,C++ 11 还新增了一个array模板类,它跟数组更加类似,长度是固定的,但更加方便、更加安全。所以在实际应用中,一般推荐对于固定长度的数组使用array,不固定长度的数组使用vector。
1.函数基本知识
(1)函数定义
一个完整的函数定义主要包括以下部分:
- 返回类型:调用函数之后,返回结果的数据类型;
- 函数名:用来命名代码块的标识符,在当前作用域内唯一;
- 参数列表:参数表示函数调用时需要传入的数据,一般叫做“形参”;放在函数名后的小括号里,可以有0个或多个,用逗号隔开;
- 函数体:函数要执行的语句块,用花括号括起来。
函数一般都是一个实现了固定功能的模块,把参数看成“输入”,返回结果看成“输出”,函数就是一个输入到输出的映射关系。
我们可以定义一个非常简单的平方函数:
使用流程控制语句return,就可以返回结果。
(2)函数调用
- 调用函数时,使用的是“调用运算符”,就是跟在函数名后面的一对小括号;括号内是用逗号隔开的参数列表。
- 这里的参数不是定义时的形参,而是为了初始化形参传入的具体值;为了跟函数定义时的形参列表区分,把它叫作“实参”。
- 调用表达式的类型就是函数的返回类型,值就是函数执行返回的结果。
讯享网
【注意】:
- 实参是形参的初始值,所以函数调用时传入实参,相当于执行了int x = 6的初始化操作;实参的类型必须跟形参类型匹配;
- 实参的个数必须跟形参一致;如果有多个形参,要按照位置顺序一一对应;
- 如果函数本身没有参数,参数列表可以为空,但空括号不能省;
- 形参列表中多个参数用逗号分隔,每个都要带上类型,类型相同也不能省略;
- 如果函数不需要返回值,可以定义返回类型为void;
- 函数返回类型不能是数组或者函数。
(3)全局变量和局部变量
在C++中,全局变量和局部变量是两种不同类型的变量,它们在多个方面存在显著的差异。以下是它们之间的主要区别:
(1)作用域:
- 全局变量:在函数之外定义,其作用域从定义点开始,直到程序结束。全局变量可以在整个程序中访问,包括所有的函数和块。
- 局部变量:在函数或代码块内部定义,其作用域仅限于定义它的函数或代码块。一旦离开该函数或代码块,局部变量就不再存在。
(2)生命周期:
- 全局变量:在程序开始执行时创建,并在程序结束时销毁。它们的生命周期是整个程序的执行时间。
- 局部变量:在函数或代码块被调用时创建,当函数或代码块执行完毕后销毁。它们的生命周期是短暂的,仅限于函数或代码块的执行期间。
(4)函数声明
- 如果我们将一个函数放在主函数后面,就会出现运行错误:找不到标识符。这是因为函数和变量一样,使用之前必须要做声明。函数只有一个定义,可以定义在任何地方;如果需要调用函数,只需要在调用前做一个声明,告诉编译器“存在这个函数”就可以了。
- 函数声明的方式,和函数的定义非常相似;区别在于声明时不需要把函数体写出来,用一个分号替代就可以了。
讯享网
2.参数传递
在上面平方函数的调用中,实参n的值 6 被拷贝给了形参x。
(1)传值的困扰
讯享网
(2)指针形参
- 使用指针形参可以解决以上传值的这个问题。如果我们把指向数据对象的指针作为形参,那么初始化时拷贝的就是指针的值;复制之后的指针,依然指向原始数据对象,这样就可以保留它的更改了。
3.返回类型
(1)无返回值
- 当函数返回类型为void时,表示函数没有返回值。可以在函数中需要返回时直接执行 return语句,也可以不写。因为返回类型为void的函数执行完最后一句,会自动加上return返回。
- 例如,可以将之前“两元素值互换”的代码,包装成一个函数。可以先做一个判断,如果两者相等就直接返回,这样可以提高运行效率。
讯享网
(2)有返回值
如果函数返回类型不为void,那么函数必须执行return,并且每条return必须返回一个值。返回值的类型应该跟函数返回类型一致,或者可以隐式转换为一致。
4.递归
- 如果一个函数调用了自身,这样的函数就叫做“递归函数”。
- 递归是调用自身,如果不加限制,这个过程是不会结束的;函数永远调用自己下去,最终会导致程序栈空间耗尽。所以在递归函数中,一定会有某种“基准情况”,这个时候不会调用自身,而是直接返回结果。
(1)用递归方法求1+2+…+N的值
讯享网
(2)求5的阶乘
- 递归示意图:

(3)斐波那契数列
- 斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, …
- 它的规律是:当前数字,是之前两个数字之和。在数学上,斐波那契数列被以递推的方法定义: F(0)=1,F(1)=1, F(n) = F(n - 1) + F(n - 2)(n ≥ 2)
讯享网
(4)真题演练


- 第一种解法:递归
- 第二种解法:for循环嵌套
讯享网
- 第三种解法:等差数列求和公式

(4)路飞吃桃
题目链接
参考代码:递归
讯享网
参考代码:for循环
(5)弹簧板
题目链接
参考代码:
讯享网
(6)递归实现指数型枚举
题目链接
(7)递归实现组合型枚举
题目链接
讯享网
(8)递归实现排列型枚举
题目链接






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/157650.html