本人微信公众号"aeolian"~

C++函数返回值(02)

对象作为返回值

编译器会将函数栈中的返回值数据拷贝到返回栈中

指针作为返回值

函数的返回值可以是存储某种类型数据的内存地址,称这种函数为指针函数。它们的一般定义形式如下:  类型标识符 *函数名(参数列表);  在C++中,除了内存分配失败之外,new不会返回空指针,并且没有任何对象的地址为零。指针所指向的对象的生存期不应低于该指针的生存期。

用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。

#include 
int *func(){
  int n = 100;
  return &n;
}
int main(){
  int *p = func(), n;
  n = *p;
  printf("value = %d\n", n);
  return 0;
}

运行结果:

value = 100

既然func函数执行结束,那么func()函数内的局部变量就应该被销毁,但是这里可以取到值,这个就很奇怪,修改一下

#include 
int *func(){
  int n = 100;
  return &n;
}
int main(){
  int *p = func(), n;
  printf("c.biancheng.net\n");
  n = *p;
  printf("value = %d\n", n);
  return 0;
}

运行结果:

c.biancheng.net
value = -2

前面说函数运行结束后会销毁所有的局部数据,这个观点并没错,大部分C语言教材也都强调了这一点。但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存。对于上面的两个例子,func() 运行结束后 n 的内存依然保持原样,值还是 100,如果使用及时也能够得到正确的数据,如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。

引用作为返回值

函数返回引用,要求在传参里必须有引用或者指针类型作为被返回的值。

传参用引用
#include   
#include   
  
int func(int& t)  
{  
    return t;  
}  
  
int main(int argc, char * argv[]) {  
    int a=0;  
    int b=func(a);  
    printf("&a=0X%08X,&b=%08X\n",&a,&b);  
    printf("a=%d, b=%d", &a, &b);  
    printf("a=%d, b=%d", a, b);  
    return 0;  
}  
输出:
&a=0X0022FF4C,&b=0022FF48  //十六进制变量地址
a=2293580, b=2293576;  //十进制变量地址
a=0, b=0  //变量值

函数返回值和传参都用引用

#include   
#include   
  
int &func(int& t)  
{  
   return t;  
}  
  
int main(int argc, char * argv[]) {  
  
  int a=0;  
  int b=func(a);  
  printf("&a=0X%08X,&b=%08X\n",&a,&b);  
  printf("a=%d, b=%d", a, b);  
  return 0;  
}

输出是:
&a=0X0022FF4C,&b=0022FF48
a=0, b=0

函数返回值用引用,传参用指针

#include   
#include   
  
int &func(int* t)  
{  
      return *t;  
}  
  
int main(int argc, char * argv[]) {  
  
      int a=0;  
      int b=func(&a);  
      printf("&a=0X%08X,&b=%08X\n",&a,&b);  
      printf("a=%d, b=%d", a, b);  
      return 0;  
}  

输出:
&a=0X0022FF4C,&b=0022FF48
a=0, b=0

 

点赞

Leave a Reply

Your email address will not be published. Required fields are marked *