引用:
1.引用的定义:
类型& 引用变量名称 = 变量名称
注意:&和类型结合称之为引用符号,不是取地址符号
那么引用到底是什么意思呢?其实引用代表着别名的意思。接下来结合具体实例来解释
int mian()
{
int a=10;
int b=a;
int& c=a;
return 0;
}
我们定义一个整形变量a=10;我们再定义一个变量b=a,注意这个b是占用内存空间的,b的值为a的值,同为10,但是我们用一个c去引用a时,c不开辟空间,只是给变量a取了一个别名,c就是变量a,c的值为变量a的值,为10;
2.引用的特点
1.定义引用时必须初始化
int main()
{
int a=10;
int &x;//error
return 0;
}
像上面这种情况就是错误的,我们在定义一个引用时必须要初始化,到底是谁的别名。
2.没有空引用
我们都知道,指针有空指针,那么引用有没有空引用呢?就是: int &y=NULL;我们的引用时没有所谓的空引用的。
3.没有引用的引用,即二级引用
int main()
{
int a=10;
int &b=a;//ok
int &&c=b;//error 没有引用的引用
}
注意:引用不需要空间,引用定义时被初始化,之后不可以改变
我们举例说明
int main()
{
int a=10,b=20;
int &c=a;
//我们现在不想让c引用a了,想让c引用b
c=b;
//这种想法是错误的,因为我们在引用定义时必须初始化,之后是不可以改变的。
//这里的c=b,只是让c的值由原来的10变成了20,即a的值由原来的10变成了20。
return 0;
}
3.常引用(const 引用)
我们的常引用也被称为万能引用,因为常引用不仅可以引用变量,还可以引用字面常量。我们先说常引用引用普通变量:
int main()
{
int a = 10;
const int& y = a;
y = 20;//error
return 0;
}
看上边的代码,我们用一个常引用y去引用普通变量a,这种情况是可以的,只不过我们不可以通过y去改变变量a的值。我们发现const int&和我们上一篇文章中的const和指针关系中的const int *有点类似,还有int *const,那么int& const可不可编译通过呢?
int main()
{
int a = 10;
int& const x = a;//ok
x = 20;//ok
return 0;
}
这种情况是可以的,只不过这种情况就相当于普通引用了 ,那还不如直接写int &x=a;二者是相同的。
常引用引用字面常量:
int main()
{
const int& z = 10;//ok
//原理:创建一个临时的tmp
//int tmp=10;
//const int &z=tmp;
return 0;
}
我们用常引用直接引用10,这种情况是可以的, 其原理是先创建一个临时的变量tmp,令tmp等于10,再用常引用去引用tmp;
常引用引用常变量
int main()
{
const int b=10;
const int &f=b;
return 0;
}
4.引用作为形参代替指针
在C语言中,我们经常用指针作为函数的形参,比如我们写一个交换函数:
void myswap(int* a, int* b)
{
assert(a != NULL && b != NULL);
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 10, b = 20;
myswap(&a, &b);
cout << a <<" " << b << endl;
return 0;
}
结果:
我们有了引用之后,要慢慢学会用引用作为形参代替指针,那么上面代码我们用引用的写法如下:
void my_swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 10, b = 20;
my_swap(a, b);
cout << a <<" " << b << endl;
return 0;
}
运行结果:
得到了相同的结果,但是我们会发现用引用会比指针有很多优点,比如因为不存在空引用,所以我们进入函数的时候不需要判空。
5.其他引用形式:
int main()
{
int a=10,b=20;
int ar[5]={1,2,3,4,5};
int *p=&a;
int*&rp=p;//引用指针
int &x=ar[0];
int(&br)[5]=ar;//引用数组
return 0;
}
注意:引用指针时,不能写成int &*rp=p。
6.引用与指针的区别
1.从语法规则上
1.1指针变量存储某个实例(变量或对象)的地址;引用是某个实例的别名
程序为指针内存分配内存区域;而不为引用分配内存区域
1.2解引用是指针使用时要在前面加“*”,引用可以直接使用
1.3指针变量的值可以发生改变,存储不同实例的地址;引用在定义时就被初始化,之后无法改变。
1.4指针变量的值可以为NULL;没有空引用
1.5指针变量作为形参时需要测试它的合法性(判空);引用不需要判空
1.6对指针变量使用sizeof得到的是指针变量的大小。对引用使用得到的是变量的大小。
1.7理论上指针的级别没有限制;但引用只有一级,不存在引用的引用,但可以有指针的指针。
1.8++引用与++指针的效果不一样
2.从汇编层次上
引用实质上就是一个指针。本质(* cosnt)
引用从底层上看其实就是一个指针(* const)