C++(9)--裸指针、智能指针、引用

指针

  • 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 输出时是4033

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/444842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于valgrind的安装和内存泄露分析

程序的安装 如果使用的是tar包安装. valgrind # wget http://valgrind.org/downloads/valgrind-3.9.0.tar.bz2 # tar -jxvf valgrind-3.9.0.tar.bz2 # cd valgrind-3.9.0 # ./autogen.sh # ./configure # make; make install 使用命令: valgrind --tool=memcheck --leak-…

关于mysql的cpu占用高的问题

现在游戏开了泰服 ,发现泰服的cpu占用率总是比繁体或者大陆的高很多,每次都是占用了300%多 top - 15:34:06 up 222 days, 2:51, 2 users, load average: 0.75, 0.73, 0.66 Tasks: 215 total, 1 running, 214 sleeping, 0 stopped, 0 zombie Cpu(s): 52.4%us, 8.5%…

网络原理知识点汇总

OSI七层模型 vs. TCP/IP 五层模型&#xff08;有时候也说四层&#xff09;及各层协议 七层&#xff1a;物理层&#xff1a;为数据端设备提供传送数据的通路&#xff0c; IEEE802 数据链路层&#xff1a;提供介质访问和链路管理&#xff0c; ARP&#xff0c;MTU 网络层&#xf…

无限踩坑系列(8)--猿界神猿

计算机一句话冷知识1.GNU2. Unix与C语言3. Linux与git-hub4. c/c 编译器5. python1.GNU GNU是一个自由的操作系统&#xff0c;其内容软件完全以GPL方式发布。 GNU&#xff1a;GNU’s Not Unix!的递归缩写 Unix 商业化之后&#xff0c; RMS发起了GNU计划&#xff0c;在该计划下…

C++实现md5加密或计算文件的唯一性识别

由于网络上传了很多关于C实现md5加密的类&#xff0c;至于那个是原创&#xff0c;我不敢妄加猜测&#xff0c;只是这里我声明我是转载的&#xff0c;并支持原创。 对于md5加密算法&#xff0c;我提供两文件&#xff1a; #ifndef MD5_H #define MD5_H #include <string>…

Crontab的格式

第1列分钟1&#xff5e;59 第2列小时1&#xff5e;23&#xff08;0表示子夜&#xff09; 第3列日1&#xff5e;31 第4列月1&#xff5e;12 第5列星期0&#xff5e;6&#xff08;0表示星期天&#xff09; 第6列要运行的命令 下面是crontab的格式&#xff1a; 分 时 日 月 星期 要…

leetcode516 最长回文子序列

给定一个字符串s&#xff0c;找到其中最长的回文子序列。可以假设s的最大长度为1000。 示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 "bbbb"。 示例 2: 输入: "cbbd" 输出: 2 一个可能的最长回文子序列为 "bb"。 …

C++(10)--动态分配内存new,程序的内存分配

动态分配内存1. 动态分配内存1.1使用new分配内存1.2使用delete释放内存1.3使用new创建动态分配的数组2. 程序的内存分配3.数组与指针案例实践4.二维数组与指针《老九学堂C课程》《C primer》学习笔记。《老九学堂C课程》详情请到B站搜索《老九零基础学编程C入门》-------------…

社交app应用开发 客户端+服务器源码

原帖地址&#xff1a;http://www.devdiv.com/iOS_iPhone-想学习移动社交APP的童鞋有福了&#xff0c;图文展示&#xff0c;附客户端&#xff0c;服务端源码。-thread-121444-1-1.html 想学习移动社交APP的童鞋有福了&#xff0c;图文展示&#xff0c;附客户端&#xff0c;服务…

leetcode83 删除排序链表中的重复元素

给定一个排序链表&#xff0c;删除所有重复的元素&#xff0c;使得每个元素只出现一次。 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3 思路&#xff1a;判断下一个是否相同即可。 /*** Definition for singl…

tcpdump的用法

第一种是关于类型的关键字&#xff0c;主要包括host&#xff0c;net&#xff0c;port, 例如 host 210.27.48.2&#xff0c;指明 210.27.48.2是一台主机&#xff0c;net 202.0.0.0 指明 202.0.0.0是一个网络地址&#xff0c;port 23 指明端口号是23。如果没有指定类型&#xff0…

关于NFS服务器的原理总结和mount挂载

NFS 是Network File System的缩写,即网络文件系统。一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布。功能是通过网络让不同的机器、不同的操作系统能够彼此分享个别的数据,让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是在类Unix系统间实现磁…

leetcode203 移除链表元素

删除链表中等于给定值 val 的所有节点。 示例: 输入: 1->2->6->3->4->5->6, val 6 输出: 1->2->3->4->5 思路&#xff1a;就删呗&#xff0c;注意第一个数可能会被删 /*** Definition for singly-linked list.* public class ListNode {* …

不需要安装max或者xcode的object C开发环境

有时候很多人在没有mac开发机的时候&#xff0c;都想着安装一个虚拟mac机&#xff0c;或者用codeblock去配置成一个OC开发环境&#xff0c;我之前在学习OC的时候就这么办过&#xff0c;虚拟机卡的要死&#xff0c;codeblock本来就不是专门用来做OC开发的&#xff0c;还要自己弄…

leetcode338 比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i &#xff0c;计算其二进制数中的 1 的数目并将它们作为数组返回。 示例 1: 输入: 2 输出: [0,1,1] 示例 2: 输入: 5 输出: [0,1,1,2,1,2] 进阶: 给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可…

C++(11)--编程实践1-经典养成类游戏简单实践

经典养成类游戏简单实践-小公主养成记《老九学堂C课程》学习笔记。《老九学堂C课程》详情请到B站搜索《老九零基础学编程C入门》-------------简单的事情重复做&#xff0c;重复的事情用心做&#xff0c;用心的事情坚持做(老九君)---------------致敬&#xff1a;日本Gainax公司…

关于房屋的风水学整理

第一步&#xff1a;看缺角&#xff0c;根据户型图的整体形状分析有无缺角户型的形状很多&#xff0c;有三角形的&#xff0c;手枪形的&#xff0c;锯齿型的等等&#xff0c;总的来说缺角就不好&#xff0c;方方正正好&#xff0c;适合“天方地圆”。如下图什么是缺角&#xff0…

房屋凶吉位判断

房屋的吉凶位按八宅来判断比较适合自身简易的操作&#xff0c;但每个房屋&#xff0c;都是既有共性&#xff0c;也有个性的&#xff0c;具体的吉凶方位的判断&#xff0c;可能要用到家中每个人的年命、运程&#xff0c;房屋周边的山水形势及地理环境要素。这些内容&#xff0c;…

leetcode226 反转二叉树

翻转一棵二叉树。 示例&#xff1a; 输入&#xff1a; 4 / \ 2 7 / \ / \ 1 3 6 9 输出&#xff1a; 4 / \ 7 2 / \ / \ 9 6 3 1 备注: 这个问题是受到 Max Howell 的 原问题 启发的 &#xff1a; 谷歌&#xff1a;我们90&#xff05;的…