| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> c++:函数中的指针与引用 -> 正文阅读 |
|
[C++知识库]c++:函数中的指针与引用 |
????????为了搞清楚一个变量的生存周期花上大量的时间,为了查找一个反复被delete的指针变量而苦苦烦恼,如果是java或者py这些痛苦都不复存在,但是指针与引用起码关于指针与引用这一块都没有搞清楚,那么我用cpp写代码的意义何在?于是,我花了大量时间把指针与引用本质的东西问到底!c++付出大量的学习代价,我想这也是其无所不能的原因,因为难,所以无可代替! 本期我们详细讲解指针与引用在函数中的应用与对比。 一、关于指针与引用1、指针(1)众所周知,指针对应着指针本身(本文简称指针)与指针变量,指针是存指针变量的地址,而指针变量就是指针所指向的值。指针存储于栈区,而指针变量在堆区中开辟空间。
输出如下: ?(2)指针是变量,需要在内存中开辟一块空间进行存储,可以无初值,如下所示,不会报错:
(3)注意常量指针与指针常量的区分,指针常量指指针本身无法改变,而其对应的指针变量可以修改,而常量指针则指针可以修改,而其对应的指针变量无法修改,如下: 2、引用?(1)基本概念:引用&即别名,是c++的一层语法糖(其实与指针实现机理基本一样),这样可以使用原始数据而不是数据副本,节约大量副本拷贝的时间。 1)声明时必须初始化,否则报错: 2)注意声明&引用符号与取地址&的区别:
3)不能引用常量,只能引用变量: (2)本质:常量指针即 int const*(假定为int类型),因此其与初始化对象自始至终都绑定在一起,无法令引用重新绑定到另外一个对象上 (3)右值引用与左值引用: 左值:有存储地址与变量名 右值:既无存储地址又无变量名
具体定义如下:详细了解,可看左值引用与右值引用
二、引用与指针在函数中如何选择1、选择基本基本原则???能用引用尽量用引用,引用优先原则,具体理由如下: (1)引用必须初始化,否则编译无法通过,而空指针可以编译阶段,在运行阶段往往造成程序的崩溃; (2)引用不是变量(是另外一个变量的别名),指针是变量,后者需要占用一定的存储空间,当然这是废话了,因为指针所占用那点空间相对于程序来说简直九牛一毛。 2、函数形参中的指针本文拿交换函数进行举例:
????????实际上,交换成功的只有交换函数2,第一个交换的局部函数里面的地址,其空间是在栈区开辟的,其生存周期仅次于swap1函数,所以实参无任何改变,而第二个交换的是指针变量(在堆区开辟),当然成功。同理,第三个的结果就是a与b的值都一样。输出结果如下: ? ? ? ? 因此:指针作为函数的参数,可以修改指针地址指向的值,并且能够正确返回,但是无法通过直接修改指针的地址来改变指针的返回,因为指针参数当中,指针的地址是值传递,无返通过修改值传递得到正确返回。如果想通过修改指针的地址来修改指针的返回结果,需要通过引用传递,则必须将指针改为指针的引用作为函数参数,如void test3(*& p)函数一样。 ?通过引用交换地址来达到交换变量值得目的,例子如下:
3、函数形参中的引用? ? ? ? 引用用起来显得舒服很多,因为只是一层语法糖,与值传递一样的用法缺达到形参与实参同步的效果:
? ? ? ? 另外,采用引用作为形参避免了临时变量(也就是平时所说的副本)的拷贝,这在面向对象中尤为重要,避免了大量重复的复制拷贝构造函数的时间浪费,如下所示:
? ? ? ? 如果不希望对实参的值进行修改,形参声明为const是一个比较好的习惯,这在很多经典的教材里面被反复提到。 ? ? ? ? 从上可以看出,选择引用比指针可避免犯大量的错误,可避坑 三、指针与引用作为返回值:1、指针作为返回值过于简单不多说,直接上代码,道理全在代码里面:
输出结果如下: ?注意返回的是一个临时变量(右值),但是不能返回局部变量的地址,否则就会变成空指针,如下: ?本文采用的是G++编译器,返回的是空指针,当然在msvc处理可能与此结果不太一致。 ?2、引用作为返回值(1)首先不能返回局部变量的引用
????????会发现输出的为空字符串,当函数执行完毕,程序将释放分配给局部对象的存储空间。此时,对局部对象的引用就会指向不确定的内存。 (2)返回引用与返回值得区别:函数返回值时会产生一个临时变量作为函数返回值的副本,而返回引用时不会产生值的副本,返回引用极大提高性能:
结果对比:引用完胜 (3)当引用作为参数时,可返回引用的参数:
同时,引用作为参数参数可避免了临时变量的拷贝,极大了提高时间性能,这一点上一节以及提到 (4)返回引用可以当做左值使用,最经典的应用就是面向对象中运算符的重载,例如“a=b=c”这种链式编程思想是通过引用来进一步实现的:
(5)引用可当左值使用,如果不希望改变返回值可以定义为const int &abc(int a, int b, int c, int &result):
3、返回值选择引用还是指针?????????如果可以选择,则通常更倾向于使用引用而不是指针,因为这样可以降低程序偶然发生内存崩溃的概率。只有在管理那些需要对指针进行操作的对象时(创建、销毁或者添加到一个托管容器中),才会选择使用指针,并且,通常可以将这些例程封装为成员函数。 ? ? ? ? 但是引用不能为空,如果可能存在空对象时,应考虑使用指针。当一个类中包含引用成员时,这个类就无法使用语言生成的默认构造函数,拷贝构造函数和赋值函数。这是因为引用不能为空(必须初始化),必须在构造函数中为引用成员赋值,语言默认生成的函数不具备这个功能。默认构造函数在C++中时非常重要的概念,特别是在使用STL时,因此为了默认构造函数,必须摒弃引用成员变量。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 | -2025/3/4 13:22:25- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |