指针

  • 1.裸指针的基本概念
    • 1.1 裸指针的声明*/初始化&
    • 1.2 操作裸指针--间接运算符*
    • 1.3 裸指针使用 demo--指向一个简单变量
    • 1.4 空指针--nullptr
    • 1.5 特殊指针--void *ptr
  • 2.指针和引用--引用定义&
  • 3.指针和数组
    • 3.1 数组指针的定义
    • 3.2 数组指针递增/递减操作
    • 3.3 指针与数组使用的一些注意点

《老九学堂C++课程》《C++ primer》学习笔记。《老九学堂C++课程》详情请到B站搜索《老九零基础学编程C++入门》
-------------简单的事情重复做,重复的事情用心做,用心的事情坚持做(老九君)---------------

1.裸指针的基本概念

指针是一个值为内存地址的变量(数据对象)。也就是说指针它一样是一个变量,只不过该变量中存放的是另一个对象的内存地址,存放另一个对象的地址的操作又叫指向了该对象。
裸指针相对于智能指针而言,智能指针的使用详见part 5

  1. 变量名–地址的助记符, 指针–存放内存地址

  2. 定义指针时不赋初值,该指针叫野指针。强烈建议初始化所有指针/尽量等定义了变量之后再定义指向它的指针.

  3. 指针指向的对象可以改变(可以通过赋值–去地址符号改变指针的内容)

  4. 指针类型与指向对象的类型匹配

  5. 裸指针需要手动释放,否则会造成内存泄漏

1.1 裸指针的声明*/初始化&

裸指针声明 --仅声明不初始化的指针是非常不安全的,所以推荐声明完就初始化。

数据类型 * 指针变量名     // 定义一个指向(数据类型)变量的指针
int *ptr_num;
int *ptr_name;
int *money_ptr;
double *p_price;

注意:星号靠前靠后都是定义指针型变量,建议靠后结合知名该变量是指针。

int* a,b,c; //只有a为指向int 类型变量的指针,b、c是一般的int 型变量
int *a, *b, *c; //定义了3个指向int 类型变量的指针

裸指针初始化–取地址符号&,取变量的地址赋值给指针变量

int year;
year = 2021;       // year 对应的变量块中存放数2021
int *ptr_year;     // 声明一个指针变量
ptr_year = &year;  // 将变量year的地址出来赋给指针变量,我们说的是ptr_year指向了year这个变量

1.2 操作裸指针–间接运算符*

操作裸指针–间接运算符*
间接运算符*作用于指针变量,取变量中的地址,然后对该地址对应的内存空间进行操作

int num = 1024;
int *ptr_num;
ptr_num = \#
*ptr_111;  //等价于 num = 111;

注意:指针声明之星号 和 间接运算符之星号 的作用完全不同

1.3 裸指针使用 demo–指向一个简单变量

int main(){double num = 1024.5;double *ptr_num = &num;cout << "ptr_num 的值: " << ptr_num << "\t" << &num << endl;cout << "ptr_num指向空间的值: " << *ptr_num << endl;return 0;
}

输出:

ptr_num 的值: 0x7ffee273f630   0x7ffee273f630
ptr_num指向空间的值: 1024.5

demo2:字符指针在输出时候的注意事项

int mian(){char ch = 'a';char *ptr_ch = &ch;// 默认以字符串的方式打印字符(char 型指针被默认为带有间隔操作符号)       cout << ptr_ch << "\t" << *ptr_ch << endl;// 强制转换成字符型指针(输出地址,void * 任意的地址类型)cout << (void * )ptr_ch << "\t" << *ptr_ch << endl;return 0;
}

1.4 空指针–nullptr

空指针: 不指向任何对象指针。
作用: 初始化指针,避免出现野指针。
提示: 在使用一个指针前可以检查它是否为空。


int *ptr1 = nullptr;        // c++ nullptr 字面值常量 =0, 可以被转换成任何类型的指针
int *ptr2 = 0;# include <cstdlib>        // c 语法空指针
int *ptr3 = NULL

1.5 特殊指针–void *ptr

一种特殊的指针类型,可以存放各种类型变量的地址

注意1:void *指针不能用来访问地址所指向的对象(即用* 取地址对应的内容)
void 使用技巧: 和别的指针比较、作为函数的输入输出、赋值给另一个void 指针

void 指针使用示例

int main(){// void 指针double objNum = 3.14;double *ptr_obj = &objNum;void *vptr_obj = &objNum;cout << (vptr_obj == ptr_obj) << endl;return 0;
}

2.指针和引用–引用定义&

引用:对象的一个别名,引用访问变量时直接用引用名就可以了,不需要和指针一样用*。

引用的定义

int int_val = 1024;
int& refValue = int_val; # 定义了变量int_val的引用refValue

引用的使用 :和所有的一般变量一样使用即可

int num = 108;
int& rel_num = num;
rel_num = 118;               // 直接使用引用对变量赋值
cout << &num << '\t' << &rel_num << endl;
// 输出 操作的是同一块内存空间,在使用数组或者对象的引用时,才会凸显其优势
0x7ffee750f60c  0x7ffee750f60c

常量引用: 一般情况下常量的引用是错的,但是如果一定要定义一个常量的引用给可以使用const

double ref = 100.0;//❌
const double ref = 100.0;//☑️

引用和指针的关系

  1. 引用是对指针的简单封装,底层仍然是指针。
  2. 引用在获取地址时,编译器内部会进行* 操作。
  3. C++提倡使用引用,而少用指针
  4. 引用的优势-效率更高。指针赋值时的取地址符号&会验证地址的有限性(编译器内部机制?)而引用不需要,所以引用使用起来效率更高。

注意事项:

  1. 引用只能绑定在对象上,不能与字面值或者某个表达式的计算结果绑定在一块。
  2. 引用都必须初始化,所以引用使用之前不需要测试其有效性。

3.指针和数组

数组数据是一块连续的内存地址,数组名就是这块连续内存空间的首地址

3.1 数组指针的定义

int main(){double score[] = {11, 22, 33, 44, 55};double *ptr_score = score;    // 指向数组的指针,不需要取地址符号cout << sizeof(score) << '\t' << sizeof(ptr_score) << endl;cout << ptr_score[2] << endl;    // 数组指针可以像数组名一样使用下标操作数组return 0;
}
// 输出
40      8          # 数组名对应的数据类型为double[5] 用sizeof 输出时是40位
33

3.2 数组指针递增/递减操作

指针的++,–被视为指针的移动操作,移动下一个/上一个基本单位

int main(){double score[5] = {98, 87, 65, 43, 76};double *ptr_score = score;for(int i = 0; i < 5; i++){cout << *ptr_score++ << endl;        // }return 0;
}

3.3 指针与数组使用的一些注意点

int num[50]; //num数组名,也可以理解成数组的首地址
// num的值和&num[0] 的值一致
// 数组第i+1个元素地址可以表示为:&num[i+1] num + i + 1
// 数组第i+1个元素可以表示为: num[i+1] 或者 *(num+i+1)
// 为指向数组的指针赋值
int *ptr_num = num;
int *ptr_num = &num[0];
//指针变量也可以指向数组元素
int *ptr_num = &num[4]
int *ptr_num = num + 4

C++(9)--裸指针、智能指针、引用相关推荐

  1. android ndk 智能指针,智能指针与弱引用详解

    在android 中可以广泛看到的template class Sp 句柄类实际上是android 为实现垃圾回收机制的智能指针.智能指针是c++ 中的一个概念,因为c++ 本身不具备垃圾回收机制,而 ...

  2. 野指针 空指针 悬空指针 智能指针

    C语言中"野指针"."悬空指针"是什么? C语言中"野指针"."悬空指针"是什么?_不脱发的程序猿的博客-CSDN博客_ ...

  3. VTK修炼之道80:VTK开发基础_智能指针与引用计数

    1.引用计数 VTK经过多年的开发与维护,已经形成了一套稳定的框架和开发规则.因此,了解这些规则和框架是定制VTK类的基础,这其中用到了大量面向对象的设计模式,例如对象工程模式.观察者/命令模式:还有 ...

  4. 【C++】智能指针(auto_ptr,shared_ptr,unique_ptr)及 shared_ptr 强引用原理

    C++智能指针(Smart Pointer) 传统指针存在的问题 auto_ptr 智能指针的简单自实现 shared_ptr shared_ptr 内存销毁的原理(强引用) shared_ptr 的 ...

  5. c++string 加引号_C++|引用计数与shared_ptr智能指针(以实现String类为例)

    C++ 中,动态内存的管理是通过一对运算符来完成的,new 用于申请内存空间,调用对象构造函数初始化对象并返回指向该对象的指针.delete接收一个动态对象的指针,调用对象的析构函数销毁对象,释放与之 ...

  6. 五点讲述C++智能指针的点点滴滴

    (在学习C/C++或者想要学习C/C++可以加我们的学习交流QQ群:712263501群内有相关学习资料) 0.摘要 本文先讲了智能指针存在之前C++面临的窘境,并顺理成章地引出利用RAII技术封装普 ...

  7. 【Smart_Point】C/C++ 中智能指针

    C++11智能指针 目录 C++11智能指针 1.1 C++11智能指针介绍 1.2 为什么要使用智能指针 1.2.1 auto_ptr(C++98的方案,C++11已经抛弃)采用所有权模式. 1.2 ...

  8. boost any 实现万能容器_全面剖析 C++ Boost 智能指针!| CSDN 博文精选

    作者 | .NY&XX 责编 | 屠敏 出品 | CSDN 博客 为什么要使用智能指针 C++没有提供类似JAVA的垃圾回收机制,因此Boost可以通过智能指针来管理内存避免一些问题.C++继 ...

  9. 全面剖析 C++ Boost 智能指针! | CSDN 博文精选

    作者 | .NY&XX 责编 | 屠敏 出品 | CSDN 博客 为什么要使用智能指针 C++没有提供类似JAVA的垃圾回收机制,因此Boost可以通过智能指针来管理内存避免一些问题.C++继 ...

  10. C/C++编程:智能指针

    计算机系统中的资源有很多种,内存是我们最常用到的,此外还有文件描述符,socket.操作系统handler,数据库连接等,程序里申请这些资源之后必须及时归坏系统,否则就会产生难以预料的后果 std:: ...

最新文章

  1. vue 强制刷新组件
  2. mysql获取当前时间,前一天,后一天(执行效率比较高)
  3. OpenGL ES之GLKit的使用功能和API说明
  4. 使用GoLand创建并运行项目
  5. usb接口linux系统设计,AUFS 联合文件系统 - 基于USB接口的微型桌面Linux系统设计
  6. php和windows对应,哪个.so文件可以用于windows系统中与.dll文件相对应的linux系统,以便将php连接到ms sql server...
  7. java 过滤js事件_java中的过滤器与监听器
  8. windows分辨率修改工具_3个修改图片DPI的方法
  9. 西门子PLC usb编程电缆驱动
  10. 联想服务器bios中文显示,联想bios怎么设置中文显示
  11. ant design中Button与button点击事件
  12. js神秘的电报密码---哈弗曼编码
  13. VIJOS-P1626 桐桐的糖果计划
  14. linux批量追加内容,利用sed的追加功能批量在文件中追加内容
  15. 古训《增广贤文》补遗
  16. 青年在选择的职业时的思考
  17. 什么软件可以翻译英语文章?文本翻译软件大分享
  18. DDD为什么能火起来?DDD 与微服务到底是啥关系!
  19. BATH围猎新基建,后浪“TMD”集体缺席
  20. 《黑客攻防技术宝典:Web实战篇》习题答案(三)

热门文章

  1. string也可以很精彩
  2. argis中4波段影像变3波段
  3. 【转】tftp命令详解
  4. 【转】How to install VNC server on ubuntu 14.04
  5. 【转】Microsoft Teams快速上手系列-01Teams的前世今生
  6. 【转】Dynamics 365Online 如何启用手机端APP的离线功能
  7. ASP.NET Core管道深度剖析(1):采用管道处理HTTP请求
  8. TPL 和传统 .NET Framework 异步编程
  9. 任务调度开源框架Quartz动态添加、修改和删除定时任务
  10. 软件测试计划时要记住什么