- 单行注释 //
多行注释 /**/ - 常量
#define 常量名 常量值
const 数据类型 常量名 = 常量值
- 关键字不要和变量或常量重名
- 数据类型
- 短整型(2字节)-整型(4字节)-长整型(4字节)-长长整型(8字节)
short<int<=long<=long long
实型 - float(4)-double(8)
- 科学计数法
3e2 3*10^2
3e-2 3*0.1^2
- sizeof
sizeof(datatype\变量)
- 字符型
char ch = 'a'
字符串
C风格char str[] = "abc"
C++风格string str = "abc"
- 布尔型
bool flag = true
- 键入
int a = 0;
cin >> a;
float b = 3.14f;
cin >> b;
char ch = 'a';
cin >> ch;
string str = "hello";
cin >> str;
bool flag = true;
cin >> flag;
- 三目运算符
表达式1 ?表达式2 : 表达式3
返回的是变量,可以继续进行赋值操作 - goto 无条件跳转语句
- 二维数组定义时可以省去行数
- 查看二维数组的首地址
(int)arr
二维数组的第一行首地址(int)arr[0]
二维数组第一个元素的首地址(int)&arr[0][0]
int 不是必须加的。只是转换类型 - 值传递 形参改变不会改变实参
地址传递 传递的是地址,实参可以改变 - 函数的声明
无需在main前定义函数int max(int a, int b);
声明可以多次,定义只有一次 - 函数的分文件编写
头文件声明函数
源文件导入头文件 应用函数 - 指针 保存地址 初始指针
int * p
& 取地址 取出变量a的地址
* 解引用 找到对应地址中的内容
32位操作系统 x86 所有指针类型均占用4个字节
64位操作系统 x64 所有指针类型均占用8个字节 - 空指针 用于给指针变量进行初始化 不可以访问0~255是系统占用的,因此不可以访问
- 野指针 指向非法的内存空间 直接给指针一个未知地址
- const 修饰指针
a. 常量指针
指针的指向可以更改,但是指针指向的值不可以改
int a = 10;
const int * p = &a;
b. 指针常量
指针的指向不可以更改,指针指向的值可以改
int a = 10;
int * const p = &a;
c. 同时修饰
均不可以修改
int a = 10;
const int * const p = &a;
记忆技巧 const和*的位置关系,修饰谁谁不可以修改 - 结构体 一些类型数据的集合的一个类型
struct 结构体名 {结构体成员列表};
struct Student{
string name;
int age;
int score;
}
struct 创建变量可以省略,定义不可以省略
三种创建变量方式
1、struct Student s1;
s1.name = "zhangsan";
s1.age = 18;
s1.socre = 100;
2、struct Student s2 = {"lisi", 19, 80};
3、struct Student{
string name;
int age;
int score;
}s3; 很少用
- 结构体数组
将自定义的结构体放到数组中方便维护
定义
struct 结构体名 {结构体成员列表};
struct Student{
string name;
int age;
int score;
};
创建结构体数组
struct Student stuarr[3] = {
{"12",18,50},
{"22",18,50},
{"32",18,50},
};
22、结构体指针
定义
struct 结构体名 {结构体成员列表};
struct Student{
string name;
int age;
int score;
};
struct Student stu1 = {"12", 18, 50};
& 取什么类型数据的地址,返回的就是什么类型
struct Student *p = &s;
通过结构体指针访问结构体中的属性,需要利用->
name = p->name;
23、结构体嵌套结构体
结构体中成员可以是另一个结构体
struct Student{
string name;
int age;
int score;
};
struct Teacher{
int id;
string name;
int score;
struct Student stu;
};
teacher T1;
T1.id = 1
T1.name = "hh"
T1.stu.name = "qq"
T1.stu.age = 20
T1.stu.score = 18
- 结构体做函数参数
- 值传递 .访问 形参改变,实参不变
- 地址传递 ->访问 形参改变,实参改变
- 结构体中const使用场景
结构体地址传递,节省内存空间
形参之前加入const,防止误修改 - 内存的分区模型
代码区 程序运行前
存放函数体的二进制代码,存放CPU执行的机器指令,共享,只读
全局区 程序运行前
全局变量 静态变量 常量,程序结束后由操作系统释放
const修饰局部变量变为局部常量也不在全局区
栈区 程序运行后
编译器自动分配释放 存放函数的参数值、局部变量
不要返回局部变量的地址
堆区 程序运行后
程序员分配释放 ,若程序员不释放,程序结束由操作系统回收
new int(10)
创建堆区数据,返回的是这个数据的地址即相应的指针
delete p
释放堆区数据,再访问会报错
new * arr = new int[10]
创建数组堆区
delete[] arr
释放数组
26. 引用 给变量起别名
int a = 10
int &b = a
注意事项
-引用必须要初始化
-引用一旦初始化后,就不可以更改了
-赋值操作不是更改引用
引用做函数参数
void Swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
}
int a = 10;
int b = 20;
Swap(a, b);
\\ 上面操作相当于int &a = a;给a起了个别名,函数中同样可以修改实参
引用做函数的返回值
-不要返回局部变量的引用 ,局部变量保存在栈区,函数结束会释放
-如果函数的返回值是引用,这个函数调用可以作为左值
引用的实质
本质:引用的本质在C++内部实现是一个指针常量
常量引用
作用:常量引用主要用来修饰形参,防止误操作
错误
int a = 10;
int &ref = 10;
正确
const int & ref = 10;
编译器替换为
int temp = 10;
const int & ref = temp;
主要应用
防止形参改变影响原始值
将形参变为 const int &val
- 函数提高
函数的默认参数
-如果函数从某个参数后为默认参数,之后的参数都必须为默认参数,和python一样
-如果函数声明有默认参数。函数实现就不能有默认参数,函数和声明中只能有一个默认参数
函数的占位参数
目前占位参数无用,之后会用到
占位参数还可以为默认参数
void func (int a, int){
cout << a <<endl;
}
func(10, 10);
void func (int a, int = 10){
cout << a <<endl;
}
func(10);
函数重载
函数名可以相同,提高复用性
满足条件:
-同一个作用域下
-函数名称相同
-函数参数类型不同,或者个数不同或者顺序不同
注意事项
-函数的返回值不可以作为函数重载的条件
-引用作为重载的条件
是否加const可以作为重载条件
-函数重载碰到默认参数,会出现二义性,避免出现这种情况
如果只传一个参数,编译器不知道调用哪个,如果传入两个则没有这种问题
- 类和对象
class 类名 {属性 行为}
访问权限
公共权限public 成员 类内可以访问,类外可以访问
保护权限protected 成员 类内可以访问,类外不可以访问 儿子可以访问父亲的保护内容
私有权限private 成员 类内可以访问,类外不可以访问 儿子不可以访问父亲的私有内容
29. struct和class的区别
struct默认权限是公共权限
class默认权限是私有权限
30. 成员属性设置为私有
-可以自己控制读写权限
-对于写可以检测数据的有效性
31. 对象的初始化和清理
构造函数和细够函数,自动由编译器调用,如果自己不写,编译器会提供,不过是空实现
构造函数的分类和调用
按照参数分类 无参构造(默认构造)和有参构造
按照类型分类 普通构造 拷贝构造 Preson(const Person &p)
(将传入的人身上所有的属性,拷贝到我身上)
调用
括号法
显示法
隐式转换法
拷贝构造函数的调用时机
-使用一个已经创建完毕的对象来初始化一个对象
-值传递的方式给函数参数传值
-以值方式返回局部对象
构造函数的调用规则
深拷贝和浅拷贝
浅拷贝是简单的赋值复制
析构函数可以定义堆区数据释放,而浅拷贝带来的问题就是堆区内存重复释放
深拷贝,自己申请堆区存储数据
初始化列表
类对象作为类成员
当其他类对象作为本类成员时,先构造其它类,在构造本类
析构时正好相反,先析构本类,再析构其它类
静态成员
-静态成员变量 不属于某一个对象上,所有对象都共享一份数据
通过对象来访问 通过类名进行访问
也是拥有权限的,设置为私有则类外无法访问
a所有对象共享同一份数据,b编译阶段就分配内存,c类内声明,类外初始化操作
-静态成员函数
a所有对象共享同一个函数 b静态成员函数只能访问静态成员变量(因为无法区分普通变量属于哪个创建对象,因为这个函数是共享的)
也有访问权限
两种访问方式
- 对象模型和this指针
空对象占用内存空间为1,为了区分空对象占内存的位置,每个空对象应该有一个独一无二的内存地址
成员变量和成员函数是分开存储的
计算对象占用内存大小时
非静态成员变量属于类的对象上,静态成员变量不属于类对象上,非静态成员函数也不属于类对象上,静态成员函数也不属于类对象上
this指针
this指针指向 被调用的成员函数 所属的对象
a 解决名称冲突 类内成员变量和构造函数的形参变量名称相同
b 返回对象本身 用*this (类似于python中的self??)
返回的值是一个对象则是新创建的一个对象,加上引用才是返回一个地址
空指针调用成员函数
const修饰成员函数 常函数
常函数内不可以修改成员属性
this指针的本质 是指针常量 指针的指向不可以修改
mutable 加入后可以修改
常对象 const修饰对象
常对象里面属性也不可以修改,除了加mutable修饰
常对象只能调用常函数
33. 友元
让一些特殊的类或函数可以访问私有属性
-全局函数做友元
在类中声明一下 friend 函数声明
-类做友元
在类中声明一下 friend 类
-成员函数做友元
在类中声明一下 friend 类::成员函数
34. 运算符重载
-加号运算符重载