各位读者老爷好,本鼠最近浅学了一点C++的入门知识!利用本博客作为笔记的同时也希望得到各位大佬的垂阅!
目录
1. 引用
1.1.引用的概念
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。
“取别名”的方法:类型& 引用变量名(对象名) = 引用实体。如下例所示:
#include<stdio.h>
int main()
{
int a = 10;
int& ra = a;//引用,ra就是a的别名
printf("%p\n", &a);
printf("%p\n", &ra);
return 0;
}
我们看到ra和a的内存空间确实是同一块。
注意:引用类型必须和引用实体是同种类型的。如上,变量a和ra的类型都是int。
1.2.引用的特性
1.引用在定义时必须初始化,就是必须说清楚是谁的别名。
2.一个变量可以有多个引用,就是说一个变量可以取多个别名。
3.引用一旦引用一个实体,再不能引用其他实体,就是说引用不能改变指向。
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
//int& ra; 这条语句在编译时会出错,因为引用在定义时没有初始化
int& ra = a;
int& rra = a;
rra = b;//这里是将b赋值给a的别名rra,可不是改变rra的指向
cout << rra << endl;
cout << &a << endl;
cout << &ra << endl;
cout << &rra ;
return 0;
}
1.3. 常引用
我们知道了引用的概念,但是还必须知道常引用。我们看一个代码:
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;
const int c = 10;
int& d = c;//error C2440: “初始化”: 无法从“const int”转换为“int &”
return 0;
}
主函数第四条语句编译时会报错,为啥子捏?
原因:俺们看第三条语句,c是被const修饰了,c是常变量,具有常性,不可被更改。那么第四条语句如果通过的话明显是权限放大的表现:可以通过c的别名d更改c啊!显然这种权限放大的行为不行的。
那么常量想要取别名怎么办?
其实用const修饰别名就好了,这就是常引用,如下:
#include<iostream>
using namespace std;
int main()
{
const int c = 10;
const int& d = c;
return 0;
}
所以我们要知道取别名不能放大权限(权限只能平移和缩小,不可放大)!
知道了常引用,如果我们有一种场景:本身是可以改变的,但不希望通过别名改变本身。那么我们就可以使用常引用。这是一种权限的缩小。如:
#include<iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;
const int& c = a;
b++;
c++;// error C3892: “c”: 不能给常量赋值
return 0;
}
这里b和c都是a的别名,不过c被const修饰了。通过b改变a是没问题的,但像通过c改变a编译时就会报错!
我们再看一些代码会对常引用有更深的理解:
代码1:
#include<iostream>
using namespace std;
int main()
{
const int& a = 10;
int& b = 10;//error C2440: “初始化”: 无法从“int”转换为“int &”
return 0;
}
这里a就是常量10的别名,这里常引用使用的没毛病!但是第二条语句编译报错,原因还是权限放大了:如果编译通过就可以通过10的别名b更改10。
代码2:
#include<iostream>
using namespace std;
int main()
{
double a = 13.14;
int& b = a;//error C2440: “初始化”: 无法从“double”转换为“int &”
return 0;
}
这里为什么会报错呢?
但是将b用const修饰之后编译就通过了(当然有警告),这又是为啥?
#include<iostream>
using namespace std;
int main()
{
double a = 13.14;
const int& b = a;
return 0;
}
要搞清楚为啥,我们还要看一个代码:
#include<iostream>
using namespace std;
int main()
{
double a = 13.14;
int b = a;
cout << b;
return 0;
}
这个代码编译也通过了(当然也有警告)。那么是如何将double类型的数据赋值给int类型的数据的捏?
表面上好像就是a直接赋值给b呗。但是其实是产生了一个临时变量,先通过整形提升将a转换为整形,再将a赋值给临时变量,临时变量就是整形类型了,临时变量再赋值给b的。