不定期更新
P1 课程安排
P2 第一个c++程序 helloworld
P39 break
-
例子 写个乘法口诀表
-
打印行数
-
break 语句
-
break常见三种使用场合:
- 出现在switch条件语句中,作用是终止case并跳出switch
- 出现在循环语句中,作用是跳出当前的循环语句
- 出现在嵌套循环中,跳出最近的内层循环语句
P40 程序流程结构 跳转语句continue
-
作用:在循环语句中,跳过本次循环中尚未执行的语句,继续执行下一次循环。
-
示例:
- 如下 第3 行永远不会被执行。
- for()
{
1
2
continue; //到本行就不执行3了,而开始下一次循环
3
} - 与break 的区别,break会退出本次循环,而continue不会。
P41 goto语句
- 作用:可以无条件跳转语句
- 语法:goto 标记;
- 解释:如果标记存在,执行到goto语句时,会跳转到标记的位置。
- 会跳过3,4行直接执行第5行,不建议用。
P42 一维数组定义方式
-
概述:所谓数组,就是一个集合,里面存放了相同类型的数据元素。
-
特点:数组中每个数据元素都是相同的数据类型;
数组是由连续的内存位置组成的; -
定义方式:
- 数据类型 数组名【长度】
- 数据类型 数组名【长度】= {值1,值2…}
- 数据类型 数组名【 】 = {值1,值2…}
P44 数组案例 5只小猪称重
P45 数组案例 数组元素逆置
- 下面这个方法得出数组末尾元素下标
P52 函数值传递
- 所谓值传递就是函数调用时实参将数值传给形参
- 值传递时,如果形参发生改变,并不会影响实参
- 如下 a b 是实参,num1 和 num2 是形参,函数内该改变num1,num2 不会影响a,b的值。
P56 指针
-
指针的作用:可以通过指针间接的访问内存,
-
内存编号一般是从0开始记录的,一般用16进制表示。可以利用指针变量保存一个变量的地址
-
定义方法:数据类型 * 指针变量名;
-
理解指针时注意理解int * 不等于 * p 之前老是理解不了
数据类型 * 相当于关键字。
-
使用方法:可以通过解引用的方式来找到指针指向的内存(指针变量名前加一个*)
-
指针类型一定要和变量类型相同
P57 指针所占的内存空间
- c++中规定在32位操作系统中,占用4个内存空间,64位下占8个字节。(可能是编译器位数 不是系统位数)
- 查看方法:下图 编译器选项x86 就是32位系统,选择x64 就是64位系统。图中4条语句就是查看指针变量在内存中所占空间的大小的方法;第一条可以写成 sizeof ( p ) ,一样的效果。
P58 空指针和野指针
- 空指针:指针变量指向内存中编号为0的空间。
- 用途:初始化指针变量
- 注意:空指针指向的内存是不可以访问的
- 示例:如下图程序编译会崩
P59 野指针
- 定义:指针变量指向非法的内存空间
- 如下,程序不会报错,但运行会出错
P60 const修饰指针
-
const修饰指针有三种情况
- const修饰的是指针:常量指针
- const修饰的是常量:指针常量
- const即修饰指针又修饰常量
-
const 修饰的指针叫做常量指针,常量指针的特点是指针的值可以改变,但是指针指向的值不可以改变。如下*p的内容不可以改,但是的内容可以改。
例如:int a = 10;
int b = 11;
const int * p = &a;
*p = 20; (此句语法不合法)
p = &b; (此句语法正确) -
const修饰的是常量 叫指针常量
- 形如:int * const p = &a;
- 特点:指针的指向不可以改,但是指向的值可以改;
例如:int a = 10;
int b = 11;
int * const p = &a;
*p = 20; (此句语法正确)
p = &b; (此句语法不合法)
-
const 即修饰指针又修饰常量
- 形如:const int* const p =&a;
- 特点:指针的指向和指向的值都不可以改;
例如:int a = 10;
int b = 11;
const int * const p = &a;
*p = 20; (此句语法不合法)
p = &b; (此句语法不合法)
-
记忆技巧:
- 把 const 读作常量,把 * 读作指针
- 从左到右读:比如
const int * p = &a; 叫做常量指针。
int * const p = &a; 叫做指针常量。(int * 读作指针)
const int * const p = &a; 叫做即修饰指针又修饰常量; - const后紧跟的就是不可以改的内容。
比如 const int * p = &a; 叫做常量指针。const后紧跟的是int * 所以指向的值(* p)不可以改,但是 p 的内容可以改。
比如 int * const p = &a; 叫做指针常量。const后跟的是p,所以 p 的值不可以改,但是指向的值(* p)可以改。
比如 const int * const p = &a; 叫做即修饰指针又修饰常量;两个都不可以改。
P61 指针和数组
- 利用指针访问数组中的值。
P62 指针和函数
-
指针和函数
-
值传递:之前讲过
-
地址传递:如果是地址传递可以修改实参。
-
P63 指针 数组 和函数
- 实现一个冒泡排序 对10个整型数组
#include <stdio.h>
#include <iostream>
using namespace std;
void bubblesort(int *arr, int len)
{
for (int i = 0; i < len; 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 main(void)
{
int arr[10] = { 1, 5, 6, 8, 6, 6, 3, 7, 9, 7 };
int len = sizeof(arr) / sizeof(arr[0]);
bubblesort(arr, len);
for (int jj = 0; jj < len; jj++)
{
cout << arr[jj] << endl;
}
system("pause");
}
+注意: 头文件那里空格不能少,endl 是 L 不是数字1;
P64 结构体的定义和使用
-
概念:结构体是用户自定义的数据类型,允许用户存储不同的数据类型。
-
语法:struct 结构体名称 { 结构体成员列表 };
-
通过结构体创建变量的方式有三种
- struct 结构体名 变量名;
- struct 结构体名 变量名 = { 成员1值,成员2值 };
- 定义结构体时顺便定义变量;
示例:
创建结构体变量的第三种方法;定义结构体时同时定义结构体变量。
- 定义结构体变量时 struct 关键字可以省略,但是定义结构体时不可以省略。
P65 结构体数组
-
作用:将自定义的结构体放入到数组中方便维护
-
语法:struct 结构体名 数组名 [ 元素个数 ] = {{},{},{},…{}};
-
使用方法:
-
遍历方法和普通数组一样。
P66 结构体指针
-
利用操作符 -> 可以使用结构体中的值
-
结构体指针定义:
-
通结构体指针访问结构体变量中的值,需要利用操作符 ->
-
之前查过-> 和 . 的区别,粗浅了解为一个可以改变值一个不可以改变值,理解的效果时对的,根本区别应该是结构体指针要用 -> 访问。
P67 结构体嵌套
- 在结构体中可以定义另一个结构体,用来解决实际问题。
P68 结构体作为函数参数
- 同样具有值传递和地址传递两种方式。
P69 结构体种const 的使用场景
-
值传递时 形参中会复制一次形参,所以函数内不会改变函数外的实参的值,但这样会导致特别占内存,当传递的变量特别大的时候。比如传一个结构体数组。
-
所以在函数参数中改用指针,可以减少内存空间,而且不会复制新的副本出来。
-
但地址传递会有一个隐患,函数内有可能误操作改变外面实参的值。
-
解决方法:传结构体指针时用const 修饰。
-
小疑问: 传变量指针时,这么用const 修饰 是什么效果。
-
P70 结构体案例1(每个老师结构体包含5个学生)
- 主要知识点结构体嵌套
- 字符追加:之前要是知道这个,zigbee中串口打印就不用老是用两个数组。
P71 结构体案例2(根据嵌套结构体中的一个成员,对嵌套的结构体进行排序)
- 没有特别特殊的
P72 通讯录管理系统演示
-
需求:
-
要做非法输入处理:比如要删除一个不存在的联系人;
P73 通讯录管理系统创建项目
- 创建项目
- 新建文件
P74 通讯录管理系统-菜单
P75 退出功能实现
-
建一个用户选择变量,接收用户输入
P76 通讯录管理系统添加联系人结构
P77 通讯录管理系统添加联系人结构(后三步)
- 清屏 system(“cls”);
P78 显示联系人
-
根据表达式值是1 或 2 决定输出是男或者女,可以用三目运算符,之前编程的好多if都可以这么代替。
P79 删除联系人(检测此人是否存在)
-
c++ 中 case 后不止有一句时需要加{ };
P80 删除联系人(删除操作)
-
删除具体实现是先找到联系人的数组下标,然后将后面的所有元素前移
-
通讯录人员数目减减
P81 查找联系人
P82 修改联系人
- 输入联系人性别时输对才继续往下
P83 清空联系人
P84 程序的内存模型-代码区
- c++ 核心编程
- 本阶段主要针对c++面向对象编程技术做详细讲解,探讨c++ 中的核心和精髓。
- 内存分区模型
c++程序运行时,将内存大方向划分为4个区域- 代码区:存放函数体的二进制代码,由操作系统进行管理的
- 全局区:存放全局变量和静态变量以及常量
- 栈区: 由编译器自动分配释放,存放函数的参数值,局部变量等。
- 堆区: 由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。
- 内存四区的意义:
- 不同的区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。
- 代码区
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域- 代码区:存放cpu执行的机器指令
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可,代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令。
- 代码区:存放cpu执行的机器指令
P85 程序内存模型-内存四区-全局区
- 全局区:全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和其他常量也存放在此
该区域的数据在程序结束后由操作系统释放
例程演示 局部变量,全局变量,静态变量,常量,const修饰的全局常量,const修饰的局部常量的地址 - 总结
c++ 中程序运行前分为全局区和代码区
代码区特点是共享和只读
全局区中存放全局变量、静态变量、常量
常量区中存放const修饰的全局常量 和 字符串常量
P86 程序内存模型-内存四区-栈区(程序运行后)
-
栈区:由编译器自动分配和释放,存放函数的参数值,局部变量等。
-
注意事项:不要返回局部变量的地址,栈开辟的数据由编译器自动释放
-
注意理解这里用int * p 接收函数内的&a;下图中第一行正确返回a的值,第二行返回乱码。
P87 程序内存模型-内存四区-堆区
- 堆区:由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。在c++ 中主要利用new 在堆区开辟
P88 程序内存模型-new 运算符+
-
作用:c++中利用new操作符在堆区开辟数据
-
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用delete
-
语法:new 数据类型利用new 创建的数据,会返回该数据对应的类型的指针
-
释放new 出来数组
-
示例
P89 c++中的引用
- 作用:给变量起别名
- 语法:数据类型 &别名 = 原名
- 图示:注意看到int a = 10 ;理解为定义了一个变量,占了4个字节内存,存的是10.下图中输出为20
P91 c++引用的注意事项
-
引用必须初始化,即下图写法不可以,不能声明时不赋值,后面再赋值
-
引用在初始化后,不可以改变。
-
示例
P92 引用做函数参数
-
作用:函数传递时,可以利用引用的技术让形参修饰实参
-
优点:可以简化指针修改实参
-
示例:实现两个数交换的三种方法前两种
-
引用传递:引用的方式交换两个数的值,参数值传的是别名
P93 引用的本质
- 引用的本质在c++内部实现是一个指针常量
- 讲解示例:发现是引用,理解为int * const ref = &a; 指针常量,const后跟的不能改。
P94 引用-常量引用
- 作用:常量引用主要用来修饰形参,防止函数内误操作改变实参的值
在函数形参列表中,可以加const 修饰形参,防止形参改变实参 - 示例:11 行 写法合法,但不是常量引用常用的用法,11行 代码如果如果去掉前面的const 则不合法。
P95 函数高级-函数的默认参数
-
在c++ 中函数的形参列表中的形参是可以有默认值的。
-
语法:返回值类型 函数名 (参数 = 默认值 ){ }
-
注意:
- 声明时如果定义了初始值 调用时可以不传值,或者只传其中一个形参的值,没传的会用声明时的默认值,传了的就用传进来的。
- 定义时形参列表中某个位置有了默认值,那么从这个位置往后,从左至右都必须有默认值,例如 int func( int a ,int b =1,int c )此句不合法, int func( int a ,int b =1,int c =2 )此句合法。
- 如果声明时形参中有默认值,那么函数实现时形参列表中就不能再赋值了。下图是错误示范。声明和实现只能有一个有默认参数。
P96 函数高级-函数的占位参数
-
c++中函数对的形参列表可以有占位参数,用来做占位,调用时必须需填补该位置
-
语法:返回值类型 函数名 (数据类型){ } (在形参列表中只写数据类型不写变量名)如图第二个int就是占位用的,但是调用时必须给第二个位置传一个值。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8tzfOPe-1644546541808)(en-resource://database/858:1)]
-
在现阶段函数的占位参数存在意义不大,但是在后面的课程中会用到该技术。
-
示例:占位参数也可以有默认值。比如 int func( int a,int = 10 )
P97 函数高级-函数重载
- 作用:函数名可以相同,提高复用性。
- 函数重载需满足的条件:
- 同一个作用域下
- 函数名相同
- 函数的参数类型不同 或者 个数不同 或者 顺序不同
- 注意:函数的返回值不可以作为函数重载的条件
- 示例:
P98 函数高级-函数重载的注意事项
-
引用作为重载的条件
-
函数重载碰到函数默认参数
-
示例:如下图要调用上面的就写 func(a),要调用下面的就写 func( 10 ) ,注意理解图中注释。
-
函数重载碰到默认参数,如下图的定义,当写func( 10 ),两个函数都可以进去,所以编译器会报错。