函数返回局部变量

今天和同学讨论了函数返回局部变量,这里有许多的细节,在这里做一下总结

函数返回局部变量一定要注意,要区分两点:

1、分清楚返回的是局部变量的值还是地址;

2、分清楚返回的是否是栈区

如果返回的是值就可以,不涉及地址就不会出错;如果返回的是全局区/堆区的变量,无论是返回值、地址都可以

局部变量作用域只在函数内部,在函数返回后内存被释放。只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错

总之---时刻牢记返回的是值还是地址,如果是地址,不能返回栈区的变量的地址

例子如下:

首先内存广义分为全局区、代码区、堆区、栈区(其实还可以分的很细,后面还会再总结,在这里都是为了更好理解返回局部变量)

#include <stdio.h> 
//1、返回的值是字符串常量的首地址,但“hello”是一个字符串常量,存放在只读数据段(全局区),在re1函数返回后内存不会被释放(整个程序运行结束才会释放),故不会出错
char *re1() 
{ 
    char *p="hello"; 
    return p; 
} 
//2、返回的是字符数组(数组中存放字符串)的首地址,其返回的是地址并且存放在栈区,在re2函数返回后栈区内存释放,内存地址已经释放,所以地址中存放的内容未知,不可行
char *re2() 
{ 
    char p[]="hello"; 
    return p; 
} 
//3、返回的是字符数组(数组中存放字符串)的首地址,但其被声明为static类型,其返回的地址存放在全局区,可行
char *re3() 
{ 
    static char p[]="hello"; 
    return p; 
} 
//4、f1返回一个局部变量的值,无论这个值在哪个区都不会出错;f2返回地址,并且返回的是存放在栈区的变量地址,不可行(可以加static,可行)
int f1()
{
      int a;
       a = 10; 
      return a;    //允许
}                   
int * f2()
{
      int a;
      a = 10;
      return &a;    //无意义,不应该这样做
} 
//5、C++返回类型是int &, f3返回一个局部变量的引用(a的副本),需要说明的是在接收引用时,有两种接受方法:(现在粗暴的理解为用int接收就是值,用int&接收就是地址)
//        1、int d1 = f3;//返回一个a的副本10,用d1接收,不涉及地址,可行
//        2、int &d2 = f3;(内部会*d2)相当于返回一个内存空间,然后给内存空间起了一个别名d2,d2和f3指向同一片地址空间,但是这片地址空间已经被释放了,不可行
int & f3()
{
      int a;
      a = 10;
      return a;    
} 
//6、返回指向堆内存的指针是可以的,因为堆区地址只要不手动释放就一直存在

char *re4(int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}

int main() 
{ 
    char *a; //字符串常量在c中这样接收,但在C++中使用const char * a接收
    a = re1(); 
    char *b;  //字符数组c和C++都是这么接收的
    b = re2();
    char *c;
    c = re3();
//f3的两种接受方法
    int d1 = f3;
    int &d2 = f3;
    
    return 0; 
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值