函数返回值是引用(引用当左值)
语法:Type &Funname(形参列表) { }
难点:当函数的返回值为引用时
返回值是基础类型,当引用
若返回栈变量,不能成为其他引用的初始值,不能作为左值使用。
//C++
int getAA1()
{
int a = 10;
return a;
}
int& getAA2()
{
int a = 10;
return a;
}
int* getAA3()
{
int a = 10;
return &a;
}
void main()
{
int a = getAA1();
int b = getAA2();
int *c = getAA3();
printf("a:%d,b:%d,c:%d \n", a, b, *c);
system("pause");
}
返回值是基础类型a时,在返回的时候,编译器会在内存中创建一个临时变量并将a的值拷贝给临时变量。当返回到主函数后,临时变量的值再拷给对应的变量。
int a = getAA1(); //正确 返回值
int &a = getAA1(); //错误 非常量引用的初始值必须为左值
注意“非常量引用的初始值必须为左值”什么意思,getAA1()返回的是一个常数,常数是不可以初始化引用的,因为引用是变量的别名,必须为“=”左边的值,也就是变量名。
返回值是引用时不会产生临时变量(副本),而是直接将a(全局变量)返回给主函数,在主函数中b直接从a中拷贝值,这样就避免了临时变量的产生。
int b = getAA2(); //正确 返回引用
int &b = getAA2(); //正确 返回引用
int *c = getAA3(); //正确 返回指针
返回值是static变量/全局变量,当引用
若返回静态或全局变量时,可以成为其他引用的初始值,既可以作右值,也可作左值使用
static修饰变量的时候,变量是一个状态变量
int j()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return a;
}
int& j1()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return a;
}
int *j2()
{
static int a = 10;
a++;
printf("a:%d \n", a);
return &a;
}
void main22()
{
// j()的运算结果是一个数值,没有内存地址,不能当左值。。。。。
//11 = 100;
//*(a>b?&a:&b) = 111;
//当被调用的函数当左值的时候,必须返回一个引用。。。。。
j1() = 100; //编译器帮我们打造了环境
j1();
*(j2()) = 200; //相当于我们程序员手工的打造 做左值的条件
j2();
system("pause");
}
常量引用
1、const &int a 相当于 const int *const a
2、普通引用 相当于int *const a
3、当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
4、使用字面量对const引用初始化后,将生成一个只读变量
//一般引用
int a =10;
int &b = a;
b = 20;
cout<<a<<endl;//20
//常引用
int x = 10;
const int &x1 = x;//只读属性 不能通过x1去修该x的值
//x1 = 20;
//常引用的初始化
//1.用变量初始化常引用
int a = 10;
const int &b = a;
//2.用字面量初始化
int b = 10;//C++编译器把b放在符号表中
//int &b1 = 11;//字面量没有内存地址 不能直接给一般引用引用字面量
//引用就是给内存多取一个别名
const int &b1 = 20;//c++编译器 自动分配内存空间
总结
1、引用本身是目标变量或对象的别名,对引用的操作实际上是对目标变量或对象的操作,因此能使用引用时尽量用引用而非指针。
2、用引用传递函数的参数,能保证参数在传递的过程中不产生临时变量(副本),从而提高传递效率,同时通过const的使用,还可以保证参数在传递过程中的安全性
3、在引用的使用中,单纯给某个变量取别名是没有意义的,引用的目的主要用于在函数参数的传递中,提高效率问题。