当函数中返回值为值,指针,引用时,是如何带出和接收的?

首先我们需要知道的是,当返回一个值,指针,引用时(小于八个字节均可以由寄存器带出)

需要注意的是,由于举例,下面的例子中返回了局部变量的地址,而这是有风险的,不能返回临时的局部的地址或引用。仅供思路分析的参考

1.返回内置类型的值,引用,指针,分别用指针,值,引用接收的情况。

1)通过寄存器返回一个值
这里写图片描述
2)通过寄存器带出,返回一个指针。
这里写图片描述
3)返回引用时需要解引用,返回指针时只需要返回一个地址,
这里写图片描述
4)由于是寄存器返回的值不可取地址,而定义引用变量的右边必须可取地址,如果非要使用引用就需要使用常引用。不能用一个指针接受这个函数的返回值。这个例子是错误的。
这里写图片描述
5)
返回了一个整型值,用引用接收。
常引用在函数调用完成后产生临时量。
临时量存放在dword[ebp-8]处。
这里写图片描述
6)通过常指针引用来引用一个寄存器返回的地址,会产生一个临时量。
这里写图片描述
7)返回一个引用时,返回的时候寄存器带回的是地址,在主函数栈帧时,会自动解引用。那么引用就是引用了value这个变量。value可取地址。
这里写图片描述
也可以写成int *p =&GetIntRef();
p指向的是value的地址。

2.返回自定义类型的值,引用,指针,分别用指针,值,引用接收的情况。

/****自定义类型返回值时才会产生临时量。返回指针不会产生临时量,返回引用的时候,它自身会解引用****/

//返回自定义类型的值时,分别用指针,值,引用来接收的情况

//自定义一个类型DATA
typedef struct _DATA
{
  int a;
}DATA;

DATA GetData()
{
   DATA data={10};
   return data;
}

int main()
{
   //正确,返回值由寄存器带回的
   DATA ret1=GetData();

  //正确,这里要注意,虽然通过寄存器带回,这里返回的是自定义类型的值,引用时编译器会自动产生一个临时量,而内置类型不可以
   DATA &ret2=GetData();

   //VC认为不能指向自定义类型返回的(取地址在先,临时量在后),而vs和gcc均支持指针指向自定义类型寄存器带出的返回值 (当然VC是相对比较老的编译器,我们以VS和gcc为准,这是正确的)
   DATA *ret3=&GetData();

   return 0;
}

//返回自定义类型的指针时,分别用指针,引用来接收的情况
typedef struct _DATA
{
  int a;
}DATA;

DATA* GetDataPtr()
{
   static DATA data={10};
   return &data;
}

int main()
{
    //可以
   DATA *ret1=&GetDataPtr();

   //不可以,返回指针时,跟类型无关,指针跟编译器位数有关,指针永远通过寄存器返回,引用时使用常引用
   DATA *&ret2=GetDataPtr();
   return 0;
}

//返回自定义类型的引用时,分别用指针,引用来接收的情况
typedef struct _DATA
{
  int a;
}DATA;

DATA& GetDataPtr()
{
   static DATA data={10};
   return data;
}
int main()
{
    //可以,这里引用的是寄存器带回的解引用之后的变量值
   DATA &ret1=GetDataPtr();

   //可以
   DATA *ret2=&GetDataPtr();

   //不可以,这里等式右边的是寄存器带回的是一个常量,需要用const引用
   DATA *&ret3=&GetDataPtr();
   //const引用
   DATA *const &ret3=&GetDataPtr()
   return 0;
}

int *& GetIntPtr()//错误 ,能不能返回引用就看return之后的是否可取地址
{
  static int value=10;
  return &value;//寄存器带回的一个地址
}

int *const& GetIntPtr()//正确  返回常引用
{
  static int value=10;
  return &value;
}

int*& GetIntPtr()//正确
{
  static int value=10;
  static int *ptr=&value;
  return ptr; //可取地址
}

DATA *GetDataPtr()
{
   static DATA data={10};
   return &data;
}

int main()
{

  return 0;
}
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值