引言:本节我们讲一下C++中的引用、内联函数、Auto、范围for
一、引用
先看一下下面这段代码:
在这段代码中。我们命名了两个变量,a和_a,其中_a就是a的引用
所谓引用就是a的“别名”,我们看一下这段代码的运行结果:
发现其地址一样,所以我们去改变_a的值也会把a的值也改变了。
- 引用必须在定义时就初始化。
- 引用自开始定义后,就无法变更引用对象。
- 一个变量可以有多个引用,但是不能引用的引用 。
- 引用类型需与被引用对象类型保持一致,即:
const int a = 0;
const int& _a = a;
不能:int& _a = a;(因为被引用对象不可改变,引用后也不能改变其值)
但如果:
int a = 0;
const int& _a = a;
这样是可以的,a可以改变,引用后可以改变也可以不改变
引用可以做参数和返回值
这段代码中将a传入函数,让a+100,并返回a。
可以看到直接改变了a的值。
其实到这里,你可能已经有疑问,这个和之前C中的指针有种说不出的相似。
事实上,在编译和cpu视角上,指针和引用是没有区别的,他们都是靠地址来识别的。
在C++中很多学者都不提倡滥用指针。
指针和引用的区别:
- 引用在概念上是定义一个变量的“别名“,而指针是存储一个变量的地址。
- 引用在定义时必须初始化,指针没要求。
- 引用在初始化一个实体后,就不能改变被引用对象,而指针可以。
- 指针可以NULL(C++11之后推荐使用nullptr)。
- sizeof(),引用的结果为引用类型的大小,指针为地址的大小(32位是4字节)。
- 指针可以指针的指针,引用不行。
二、内联函数
如果在函数定义前面加上inline,在release版本下,函数不会创建栈帧,而是在调用函数内部展开,类似于C中的宏函数。
就像下面这样:
但是,内联函数对于编译器来说只是一个建议,编译器会自动优化。在代码较长、递归的情况下会忽略内联。
注意:内联不能声明和定义分离,因为其在调用函数内部已经展开,就不会有符号表对应了,也就没有地址了。
三、Auto
这是C++11中的标准,就是在写一个变量的类型时可以用auto替代,让编译器自动推导类型。
#include <iostream>
using std::cout;
using std::endl;
#define Cout(X) cout<<(X)<<endl
int main(){
int a = 0;
auto b = a;//自动推导出b的类型为int
Cout(typeid(b).name());
return 0;
}
四、范围for
这个也是C++11引入的,它是基于数组的范围进行遍历。
看到这个for循环,学过java的应该特别熟悉,这个不就是是JDK1.5以后出来的一个高级for循环嘛。(C++yyds,哈哈哈)
这种循环就是把arry中的每个数取出来给e,然后用e来操作,只不过第一个for中的e是取出来每个数的引用,所以改变它也就可以改变数组里的值,第二个for中的e就只是每个数组元素的拷贝,用于遍历打印出来。