1.引用介绍
在C
语言中,对于下面两个实现交换变量值的函数,因为函数传参传的是函数值,swap1()
是完成不了的,而swap2()
可以。
#include<stdio.h>
void swap1(int a,int b)
{
int tmp=a;
a=b;
b=tmp;
}
void swap2(int* pa,int* pb)
{
int tmp=*pa;
*pa=*pb;
*pb=tmp;
}
int main(int argc,char**argv)
{
int a = 10,b = 20;
printf("初始时a=%d,b=%d\n",a,b);
swap1(a,b);//传a和b的值
printf("swap1后,a=%d,b=%d\n",a,b);
swap2(&a,&b);//传a和b的地址,&是取地址符
printf("swap2后,a=%d,b=%d\n",a,b);
return 0;
}
运行结果:
初始时a=10,b=20
swap1后,a=10,b=20
swap2后,a=20,b=10
在C++
中可以使用引用,这里的&
表示引用,&
用定义和识别的关键,而不是取地址符号:
void swap3(int& a,int&b)
{
int tmp=a;
a=b;
b=tmp;
}
引用主要用在函数传参和返回值,引用符号在定义时必须同时初始化,以后不能再另外赋值,只能使用。
2.引用和指针的对比
- 1.
C
和C++
都有指针并且使用方法和实现本质完全相同,但是引用只在C++
中可用。 - 2.引用可以理解为功能弱化、安全性增强的低配版指针。
- 3.引用能做的事指针都能做,但指针能做的事儿引用不一定能做。
- 4.引用是它指向变量的“别名”,操作引用就等于操作它关联的那个变量,这个是从引用的使用效果角度讲的,对熟悉指针的人反而不好理解“别名”这个词。
- 5.引用比指针弱的地方就是一个引用定义时必须绑定一个变量并且后面没法修改;引用比指针强的地方也是没法改,所以不存在"野指针"问题,更安全。
3.引用的本质剖析
3.1 引用可以加const修饰
int a=10;
const int &b = a;
// b=55; 这句编译报错
a =44; //编译没报错且运行没问题
这里表示b
是a
的const
别名可以通过a
来修改值,但是无法通过b
修改a
了。
引用加const修饰主要用在函数形参中,告诉用户该函数内部不会修改实参的值。某些时候我们有一个非const
类型的变量,但是我们在某个函数调用的过程中,不希望变量的值在函数内部被修改,这时候就可以用const
引用来传参。
3.2 引用和sizeof运算符
sizeof
引用得到的不是引用本身的大小,而是引用指向的目标变量的大小,但是在struct
或class
中定义一个引用,再sizeof
整个struct
或class
就会不一样。
3.3 引用的本质是const指针
int &b = a;
类似于:
int * const b = &a;
C++
标准并没有规定引用是否占用内存空间,但是大多数编译器都把引用实现为const
指针,所以大部分编译器中引用也是要占内存空间的。引用是天然const
的,所以定义时必须初始化指向变量,否则就没意义了。
引用本质是指针,是地址,所以才能实现传址调用的效果,引用就是指针在定义时增加了把指针变量本身const
化。