【C++】引用与指针_c+,2024年最新Golang码农是如何进入腾讯的

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

引用的特性
  1. 引用在定义时必须初始化

  2. 一个变量可以有多个引用,但一个引用只能有一个实体对象

#include
using namespace std;
int main()
{
int a = 0;
//一个变量可以有多个引用,但一个引用只能有一个实体
int& b = a;//不可以写成int& b; 引用必须在定义时初始化
int& c = b;
int& d = c;

cout << &a << endl;//012FFBD0
cout << &b << endl;//012FFBD0
cout << &c << endl;//012FFBD0
cout << &d << endl;//012FFBD0
//地址相同,abcd共用同一块空间
// 另外,引用类型与引用实体的类型必须一致,这里不能写为char & d = a(error)
return 0;
}

扩展(函数栈帧的创建与销毁)

这里我们进行复习一下关于函数栈帧的一些知识。我们知道,在调用一个函数时,
首先会在内存占用一块空间,用来创建该函数的函数栈帧,当调用结束后,该函数栈帧会被销毁,这里需要注意的是,当
栈帧被销毁后,这里的空间实际上在内存中还是存在的,只不过空间的使用权不再归我们使用。
并且函数栈帧的销毁,可能会对原有空间进行清理。

这里可以举个例子来理解一下,就好比说我们在酒店开了一个房间,并且在退房时把我们的电脑放在了房间里,在这里,酒店就相当于内存的存在,而我们退房的那一刻,就好比
函数栈帧销毁的那一刻,但是虽然我们退房了,该房间还是实际存在的,并没有说随着我们的退房而消失,只不过不再归我们使用。并且房间里的东西也
可能会被清理(也可能依然还在),加入此时我们再进行使用该房间,用是可以用,只不过肯定是不合法的,这种行为就好比
空间的非法访问。

引用的使用场景

做参数进行引用(输出型参数)

所谓输出型参数,实际上就是可以影响实参的参数,就比如我们经常写的交换两个变量的值,在以前我们会使用指针来完成传址调用,从而实现形参的改变影响实参,但现在我们可以用引用来实现,如下:

//做参数来使用,由于共用同一块空间,所以这里的c实际上就是a,d实际就是b
void Swap(int& c, int& d)
{
int tmp = c;
c = d;
d = tmp;
}
int main()
{
int a = 1, b = 2;
Swap(a, b);
cout << a << " " << b << endl;//2 1
return 0;
}

可以做返回值使用

我们先来看这样一段代码:

这里注意的是:这里的a是局部变量,生命周期会随着栈区的销毁而结束,所以这里返回的实际上并不是a,我们通过查看反汇编发现实际上是借助了一个临时变量来实现的。

那么不禁会有个疑问,假如这里的a不随着栈帧的结束而销毁,那么会不会直接返回a呢?可以试验一下:

对于这种现象,我们可以把引用作为返回值来使用,从而实现优化,写成如下格式:

//返回值
int& Test()
{
static int a = 10;
a++;
return a;//也会产生临时变量,但是临时变量的类型是int& 也就是a的别名,即临时变量就是返回的a,减少了拷贝操作
}
int main()
{
int ret = Test();
return 0;
}

这就是引用返回,即在返回类型前面加上&,虽然也需要借助临时变量的存在,但是由于临时变量的类型为int& ,即临时变量就是a,所以就减少了临时变量的拷贝工作,会使效率得到提升。我们可以来验证一下:

传值返回 vs 传引用返回效率对比

#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();
}

运行结果如下:

我们发现传引用返回对比传值返回,效率会有显著提高(作为参数使用时,传引用参数的效率也会高于传值作为参数的效率)

当然,传引用作为返回值的使用是有一定的限制的,我们发现上面的代码能使用传引用返回的原因在于,返回的变量不会随着作用域的销毁而销毁。假如说返回的对象出了作用域后已经销毁,则必须使用传值返回,否则返回的结果是不确定的!

并且引用用作返回时,还可以修改返回对象(后面的学习会用到很多,这里简单介绍)

如下:

#define N 10
typedef struct ARR
{
int arr[N];
}ARR;

int& PosARR(ARR& arr,int i)
{
return arr.arr[i];//这里的arr就是main函数里的arr,不会随着PosARR函数的结束而销毁,所以可以用引用返回
}
int main()
{
ARR arr;
for (int i = 0; i < N; i++)
{
PosARR(arr, i) = i * 10;//引用返回可以修改返回对象,这里的返回对象为arr.arr[i],对此进行修改
}
for (int i = 0; i < N; i++)
{
cout << arr.arr[i] << " ";//0 10 20 30 40 50 60 70 80 90
}
return 0;
}

总结

引用可以用作参数来使用(输出型参数),也可以用作返回使用,用作返回使用时返回的对象必须是出了所在函数作用域后不会销毁的(比如static修饰的变量,全局变量,malloc…),并且引用返回时,返回的对象可以被修改。同时还可以减少拷贝提高效率。

常引用

我们要记住这样一句话:指针和引用在赋值或者初始化时,权限可以被缩小或者保持,但不可进行修改。

这是什么意思呢?通过以下代码进行了解:

// 权限放大(error)
//const int c = 2;//const 修饰的常量不可以进行修改,可以理解只具有读的属性,不具有写的属性,而d可以修改,所以权限被放大
//int& d = c;//这里正确写法应为const int& d=c;

//const int* p1 = NULL;
//int* p2 = p1;//同上,前面加个const即可,const int* p2=p1; (√)

// 权限保持

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
nt* p2=p1; (√)

// 权限保持

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-SQt5ca3p-1713433725517)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值