前言

C++快速入门已经更新完毕,前两篇见:C++系列2-1:C++快速入门之命名空间和输入输出 和

C++系列2-2:C++快速入门之缺省参数和函数重载

七:引用

情景导入:

在第一次学习C语言指针时,许多教材上都会给出一个交换变量值的函数的例子,开始我们认为这样交换就可以成功

void swap(int a,int b)
{
	int temp=a;
	a=b;
	b=temp;
}
int main()
{
	int a=1;
	int b=2;
	swap(a,b);
}

但学习完指针后,就明白了这样的操作是不行的,因为每当进行一个函数就会为该函数的形参开辟一个新的空间,函数结束之后,形参的空间也就被销毁了,所以不可能交换成功。于是正确的写法应该是这样

void swap(int* x,int* y)
{
	int temp=*x;
	*x=*y;
	*y=temp;
}
int main()
{
	int a=1;
	int b=2;
	swap(&a,&b);
}

而在C++中我们引入一个新的概念——引用

(1)引用的概念

简单点来说:引用就是起别名,这一片内存空间名字叫a,然后再给它额外起一个名字,叫做b,a和b操控的是同片内存空间。

inlineC语言_c++inline_inline测试是什么意思

从下面的这个动态调试的过程中,大家可以深刻的体会到引用这种取别名的意思

inline测试是什么意思_c++inline_inlineC语言

(2)地用的地点引用在定义时必须初始化,不初始化有点像野指针的感觉一个变量可以有多个引用,也就是有多个外号一个引用一旦引用了一个实体,就不能再引用其他实体了。(3)常引用

C语言中我们就知道,如果定义一个长整形,表示这个整形变量是不可以修改的,如果用普通引用则不行

int main()
{
	const int a=10;
	int& b=a;//错误,权限被放大,之前只可读,赋值后却可读可写了
}

那么面对这样的变之后如之后然使用之前的引用方式是不可行的,这涉及到一个权限问题,变量a自身只能可读,但是它被int& b引用后,反倒可以修改了,这就矛盾了。所以要解决这种权限问题,必须使用常引用

int main()
{
	const int a=10;
	const int& b=a;//常引用
}

int main()
{
	int a=10;
	const int& b=a;//这样的做法是可以的,权限被缩小的
}

int main()
{
	int& c=1;//错误
	const int& c=1;//正确
}

int main()
{
	double a=3.14;
	int b=a;//隐式转换
	//如果用int型引用double型,引用不是那个double,而是double转换为int时
	//的那个中间变量,因为它具有常性
	int& ps=a;//错误
	const int& ps=a;//正确
}

关于常引用,确实C++在这方面有点麻烦,但是这个常引用也是有好处的,尤其体现在引用做形参。我们一般使用常引用作为形参,根据以上叙述,所以其实参可以是变量也可以是常量,同时如果实参和形参存在类型转换,这也是无妨的,也可以传递

void test(const DataType& x)
{
	//形参使用常引用好处多多

(4)引用的应用场景A:做参数

回到之前的情境导入,根据以上的叙述在C++中交换两个变量的值就可以使用引用了。

void Swap(int& x,int &y)
{
	int temp=x;
	x=y;
	y=temp;
}
int main()
{
	int a=1;
	int b=2;
	Swap(a,b);
}

inline测试是什么意思_c++inline_inlineC语言

B:做返回值

实参传给形参时,如果不用指针或引用,那么形参就要拷贝一份,这一点相信大家是很明白的。但是,函数的返回值也属于传值,也就是它不是直接返回给调用函数的变量,而是先给寄存器或内存(如果数据大的话要开辟更多空间)

inlineC语言_inline测试是什么意思_c++inline

当然,引用也可以用于返回值。让函数返回引用,在让调用它的地方引用,相当于一次拷贝。

c++inline_inline测试是什么意思_inlineC语言

其实上面的代码是有一定的问题,虽然可以正确执行,通过调试可以发现,和ret地址是一样的,他们都是那一片内存空间的别名。

inlineC语言_c++inline_inline测试是什么意思

如果在后面再调用一次sum函数,最终输出结果成了7了

inlineC语言_c++inline_inline测试是什么意思

使用调试,会感受到这个过程

inlineC语言_c++inline_inline测试是什么意思

而如果再加入一句毫不相干的代码,会发现最后输出的竟然是一个随机值,这是因为到这里的时候ret早就还给系统了。

c++inline_inline测试是什么意思_inlineC语言

所以:如果函数返回时,已经出了作用域,此时如果返回对象还未归还给系统,那么可以使用引用返回,但是如果已经还给系统了,则必须使用传值返回。

(5)引用和指针

语法角度上讲,引用是实体的别名,与实体共用统一内存空间,而从底层实现角度上讲,引用其实是按照指针的方式进行的

从汇编角度可以看出这一点

inline测试是什么意思_c++inline_inlineC语言

引用和指针的区别如下

引用

指针

引用定义必须初始化

指针没有要求

引用只能一个实体

指针在任何时候指向任何同类型的实体

没有NULL引用

但有NULL指针

使用()表示引用类型的大小

使用表示地址空间所占字节数

++引用表示引用的实体增加1

++指针表示指针向后偏移一个类型的大小(字节)

没有多级引用

但有多级指针

引用较安全

指针较不安全

八:内联函数

情境导入:

在之前的排序或者是其他的联系中,我们经常使用到一个自己构造的函数,那就是交换函数。函数如果被调用,就会产生压栈的开销,为了解决这样的问题。在C语言中,我们可以使用宏函数

# define max(a,b) a>b?a:b
int main()
{
	int ret=max(1,2);
	return 0;
}
123456

而在C++中可以使用内联函数解决

(1)内联函数的概念

使用修饰的函数叫做内联函数,编译时编译器会在调用内联函数的地方展开,它没有函数压栈的开销,因此提高了程序运行的效率

下面的函数没有用修饰,其汇编代码中存在call指令

inlineC语言_c++inline_inline测试是什么意思

如果使用将其修饰为内敛函数,在编译期间编译器会用函数体替换函数的调用。由于在debug模式,编译器不会对代码进行优化,所以可以在模式下查看汇编代码中是否存在call指令

c++inline_inline测试是什么意思_inlineC语言

(2)内联函数的特性实则是一种以空间换时间的做法,所以对于递归,循环则不适合作为内联函数不要把声明和定义分离,分离会导致链接错误,一旦被展开,就没有函数地址了。九:auto关键字(C++11)(1)auto简介

auto其实一直存在,早期C/C++人们赋予auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量

C++11赋予了auto新的含义:auto不再是一个指示器,而是一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导获得。

c++inline_inline测试是什么意思_inlineC语言

(2)auto使用注意事项

1.auto声明指针类型时,既可以使用auto也可以使用auto*,但是在声明引用时必须加上&

c++inline_inlineC语言_inline测试是什么意思

2.在同一行声明多个变量时,这些变量必须是同一类型

int main()
{
	auto a=1,b=2;//正确
	auto c=3,d=4.0;//错误
}

3.auto不能作为函数参数

void test(auto a)
{
	//编译错误,调用函数需要开栈帧,但此时编译器无法对a的类型进行推导
}

———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666

声明:1、本内容转载于网络,版权归原作者所有!2、本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。3、本内容若侵犯到你的版权利益,请联系我们,会尽快给予删除处理!