C++(写完之后记得移植到csdn)
main 是一个程序的入口,每个程序都必须有这么一个函数,并且仅有一个
注释
单行注释://
多行注释:/* */
变量
作用:给一段指定的内存空间起名,方便操作这段内存
语法:数据类型 变量名 = 初始值;
常量
作用:用于记录程序中不可以更改的数据
两种方式
-
#define 宏变量: #define 常量名 常量值 (结尾没有;号,并且写在main函数之前)
通常在文件上定义,表示一个常量
-
const修饰的变量 const 数据类型 常量名 = 常量值(写在main函数里面)
通常在变量定义前加关键字const,修饰该变量为常量,不可以修改。
#include <iostream> using namespace std; #define Day 7 //方式1 int main(){ cout << "一周总共有:"<< Day << "天"<<endl; const int month = 12; cout <<"一年总共有:"<<month <<"个月"<< endl; return 0; }
关键字
有截图
标识符命名规则
标识符只能由字母、数字、下划线组成。
第一个字符不能是数字,不能是关键字
标识符中字母区分大小写
建议:给标识符命名时,争取做到见名知意的效果,方便别人知道
整形类型
存在的意义:给变量分配合适的内存空间
有截图
sizeof关键字
统计数据类型所占内存的大小
sizeof(数据类型/变量)
类型大小比较:short < int <=long <=long long
实型类型(浮点型)
有截图
作用:用于表示表示小数
浮点型变量分为两种:
1、单精度float
2、双精度double
二者区别:在于表示的有效数字范围不同
注意:
-
有效数字既包括整数也包括小数。eg:3.14表示三位有效数字
-
单精度如果后面不带f,默认为double型,eg:float f1 = 3.14
默认3.14为双精度,然后转化为float
扩展:科学计数法
字符
作用:字符型变量用于显示单个字符
注意:
-
用单引号括起来,不要用双引号。
-
单引号里面只能有一个字符,不可以是字符串
-
C和C++中字符变量只占用一个字节。
-
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放到存储单元中
ASCII表注意事项:
转义字符
作用:用于表示一些不能显示出来的ASCII字符
有转义字符的截图
字符串型
作用:用于表示一串字符
有两种风格:
-
C语言风格:char 变量名【】 = “字符串值”;
-
C++风格:string 变量名 = “字符串值”;
注意:C++风格字符串时候,要用头文件#include<string>
C风格:等号后面的字符串值用双引号
布尔类型
作用:只代表真和假
-
true----真(本质是1)
-
false---假(本质是0)
注意:只要是非0的值都代表真
bool类型:占一个字节
数据的输入
作用:用于键盘获取数据
语法:cin>>变量
运算符
运算符的分类:
有截图
算术运算符
有截图
注意:
-
两个数想除,结果依然是整数,将小数部分去除。
-
两数相除,除数是不可以为0的。
-
两个小数可以相除,运算的结果也可以是小数
取模运算符
-
两个数相除数不可以为0,所以也做不了取模运算
-
两个小数不可以做取模运算的
总结:只有整形变量可以进行取模运算
前后置运算:
-
前置递增:先让变量+1,然后进行表达式运算 (++a)
-
后置递增:先进行表达式运算,后让变量+1(a++
eg:int a = 10;
int b1 = ++a*10 结果输出:a = 11; b1 =110
int a = 10;
int b1 = a++*10 结果输出:a = 11; b1 =100
因为先进行a*10运算,在进行a的自加一
赋值运算符:
有截图
比较运算符
有截图
逻辑运算符
有截图
注意:只要不是0都为真。有0就是假
-----------------------------------------
程序流程结构
-
顺序结构:顺序执行,不跳转
-
选择结构:条件满足就选择执行
-
循环结构:条件满足,循环多次执行某段代码
选择结构
-
单行结构:if () {} 注意:在判断语句后面,不要加分号
-
多行结构:if(){} else{}
-
多条件结构:if(){}else{} if(){}else{}
-
嵌套if语句:就是在if语句中再写一个if语句
案例:三只小猪称重
switch语句
有截图
注意:
-
break表示退出当前分支;
-
Switch
优点:结构清晰,执行效率高
缺点 :判断时候只能是整型或者字符型,不可以是一个区间
总结:与if语句相比,对于多条件判断时,switch的结构清晰,执行效率高,缺点是switch不可以判断区间。
while循环
注意:只要循环条件的结果为真,就执行循环语句
while循环案例练习:猜数字
do while 循环
注意:与while的区别在于do......while 循环会先执行一次循环语句,再判断循环条件
案例:水仙花数
for循环语句:
注意:
-
for循环中的表达式,要用分号进行分隔
-
while,do...while,for都是开发中常用的循环语句,for循环结构比较清晰,比较常用
练习案例:敲桌子
嵌套循环(常见双重for循环):
案例:乘法口诀表
跳转语句
break语句:
作用:用于跳出选择结构或者循环结构
break使用的时机:
-
出现在switch条件语句中,作用是终止case并跳出Switch
-
出现在循环语句中,作用是跳出当前的循环语句
-
出现在嵌套循环中,跳出最近的内层循环语句
continue语句:
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环。
注意:continue并没有使整个循环终止,而break会跳出循环。
goto语句:
作用:可以无条件跳转语句
语法:goto 标记
标记:
解释:如果标记的名称存在,执行到goto语句时,会跳转到标记的位置
注意:在程序中不建议使用goto语句,以免造成程序流程混乱。
数组
所谓数组就是一格集合,里面存放了相同类型的数据元素
特点1:数组中的每一个数据元素都是相同的数据类型
特点2:数组是由连续的内存位置组成的
数组有三种定义方式:
-
不给初值:int a[ 5 ] ; (定义数组的时候必须有初始长度,除非既定义也初始化才可以)
-
给初值:int a[5] = {1,2,3,4,5};
-
不给长度:int a[ ] = {1,2,3,4,5};
注意:如果在初始化数据的时候,没有全部填写完,会用0来填补剩余数据。
总结1:数组名的命名规范与变量名命名规范一致,不要和变量重名
总结2:数组中下标是从0开始索引的
一维数组名称的用途:
-
可以统计整个数组在内存中的长度 sizeof(arr)
-
可以获取数组在内存中的首地址 arr
注意:数组名是常量(他已经指向了一段首地址了,在内存的什么位置了),不可以进行赋值操作
一维数组案例1:五只小猪称体重
一维数组案例2:数组元素逆置
冒泡排序
二维数组
二维数组就是在一维数组上,增加一个维度
二维数组有四种定义方式:
-
不给初值:int a[ 5 ] [5 ]; (定义数组的时候必须有初始长度,除非既定义也初始化才可以)
-
给初值:int a[5] [ 5]= {{1},{2},{3},{4},{5};
-
给长度:int a[5] [ 5]= {1,2,3,4,5};
-
不给长度:int a[ ] [ 5]= {1,2,3,4,5};
注意:推荐使用第二种,结构清晰,直观
注意:如果在初始化数据的时候,没有全部填写完,会用0来填补剩余数据。
二维数组名称的用途:
-
可以统计整个数组在内存中的长度 sizeof(arr)
-
可以获取数组在内存中的首地址 arr
二维数组的案例:考试成绩统计
函数
函数的定义:
1、返回值类型 (函数不需要返回值,声明的时候可以写void)
2、函数名
3、参数列表
4、函数体语句
5、return 表达式 (返回值不需要的时候,可以不写return)
语法:
返回值类型 函数名 (参数列表)
{
函数体语句
return 表达式 // 注意:return 表达式同返回值类型挂钩
}
函数的调用:
函数名(参数)
注意:函数是先定义后使用的吗?
对的
定义的函数是形参,调用的函数是实参,但调用函数时候,实参的值会传递给形参。
值传递
-
函数调用时实参将数值传入给形参
-
值传递时,如果形参发生改变,并不会影响形参。
原来是a和b,后来也是a和b.
内存分析:
函数的常见样式(四种)
-
无参无返 void test01()
-
有参无返 void tesr01(int a)
-
无参有返 int test01()
-
有参有返 int test01(int a)
函数声明:
作用:告诉编译器函数名称以及如何调用函数,函数的实质主题可以单独定义。
注意:函数的声明可以多次,但是函数的定义只能有一次。
跟定义的函数一模一样,只是后面加了个;
为什么要声明?
因为编译器是一行一行执行的,如果定义的函数在main函数的后面,编译器执行到main函数的时候,会报错,找不到前面有定义过函数,所以函数声明可以告诉main函数,我把定义的函数,放在后面了,自己去找吧。
函数的分文件编写(看看dev的怎么操作)
作用:让代码结构更加清晰
4个步骤:
-
创建后缀名为.h的头文件
-
创建后缀名为.cpp的源文件
-
在头文件中写函数的声明
-
在源文件中写函数的定义
指针
作用:可以通过指针间接访问内存
-
内存编号是从0开始记录的,一般用十六进制数字表示
-
可以利用指针变量保存地址
指针变量的定义和使用
指针变量定义语法: 数据类型 *变量名;
我认为:
-
数据类型*----表示指针类型
-
可以通过指针来保存一个地址,而这个地址记录的就是数据的地址
-
简单来说,指针就是地址
重要: 定义指针 int * p;
p =&a;
使用指针 : 可以通过解引用的方式来找到指针指向的内存
指针前加 * 代表解引用,找到指针指向的内存中的
数据
指针所占内存空间:
指针也是一种数据类型,指针数据类型也占用内存空间
注意:
-
在32位操作系统下,指针是占4个字节空间大小,不管是什么数据类型
-
在64位操作系统下,指针是占8个字节空间大小
空指针和野指针
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的(因为0---255之间的内存编号是系统占用的,因此不可以访问)
运行会引发空指针异常
野孩指针:
指针变量指向非法的内存空间
注意:在程序中,尽量避免出现野指针
总结:空指针和野指针都不是我们申请的空间,因此不要访问
const修饰指针
const修饰指针有三种情况:
-
const修饰指针-----常量指针
特点:指针的指向可以修改,但是指针的值不可以改
-
const 修饰常量-----指针常量
特点:指针的指向不可以改,指针指向的值可以改
-
const 即修饰指针,又修饰常量
特点:指针的指向和指针指向的值都不可以改
重听怎么记
指针和数组 作用:利用指针访问数组中的元素
指针和函数
作用:利用指针作函数参数,可以修改实参的值
回顾:之前讲的值传递,是不改变实参的
自己C语言的内存分析更加清晰
指针,数组,函数
案例
结构体(一个学生)
基本概念:结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
结构体定义和使用
语法:struct 结构体名 {结构体成员列表};
通过结构体创建变量的方式有三种:
-
struct 结构体名 变量名 (不赋初值,后面再赋初值);
-
struct 结构体 变量名 = {成员1值,成员2值......};(直接赋初值)
-
定义结构体时顺便创建变量
第一种:
第二种:
第三种:
总结:
-
定义结构体时的关键字是struct ,不可以省略
-
创建结构体变量时,关键字struct可以省略
-
结构体变量利用操作符“.”访问成员
结构体数组(多个学生)
作用:将定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数] = {{},{}.....{}}
结构体指针
作用:通过指针访问结构体的成员
-
利用操作符 -> 可以通过结构体指针访问结构体属性
结构体嵌套结构体
作用:结构体中的成员可以是另一个结构体
例如:每个老师辅导一个学员,一个老师的结构体中,记录一个学生的结构体
总结:在结构体中可以定义另一个结构体作为成员,用来解决实际问题。
结构体做函数参数
作用:将结构体作为参数向函数中传递
传递方式有两种:
-
值传递
-
地址传递
注意:前面没有讲过二者区别
将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来。
总结:如果不想修改主函数中的数据,用值传递,反之用地址传递
结构体中的const 使用场景
作用:用const来防止误操作
在用指针地址传递的过程中,如果只是想读取信息,而不是想修改信息,就可以用const来防止误操作(简称只读不写),为什么不用值传递呢?因为 将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来。
用const修饰形参的时候,红框就是报错内容
结构体案例1:
结构体案例2:
通讯录管理系统
C++核心编程
主讲面向对象编程技术
1 内存分区模型
C++程序在执行时,将内存大方向划分为4个区域
-
代码区:存放函数体的二进制代码,由操作系统进行管理的
-
全局区:存放全局变量和局部变量以及常量
-
栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
-
堆区:由程序分配和释放,若程序员不释放,程序结束时由操作系统回收。
内存四区的意义:
不同区域存放的数据,赋予不同的生命周期,给我们很大的灵活编程
程序运行前
在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域
代码区:
- 存放CPU执行的机器指令 - 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可 - 代码是只读的,使其只读的原因是防止程序意外地修改了它的指令
全局区:
-
全局变量和静态变量存放在此
-
全局变量还包含了常量区,字符串常量和其它常量也存放在此
-
该区域的数据在程序结束后由操作系统释放
注意:写在函数体内的都是局部变量
总结:
-
C++中在程序运行前分为全局区和代码区
-
代码区特点是共享和只读
-
全局区中存放全局变量、静态变量、常量
-
常量区中存放const修饰的全局常量和字符串常量
程序运行后‘
栈区:
由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
堆区:
由程序员分配释放,若程序员不释放,程序结束时由操作系统回收
在C++中主要利用new在堆区开辟内存