C/C++ 函数返回值

函数返回局部变量的原理:

一般说来,函数中是可以进行局部变量的返回的,不然岂不是全部要用全局变量,如果使用了全局变量,那还有必要进行返回吗?那函数就没有它存在的意义了!但是要注意了,这里所谓的局部变量的返回很有内涵,什么样的值才可以进行返回而不出错?

其实,只要遵守一句话即可:函数不能返回指向栈内存的指针!

为什么?因为返回的都是值拷贝


我们先看一个最普通的例子1:

#include <stdio.h>

int func()
{
	int a = 10;
	printf("&a = %p\n",&a);
	return a;
}
int main () {
	int A;
	printf("&A = %p\n",&A);
	A = func();
	printf("%d\n",A);
	return 0;
}

执行结果:

       我们知道,局部变量的作用域是函数内部,函数一旦执行结束,栈上的局部变量会进行销毁,内存得到释放。因此,此时函数返回的是该局部变量的值拷贝,这是没有问题的。但是如果返回的是局部变量的地址,那么返回的只是该局部变量指针的拷贝,而随着函数运行结束,该拷贝指针所指向的栈内存已经被释放,那么指向一个未知区域就会导致调用的错误。

      那如果返回的指针指向的是堆内存,又会怎么样?

      这样的使用是没有问题的,在函数内new空间,在函数外delete空间。但是这样并不是一种好的编程风格,尽量在同一个作用域内进行new和delete操作,否则还要调用者手动进行内存的释放,试问这样的接口是不是很烂。如果确实需要这样做,那就传指针进去吧!

函数返回值为值对象,指针,引用

函数返回临时对象,如下例子2:

#include <iostream>
#include <string>

using namespace std;

string func()
{
	string a = "hello world";
	cout << "&a = " << &a << endl;
	return a;
}

int main () {
	string A;
	cout << "&A = " << &A << endl;
	A = func();
	cout << A << endl;
	return 0;
}

执行结果:

与例子1结论是一样的,函数返回string是值拷贝,但是拷贝的工作是string类的拷贝构造函数进行的(但是是gcc做了优化,返回值为对象时,不再产生临时对象,因而不再调用复制构造函数。函数返回值是对象的值,调用对象的拷贝构造函数?)。

但是将上面例子使用C语言改写一下,返回值是指向字符串的首地址的指针,如下例子3:

#include <stdio.h>

char* fun()
{
    char a[12] = "hello world";
    printf("a = %p\n",a);
    return a;
}

int main()
{
    char *p;
    printf("p = %p\n",p);
    p = fun();
    printf("p = %p\n",p);
    printf("%s\n",p);
    return 0;
}

执行结果:

运行结果虽然没有error,但是运行结果不是我们想要的结果(乱码)。

通过warning知道:函数返回局部变量的地址。

分析:回到函数返回值的本质——值拷贝。通过打印结果也能看出,p被赋值后的值与a的值是一样的,只是函数fun结束,a[12]局部变量被销毁,所以p指向的地址(0x7fff81c45b20)所对应的值被销毁了,所以打印乱码了。

将第5行改为:

char* a = "hello world";

运行成功,也是想要的结果。这是因为"hello world"是常量,并不是在栈区的内存,所以函数结束,该常量还是存在的。

但是将上面例子使用C++语言再改写一下,返回值是返回字符串引用,如下例子4:

#include <iostream>
#include <string>

using namespace std;

string& func()
{
	string a = "hello world";
	cout << "&a = " << &a << endl;
	return a;
}

int main () {
	string A;
	cout << "&A = " << &A << endl;
	A = func();
	cout << "&A = " << &A << endl;
	cout << "A = " << A << endl;
	return 0;
}

执行结果: 

运行结果虽然没有error,但是运行结果不是我们想要的结果(空)。

通过warning知道:函数返回局部变量的地址。

分析:与返回指针的例子道理是一样的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值