指针和引用
引用
引用:引用不是一个新的变量,而是一个已经存在的变量的别名。比如你同学在学校叫你王五,回到家里,家里人叫你小王一样,虽然叫法不同,但实际上指的都是一个人。
下面看一段代码
void test()
{
int a = 1;
int e = 4;
int &b = a;//引用的格式:类型 &引用变量名=已定义过的变量名
//int &b;//这样是非法的,引用必须初始化,否则不知道自己是谁的别名
//int &b = e;//这样是非法的,引用只能初始化一次,不能改变为在引用其它的变量
int &c = a;//可以有多个别名
int &d = c;//d为c的别名,这是合法的,别名的别名
a = 2;
b = 3;
cout << a << endl;//3
cout << b << endl;//3
cout << c << endl;//3
cout << d << endl;//3
}
最终执行的结果a和b和c都为3,b和c都是a的别名。
可以总结出引用具有以下特点:
1.一个变量可取多个别名。
2.引用必须初始化。
3.引用只能在初始化的时候引用一次,不能改变为在引用其它的变量。
const 引用
void test1()
{
int a = 1;
const int &b = a;
a = 2;
//b = 3;非法,被const修饰,b为常量(不能被修改的量),不能被赋值
cout << a <<' '<<b << endl;//a=3,b=3
const int c = 4;
const int &d = c;
//d = 5;非法,被const修饰,d为常量(不能被修改的量),不能被赋值
const int &e = 6;//合法,常量具有长属性,只有常引用(被const修饰)可以引用常量,可理解为e为6的别名
cout << c << ' ' << d << endl;//c=4,d=4
cout << e << endl;//e=6
double f = 1.1;
//int &g = f;非法,f为double类型,g为int类型,f赋值给g时要产生一个临时变量,也就是说g引用的是这个带有长属性的变量,所以不能赋值
const int &h = f;
cout << f << ' ' << h << endl;//合法,f=1.1,h=1(double转换成int,会有精度丢失)
}
引用作为参数
#include<iostream>
using namespace std;
void exchange(int a,int b) //传值调用,实现不了交换
{
int tmp = a;
a = b;
b = tmp;
}
void Swap(int &a,int &b) //传引用,这里的形参是实参的别名
{
int tmp = a;
a = b;
b = tmp;
}
void Swap(int *a, int *b) //传指针,与上面的Swap函数构成了重载
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void test() //测试函数
{
int a = 1;
int b = 3;
exchange(a, b);
cout << "a=" << a << ' ' << "b=" << b << endl;//a=1,b=3 没有完成交换
Swap(a, b);
cout << "a=" << a << ' ' << "b=" << b << endl;//a=3,b=1 完成了交换
Swap(&a, &b);
cout << "a=" << a << ' ' << "b=" << b << endl;//a=1,b=3 完成了交换,因为上面的Swap函数已经交换过一次了,所以再次交换又交换回去了
}
int main()
{
test();
system("pause");
return 0;
}
exchange( )函数不能完成两个数的交换,是因为它是传值调用,传参的时候传的只是a和b的一份临时拷贝,在函数内部完成了交换,但是函数调用完成后,这两个值就被释放掉了,所以没有完成交换。
传值和传引用作为返回值
int &Sum(int a, int b)
{
int ret = a + b;
return ret;
}
int Add(int a, int b)
{
int ret = a + b;
return ret;
}
通过反汇编看传值返回和传引用返回
结论:
1.不要返回一个临时变量的引用。
2.如果返回对象出来当前的作用域依然存在,则最好使用引用返回,这样更高效。
指针和引用的区别和联系
1.引用只能在定义时初始化一次,之后不能改变指向其他变量(从一而终),指针变量的值可以发生变化。
2.引用必须指向有效的变量,而指针可以为空。
3.sizeof引用对象和指针对象的意义不一样,sizeof引用得到的是所指向变量的大小,而sizeof指针是对象地址的大小。
4.指针和引用自增(++)和自减(–)意义不一样。
5.相对而言,引用比指针更安全。
总结
指针比引用更加灵活,但是也更危险,使用指针时一定要检查指针是否为空,指针所指的地址释放后最好置0,否则可能存在野指针的问题。