C++基础(引用和内联函数)

接上文C++基础内容

1.引用

(1)定义:引用简单来说就是给变量取个别名,它和它引用的变量共用同一块内存空间。;举个例子,你在学校老师会叫你的大名,在家你父母会叫你小名,但这个名字所指向的人都是你。

在这里插入图片描述

(2)引用的语法格式:类型+& 变量名=引用的实体

int a = 0;
int& b = a;//b对a进行引用

(3)引用的特性:

1.引用在定义时,必须初始化,不初始化编译器会报错,因为编译器不知道你要给那个变量取个别名。

在这里插入图片描述

2.一个变量可以有多个引用,相当于一个变量可以有多个别名。

int a = 0;
int& b = a;
int& c = a;
int& d = a;

3.一旦引用了一个实体,再不能引用其他实体。就相当于每一个人都有一个特定的身份证号码,不能有同时有两个能表示你的身份的身份证号码。

在这里插入图片描述

4.引用的变量和引用的实体必须是相同类型

在这里插入图片描述

(4)常引用:(涉及变量权限的问题)

假设一个变量+const表示该变量只能读,不能修改了,若没加表示该变量可读可写。

const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;

// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;

double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;

再看看以下的代码,看看该代码有没有问题


	int a = 0;
	const int& b = a;

a是可读可写,b是只可读,我们来看看结果吧
在这里插入图片描述
没有任何错误,证明大权限转化为小权限可以,小权限转化为大权限不可以。

(5)引用的使用

可以做参数也可以做返回值
我们来看一个有意思的代码

int& Add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int& ret = Add(1, 2);
	cout << "Add(1, 2) is :" << ret << endl;
	return 0;
}

这个代码的结果是什么呢?我们来看看吧
在这里插入图片描述
为什么是随机值呢?这就需要我们联系计算机内存存储的知识了,我们知道函数空间的开辟是在栈帧中,当代码执行到调用Add函数时,编译器会到Add函数所在的空间执行代码,代码执行完把Add函数里面的空间被系统回收了,然后ret又是Add函数返回值的别名,然后就得去被系统回收得Add函数的空间去寻找c的空间,所以c,就会出现随机值。
在这里插入图片描述

那么我们该如何解决这个问题呢?不需要使用引用调用,直接使用传值调用就可以得出结果7了。

(6)引用和指针的区别

指针是开辟一块空间用来存放指针所指向的变量的空间的地址
引用只是给变量的空间起了个别名

注意在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;在底层实现上实际是有空间的,因为引用是按指针的方式来实现的(如果需要认证,可以查一下汇编代码)
在这里插入图片描述

2.内联函数(以空间换取时间)

(1)定义:以inline修饰的函数为内联函数,内联函数会在别人调用它时展开自身,从而导致自身没有在栈帧中开辟空间,提高了代码的运行的效率。

使用内联函数的汇编代码图,图中显示Add内联函数并没有在栈帧上开辟空间,而是直接展开了代码。
在这里插入图片描述
注意:内联函数只是向编译器发出的一个请求,编译器可以拒绝该请求,将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器不会采用inline修饰。

3.auto关键字(c++11)

随着我们学习的深入,我们所写的代码也会越来越复杂,因此表达式所用到的类型也会越来越复杂,如果每次在计算表达式时,都要书写表达式的复杂的类型,我们有可能会写错,书写也非常的麻烦。因此c++11规定出一个关键字auto,auto可以自动识别表达式的类型。那么我们如何使用auto呢?

int TestAuto()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;
	auto c = 'a';
	auto d = TestAuto();
	cout << typeid(b).name() << endl;//这个代码表示输出变量b的类型
	cout << typeid(c).name() << endl; //这个代码表示输出变量c的类型
	cout << typeid(d).name() << endl; //这个代码表示输出变量d的类型

	return 0;
}

在这里插入图片描述
使用auto时,需要注意以下几点:

1.使用auto必须初始化,如果不初始化,编译器无法判断该表达式是什么类型,编译器就会报错。

auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
在这里插入图片描述

2.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

在这里插入图片描述

3.auto在同一行中定义多个变量必须是相同的类型,否则会报错

4.auto不能用来判断函数形参的类型,也不能直接用来声明数组。

在这里插入图片描述
在这里插入图片描述

3.C++中的空指针

在定义一个指针时,需要给该指针初始化,在c语言中给指针初始化为空是int* a=NULL;
但在C++中如果按照C语言那种方法初始化指针,可能会出现问题。
在这里插入图片描述
我们可以看看这个代码

void f(int)
{
cout<<"f(int)"<<endl;
}
void f(int*)
{
cout<<"f(int*)"<<endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);//**这里本意是传NULL指针过去调用void f(int*)函数,但由于NULL表示0,需要强制转化为整形指针类型**
return 0;
}

4.总结:

到这里c++的基础知识就已经总结完了,C++基础知识对于后面的学习类和对象的内容至关重要,需要我们高度重视C++基础知识,下篇博客就是对C++的类和对象进行总结了,加油!

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平平无奇。。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值