C++-Record09—函数的返回值当引用

目录

返回栈变量

返回全局变量

返回静态变量

总体代码


返回栈变量

引用做函数值,下面三个函数分别设定为不同的返回类型。 分别是返回一个值,返回一个引用,返回一个指针:

int getAA1()
{
	int a ;
	a = 10;
	return a;
}

//返回a的本身 返回a的一个副本 10 
int& getAA2()
{
	int a ; //如果返回栈上的 引用, 有可能会有问题
	a = 10;
	return a;
}

int* getAA3()
{
	int a ;
	a = 10;
	return &a;
}

void main1101()
{
	int a1 = 0;
	int a2 = 0;
	a1 = getAA1();

	a2 = getAA2(); //10
	int &a3 = getAA2();  //若返回栈变量	不能成为其它引用的初始值

	printf("a1:%d \n", a1);
	printf("a2:%d \n", a2); 
	printf("a3:%d \n", a3);  // *a3

	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

用debug模式下,运行: 

用release模式下,运行: 

a3又不是个乱码了!?程序因为不同的版本所运行的结果不一样,这说明程序存在潜在的bug。那么,下面来进行分析:

a1的内存空间分配就不说了;直接说a2,a2是通过引用来返回函数返回值的,而引用的本质是编译器帮程序员直接返回对应的地址,即直接就把a的地址给返回出来,把a的值也给返回出来(可以理解成,是对a的地址和变量,都作了一个副本),a运行完毕之后,在被调函数中的a的运行空间,就不需要了,析构,但通过引用进行了返回,返回一个a的引用,就是返回一个a的本身,即返回a的内存空间;再看a3,返回的是一个引用,用一个引用去接,编译器会把getAA2()的返回值(a的地址),相当于a3这个变量里面,存放的是“oxaa11”,但是,当我们打印a3的时候,编译器,一看a3是个引用,就会执行"*a3",编译器顺着a3的地址去访问,发现对应的位置,已经在被调函数运行结束的时候,都被清掉了,所以,打印出来的是一个乱码。

C++引用使用时的难点:

结论:当函数返回值为引用时,若返回栈变量,不能成为其它引用的初始值,不能作为左值使用,只能作为右值。

返回全局变量

在看当返回值是全局变量的时候:

//变量是static 或者是 全局变量

int j1()
{
	static int a = 10;
	a ++ ;
	return a;
}

int& j2()
{
	static int a = 10;
	a ++ ;
	return a;
}

//若返回静态变量或全局变量
//	可以成为其他引用的初始值
//	即可作为右值使用,也可作为左值使用
void main1112()
{
	int a1 = 10;
	int a2 = 20;

	a1 = j1();
	a2 = j2();
	int &a3 = j2();

	printf("a1:%d \n", a1);
	printf("a2:%d \n", a2); 
	printf("a3:%d \n", a3);  
	system("pause");
}

和之前的状况不一样,可以运行出结果,且不会乱码。

返回静态变量

函数当左值且为静态变量的时候:

//--- 函数当左值
//返回变量的值
int g1()
{
	static int a = 10;
	a ++ ;
	return a;  //
} 

//返回变量本身 , 就是返回所表示的内存空间
int& g2()
{
	static int a = 10;
	a ++ ;
	printf("a:%d \n" , a);
	return a;
}

void main()
{
	// g1() = 100;  左操作数必须当左值
	//11 = 100;

	g2() = 100; //函数返回值是一个引用,并且当左值 
	g2();

	int c1 = g1(); //函数返回值是一个引用,并且当右值 
	int c2 = g2(); //函数返回值是一个引用,并且当右值 
	//a = 100;
	system("pause");
}

"g2() = 100;"这句话,相当于"a = 100",因为g2返回的是变量本身,而变量本身是表示的一段内存空间。所以,是可以运行成功的,这种类型的就是函数返回值是个引用当左值。最主要的看内存空间是不是一个有效的内存空间,本例中的“static int a = 10;”是一个有效的内存空间,不会随被调函数析构而清除。

 

结论:若返回静态变量或全局变量,可以成为其他引用的初始值,既可作为右值使用,也可作为左值使用,C++链式编程中,经常用到引用,运算符重载专题。

 

总体代码

dm11_函数返回值是一个引用.cpp


#include <iostream>
using namespace std;

int getAA1()
{
	int a ;
	a = 10;
	return a;
}

//返回a的本身 返回a的一个副本 10 
int& getAA2()
{
	int a ; //如果返回栈上的 引用, 有可能会有问题
	a = 10;
	return a;
}

int* getAA3()
{
	int a ;
	a = 10;
	return &a;
}

void main1101()
{
	int a1 = 0;
	int a2 = 0;
	a1 = getAA1();

	a2 = getAA2(); //10
	int &a3 = getAA2();  //若返回栈变量	不能成为其它引用的初始值

	printf("a1:%d \n", a1);
	printf("a2:%d \n", a2); 
	printf("a3:%d \n", a3);  // *a3

	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

//变量是static 或者是 全局变量

int j1()
{
	static int a = 10;
	a ++ ;
	return a;
}

int& j2()
{
	static int a = 10;
	a ++ ;
	return a;
}

//若返回静态变量或全局变量
//	可以成为其他引用的初始值
//	即可作为右值使用,也可作为左值使用
void main1112()
{
	int a1 = 10;
	int a2 = 20;

	a1 = j1();
	a2 = j2();
	int &a3 = j2();


	printf("a1:%d \n", a1);
	printf("a2:%d \n", a2); 
	printf("a3:%d \n", a3);  
	system("pause");
}


//////////////////////////////////////////////////////////////////////////
//--- 函数当左值
//返回变量的值
int g1()
{
	static int a = 10;
	a ++ ;
	return a;  //
} 

//返回变量本身 , 
int& g2()
{
	static int a = 10;
	a ++ ;
	printf("a:%d \n" , a);
	return a;
}

void main()
{
	// g1() = 100;
	//11 = 100;

	g2() = 100; //函数返回值是一个引用,并且当左值 
	g2();

	int c1 = g1(); //函数返回值是一个引用,并且当右值 
	int c2 = g2(); //函数返回值是一个引用,并且当右值 
	//a = 100;
	system("pause");
}
发布了140 篇原创文章 · 获赞 6 · 访问量 4850

猜你喜欢

转载自blog.csdn.net/qq_17846375/article/details/104037412