函数返回值的传递

除了函数参数的传递之外,函数与调用方的另一个交互方式就是返回值。

在返回不同字节大小的返回值编译器的处理方式不一样:

小于4个字节

函数将返回值存储在eax寄存器中,返回调用方之后在读取eax寄存器的值

大于4字节小于等于8字节:

函数返回值通过两个寄存器,eax和edx存储返回后读取。

大于8字节的返回值:

将利用临时对象进行返回值的传递

1、首先在mian函数中的栈上开辟一片额外的空间作为临时对象

2、调用函数时将该临时对象的地址通过隐藏的参数传递给函数

3、函数内部将返回值的数据拷贝到临时对象,并将临时对象的地址通过寄存器eax传出。

4函数返回后,将eax指向的临时对象的内存拷贝到main函数中的变量

注意:在返回自定义类型时,无论自定义类型的大小是多少都是通过临时量进行传递的

typedef struct
{
	int value;
}Data;
Data GetData()
{
	Data data = {10};
	return data;//返回一个局部变量的值,通过寄存器拷贝
}
Data* GetDataPtr()
{
	Data data = {10};
	return &data;//返回局部变量的地址
}
Data& GetDataRef()
{
	Data data = {10};
	return data;//返回局部变量的引用,实际上是返回局部变量的地址
}
int main()
{

	Data d1 = GetData();
	//寄存器的值直接赋值到d1
	Data &d2 = GetData();
	//返回自定义类型值无论字节大小就会产生一个临时量作为引用,正确。
	Data *d3 = &GetData();
	//因为自定义类型返回值是拷贝到临时量,所以可以对临时量取地址。
    //但是不安全,临时量会被销毁
	
	Data *d4 = GetDataPtr();
	//返回指针是四字节,直接通过寄存器带出来的是常量数字
	Data * const &d5 = GetDataPtr();
	//返回的是指针只是一个常量。返回指针与类型无关都是4字节
	//返回指针和引用没有区别,都是通过寄存器带出来的常量数字
	
	Data d6 = GetDataRef();
	Data &d7 = GetDataRef();
	Data *d8 = &GetDataRef();
	
	return 0;
}

int GetInt()//返回值
{
	int value=10;
	return value;
}
int* GetIntPtr()//返回地址
{
	int value = 10;
	return &value;
}
int& GetIntRef()//返回引用
{
	int value = 10;
	return value;
}
int mai1n()
{
	//返回常量值
	int ret1 = GetInt();
	//直接通过寄存器传出
	const int &ret2 = GetInt();
	//通过寄存器传出的常量必须使用常引用
	
	//返回地址
	int *p1 = GetIntPtr();
	int *const& p2 = GetIntPtr();
	//返回引用
	
	int ret4 = GetIntRef();
	int &ret5 = GetIntRef();
	int *pret6 = &GetIntRef();//返回引用的时候直接自动解引用,可以直接替换。
	return 0;
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值