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

来源:互联网 发布:软件平台是什么 编辑:程序博客网 时间:2024/05/29 12:31

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

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

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

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

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

/****自定义类型返回值时才会产生临时量。返回指针不会产生临时量,返回引用的时候,它自身会解引用****///返回自定义类型的值时,分别用指针,值,引用来接收的情况//自定义一个类型DATAtypedef 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;}
0 0