C++新手村教学

  • 引用
    • 引用特性
    • 使用场景
    • 传值与传引用效率比较
    • const常引用
    • 引用与指针的区别

引用

类型& 引用变量名(对象名) = 引用实体;

首先我们看一个简单的程序:

#include <iostream>
using namespace std;
int main()
{int a = 1;int& b = a;cout << a << " " << b;return 0;
}


我们在 int 类型的后面接上了 & 符号,这个就代表引用。(&符号接在变量前面就叫取地址比如:int* b =&a )

那么引用是什么意思呢?
引用就是别名,比如孙悟空它就有很多别名,比如:美猴王、悟空、弼马温、齐天大圣都是它的名字,也都代表是孙悟空这个人物。

在Java中引用完全替代了指针,而在C++中没有完全替代指针,只是方便去替代(指针)做一些事情

如果我们要实现一个单链表,那么我们有了引用我们就可以这样:

某些算法书还会出现这样的我们以前没学引用所看不懂的代码:

引用特性

  1. 引用在定义时必须初始化
    我们不能写下面这种代码:
    int& ra ;
    “没有初始化,直接写一个引用”
  2. 一个变量可以有多个引用
int main()
{int a = 1;int& b = a;int& c = a;int& d = c;return 0;
}
  1. 引用一旦引用一个实体,再不能引用其他实体
    意思就是我们已经int& ra = a;
    那么就不能更改ra引用的对象(int& ra = b;这样是不允许的)

使用场景

  • 做参数
void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}

输出型参数

  • 做返回值

我们来看看下面的代码:

注意:

  1. 函数运行时,系统需要给该函数开辟独立的栈空间,用来保存该函数的形参、局部变量以及一些寄存器信息等
  2. 函数运行结束后,该函数对应的栈空间就被系统回收了
  3. 空间被回收指该块栈空间暂时不能使用,但是内存还在;

    为什么会返回的是临时变量?

    由上面图我们可以知道,我们返回的值是之前值的一份临时拷贝,在出Count函数栈帧在外面定义的临时变量。

这个临时变量如果比较小,可能在寄存器里面创建,如果比较大,那么就在上一层栈帧找个位置提前开辟好
如果是引用返回的话:

但是如果n不是存放在静态区,而是栈里面会怎么样?

这个代码就是有问题的!!!

内存销毁意味着什么?
1.空间还在吗? 空间还在,只是使用权不是我们的,我们存的数据不被保护
2.我们还能访问吗?能,只是我们读写的数据都是不确定的
(空间的申请和释放,就像是住酒店,退房了房间还在,只是不属于我们使用了,但是我们偷偷仿制一把钥匙还是能进入。空间读写数据,就像是我们丢下房间里面的东西,如果我们退房了,我们偷偷进去找,东西可能被打扫了,也可能下一任租客拿走了,东西还在不在是不却确定的)

结论:
出了函数作用域,返回变量不存在了,不能用引用返回,因为引用返回的结果是未定义的。
出了函数作用域,返回变量存在,才能用引用返回

传值与传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低

  1. 以值和引用的作为返回值类型的性能比较
#include <time.h>
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; }
// 引用返回
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{// 以值作为函数的返回值类型size_t begin1 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc1();size_t end1 = clock();// 以引用作为函数的返回值类型size_t begin2 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc2();size_t end2 = clock();// 计算两个函数运算完成之后的时间cout << "TestFunc1 time:" << end1 - begin1 << endl;cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{TestReturnByRefOrValue();return 0;
}


传引用返回作用:

  • 减少拷贝,提升效率
  • 修改返回值

关于修改返回值,我们可以通过以前C语言的顺序表实现来了解
我们修改顺序表实现的SeqListModify

头文件:
size_t SLSize(SeqList* psl);
SLDataType& SlAt(SeqList* psl, size_t pos);
实现:
size_t SLSize(SeqList* psl)
{assert(psl);return psl->size;
}
SLDataType& SlAt(SeqList* psl, size_t pos)
{assert(psl);assert(pos < psl->size);return psl->array[pos];
}
int main()
{SeqList sl;SeqListInit(&sl);SeqListPushBack(&sl, 1);SeqListPushBack(&sl, 2);SeqListPushBack(&sl, 3);SeqListPushBack(&sl, 4);// 偶数*2;for (size_t i = 0; i < SLSize(&sl); ++i){if (SlAt(&sl, i) % 2 == 0){SlAt(&sl, i) *= 2;}}for (size_t i = 0; i < SLSize(&sl); ++i){cout << SlAt(&sl, i) << endl;}SeqListDestory(&sl);return 0;
}

  1. 以值和引用作为函数参数的性能比较
#include <time.h>
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{A a;// 以值作为函数参数size_t begin1 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作为函数参数size_t begin2 = clock();for (size_t i = 0; i < 1000000; ++i)TestFunc2(a);size_t end2 = clock();// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{TestRefAndValue();return 0;
}


引用做参数:

  • 减少拷贝,提供效率
  • 输出型参数,函数中修改形参,实参也修改了

const常引用

一般情况引用做参数都是用const引用
指针和引用赋值中权限可以缩小,但是不能放大

比如我们可以这样使用:
int a = 1;(a是可读可改)
int& ra = a;(ra也是可读可改)这是权限平移

const int b=2;(b只能读)
int& rb = b;(rb变成可读可改)权限放大,是错误的
const int& rb = b;(这样就能正常使用,变成只能读)

int c = 3; (可读可改)
const int& rc = c;(只能读)权限缩小,是正确的





下面这种情况也是典型的临时变量具有常性的例子:

引用与指针的区别


引用与指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

小白看了直呼细节--CPP“引用”相关推荐

  1. java开发crm框架_这可能是2020年度最完整、详细的Java高级框架+CRM课程哟,小白看完直呼过瘾!...

    001_SpringMvc学习目标+MV核心思想 002_MVC框架对比+SpringMvc框架特点 003_SpringMvc内部请求流程解析 004_SpringMvc环境搭建与测试 005_Sp ...

  2. 一天实现用poi-tl导出word(饼图/柱状图、文字、表格、循环word),男朋友看完直呼好家伙

    用一天的时间实现了要求的word的导出,包含表格.饼图.文字.柱状图,男朋友直竖大拇指,非让我给他讲,学会以后直呼抱大腿,害,这无处安放的优秀. 想研究的可以自己看一下接口文档 Poi-tl Docu ...

  3. 一篇文章让你彻底了解什么叫Netty!大牛看了直呼内行!

    作者:java蜜蜜 链接:https://www.jianshu.com/p/1369b30b9f99 一.Netty到底是什么 1.从HTTP说起 有了Netty,你可以实现自己的HTTP服务器,F ...

  4. 《大厂面试》面试官看了直呼想要的简历

    你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和 ...

  5. 四种代码洁癖类型,程序员看了直呼内行

    很多程序员在写代码的时候 都有自己的独特的习惯 比较典型的就是"代码洁癖" 他二哥收集了一些代码洁癖症状 分了四个类型 来看看有没有你对应的吧 看到大家都如此极致的追求, 他二哥实 ...

  6. python判断奇偶数vscode_安利一波VSCode【vscode这样配置 戴夫看了直呼内行】

    之前一直用vs2017写C#,最近转到vscode,发现生产力真的高很多,而且又能写python 又能写C#,真的很香 新人发帖,如有违规,请版主直接删帖 插件: ms-ceintl.vscode-l ...

  7. 四种代码洁癖类型,程序员看了直呼内行(文末经典书送)

    很多程序员在写代码的时候 都有自己的独特的习惯 比较典型的就是"代码洁癖" 我收集了一些代码洁癖症状 分了四个类型 来看看有没有你对应的吧 一.极简断舍离型 二.距离产生美型 三. ...

  8. 恐龙的丁丁长什么样?它们是怎么啪啪啪的?这项研究网友看完直呼涨姿势.........

    全世界只有3.14 % 的人关注了 爆炸吧知识 地球霸主的私生活 也藏不住了 昨天下午,超模君码字码得累了,决定放松一下,重温一下经典的<侏罗纪公园>. 当看到恐龙在平原上成群奔跑的画面时 ...

  9. java scanner以回车结束_大佬看了直呼内行,你当初Java刚入门是否也是这样写代码?...

    1.集成开发环境 IDEA是一个专门针对Java的集成开发工具(IDE),由Java语言编写.所以,需要有JRE运行环境并配置好环境变量.它可以极大地提升我们的开发效率.可以自动编译,检查错误. 2. ...

最新文章

  1. Visual C# .NET 2003 语言的改变
  2. try catch finally
  3. PYTHON -MYSQLDB安装遇到的问题和解决办法
  4. linux整理笔记之六:samba软件包使用
  5. 初级测试开发面试题_初级开发人员在编写单元测试时常犯的错误
  6. css的三个特性 背景透明设置
  7. Linux 驱动编译报错:error: macro __DATE__ might prevent reproducible builds [-Werror=date-time]
  8. 计算机能力提升研修总结ppt,信息技术能力提升研修总结
  9. JavaScript基础修炼(14)——WebRTC在浏览器中如何获得指定格式的PCM数据【华为云分享】
  10. HDU 4334 5-sum
  11. IT成长中的龟兔赛跑
  12. oracle中文谐音,Treasure的歌词中文翻译?? bruno mars 唱的treasure中文歌词谐音 谁懂啊?帮......
  13. android mtklog,Mtklog结构及分析
  14. pdf2Image Pdf文件存为jpg NodeJs实现
  15. Web Polygraph 安装
  16. 质数 素数 合数 因子
  17. 简历javaweb项目描述怎么写_JavaWeb开发简历项目经验怎么写
  18. 安徽大学计算机学院张静,安徽大学2011年国家励志奖学金获奖学生名单
  19. BZOJ3786: 星系探索(伪ETT)
  20. 网页制作存在的一些难点

热门文章

  1. 线程、多线程、线程池总结
  2. snmp连接工具_运维工程师不可错过的2020年值得关注的综合性网络监控工具
  3. [双板滑雪]教学视频和技术贴精选
  4. FIFA 世界杯 2022 电视直播观战私家指南
  5. 自主移动机器人常用的导航定位技术及原理
  6. obv代码matlab,通达信精进终极obv指标公式,通达信obv指标公式源码
  7. leetcode解题思路分析(一百三十)1093 - 1096 题
  8. 分享——网页上的虚拟机
  9. 12月14日:跟着猫叔写代码api中的增删改查
  10. OCX控件全屏、恢复