一、C++中的指针与引用
第一节:指针与堆栈
- 注意空指针
- 指针的三种写法 *的位置随意
- int *pNumber
- int * pNumber
- int* pNumber
- 栈(存储本地变量和函数调用)
- local variables 函数调用
- 变量的生命周期由scope决定
- 堆
- 在运行时候分配内存
- 变量的生命周期完全由开发者决定,与scope无关
- new/delete(new:申请堆内存)(delete - 删除后建议直接复制nullptr -多次delete会使程序崩溃)
第二节:指针常见的错误
第一部分
- 之前说过指针所占内存大小都是8字节(32为4)指针指向堆和栈有所不同
- 指向栈
- 错误
- int *pNumber;\int *pNumber{nullptr};
- cout << *pNumber << endl;
- 尽量不要这样写
- int *pNumber;
- int n{13};
- pNumber = &n;
- 推荐
- int n{13};
- int *pNumber = &n;
- 错误
- 指向堆
- 推荐 int* pNumber{new int{13}}
int intValue{13}; int *pNumber{&intValue};
- 可以重新赋值已经被销毁的指针不用声明
- pNumber = new int(13);
- 但是不能dereferencing(*)(dereferencing 解引用)
- 可以通过if(!pNumber == nullptr)来判断该指针是否被销毁
- 内存泄露的错误
- 忘记delete
- 重新指向导致的内存泄漏
//错误 int *pNumber{new int{13}};//13泄漏 pNumber = new int(46); //正确 int *pNumber{new int{13}}; delete pNumber; pNumber = nullptr; pNumber = new int(46);
- 因为是指向堆上的指针 所以scope(作用域)过后不会销毁
{ int *pNumber{new int{13}}; }在scope后销毁13
- 推荐 int* pNumber{new int{13}}
- 指向栈
第二部分 堆上的动态数组与数组
- 栈上的数组:数组名是指向数组中第一个指针。可以通过p、(p+1)的方式来访问数组,即p[0],p[1]
- 如果想在堆上创建数组可以用double *pArray{new double[13]}{11, 2}
- 注意sizeof(pArray)的返回值为指针的长度: 8(与数组不同)
- 调用时候记得判断指针pArray是否为nullptr
- 动态数组销毁
- delete []pArray;
- 指针指向nullptr,很多安全攻击都是来源于此
- 动态数组不支持很多数组(栈数组)的操作
- std::size(c++17)
- auto等(堆上数组)
- 是否该考虑 #include<vector>
第三节:引用与指针
引用变量是别名,是某个已经存在变量的另一个名字
- 指针
- 指针
- 可以改变指向
- 必须通过解引用“*”来读取或写入数据
- 可以不初始化,即没有指向(不安全的本质)
- 引用(好处:1.必须初始化,比指针安全2.因为不需要解引用,比指针更好理解。坏处:不如指针强大(灵活))
- 不可以改变为其他值
- 不需要解引用“*”就可以读取和写入数据
- 必须初始化
- 指针
第四节:const与指针、引用
- 可以认为引用为不能改变自己指向的指针 double *const
- 指针与const(指针的两大操作空间:一个是重定向,一个是变换当前的值)
- double const*指向不可变与 double *const等价
- const double*指向值不可变 如果指向常量必须为该形式
- const double const 不可动 不可变
引用与const(const double& 相当于const double const)
第五节:函数与指针、引用
- 1.函数参数
- Pass by value(传值)
- Pass by pointer
- 指针可以改变原值,如果不想改变const int age
- 尽量用*const防止指针指向其他的值
- 写法诡异,尽量别用
- Pass by reference
- 可以修改原值 加const防止变化
- 推荐方式
- 2.函数指针
- 函数只是存在于程序的内存映射中某处代码中
- 当然可以通过获取函数的地址并将其存储在函数指针中
- 通过函数指针我们可以完成很多操作比方说回调(callback)
第六节:左值与右值
- 左值:左值可以获取地址并在以后使用的东西(左值可以获取地址可以不需要copy)
- 右值:右值本质上是暂时的临时变量,无法获取地址
–&& 可以存储右值(也不执行copy,性能更好)
参来自B站课程:【C++现代实用教程(一):基础主线(VSCODE)】https://www.bilibili.com/video/BV1S54y1Z7Wc?p=26&vd_source=4fb2ce08dedc1f6f164f004d4410ec10
源码:https://github.com/qylmumu2/Course_study.git