zoukankan      html  css  js  c++  java
  • c/c++排坑(4) -- c/c++中返回局部变量

    返回c语言中的局部变量

    先看一段代码猜猜,打印值:

    #include <iostream>
    using namespace std;
    char * func();
    int main()
    {
    	char *buf = func();
    	cout << "buf:" << buf << endl;
    }
    char * func()
    {
    	char buffer[3];
    	buffer[0] = '1';
    	buffer[1] = '2';
    	buffer[2] = '3';
    	return buffer;
    }
    

    或许你已经猜到了,会打印乱码的值。原因是返回了一个局部的变量,而局部变量再离开函数体之后就不存在了,char 指针指向不明的空间。那么如何改进这玩意儿呢?

    • 返回一个指向字符串常量的指针。
    char * func() { return "123"; } 
    
    • 使用全局声明的数组。
      这适用于自己创建的字符串情况,也很简单易用。它的缺点在于任何人都有可能在任何时候修改这个全局数组,而且该函数的下一次调用也会覆盖该数组的内容。
    • 使用静态数组。
      这就可以防止任何人修改这个值,但是该函数的下一次调用将覆盖整个数组的内容,所以调用者必须在此之前使用或备份数据的内容。和全局数组一样,大型缓冲区如果闲置不用是非常浪费内存空间的。
    char * func()
    {
    	static char buffer[3];
    	buffer[0] = '1';
    	buffer[1] = '2';
    	buffer[2] = '3';
    	return buffer;
    }
    
    • 显示分配一些内存,保存返回的值。整个方法其实挺不错的,但是缺点也非常明显,程序员必须承担内存管理的责任。我的天,在函数外还能想着给函数内的内存做释放的家伙得多变态。所以...嗯...我是受不了这种做法。
    char * func()
    {
    	char * buffer = malloc(10);
    	...
    	return buffer;
    }
    
    • 调用者分配内存来保存函数的返回值。为了提高安全性,调用者应该同时指定缓冲区的大小。
    char * func(char * result, int size)
    {
    	...
    	strncpy(result, "something", size);
    }
    
    buffer = malloc(size);
    func(buffer, size);
    ...
    free(buffer);
    

    如果程序员可以在同一代码中同时进行malloc和free操作,内存管理是较为轻松的。

    C++的一些情况

    C++中当然在普通情况下和c无异。但是考虑如下代码,看看会打印啥:

    #include <iostream>
    #include <string>
    
    using namespace std;
    string func1();
    
    int main()
    {
    	string str = func1();
    	cout << "str:" << str << endl;
    }
    string func1()
    {
    	string str("str123");
    	return str;
    }
    

    哈哈,显然你已经猜到不会打印乱码了。为啥同样是局部变量,string类型不会打印乱码呢。这是因为在C++中,返回的时候会有一个临时变量来保存这个返回值哦。同样的在输入的时候也是通过生成临时变量传参的。考虑如下代码:

    void func(Object obj)
    {
    	...
    }
    

    如果Object 是一个复杂的对象,那么其实是非常影响性能的,可考虑改成如下的代码:

    void func(const Object &obj)
    {
    	...
    }
    

    咦,是不是很熟悉呢。其实很多代码都是这样做的哈。这里的const表示不可修改,其实const关键字还真是容易让人理解错呢,将const理解成readonly大多数情况下不会错。

    See you next time. Happy Coding!!!
    我的github

  • 相关阅读:
    SQL SERVER 2000 配置文件 SETUP.INI
    (转)Sybase ASE基础知识:利用Sybase Central简单操作Sybase ASE数据库
    新软发布:Autorun病毒免疫工具
    vc 编程最需要注意的地方
    (转)不得不了解VB中的CallByName
    作业总结
    (转)傻瓜式简单制作Windows7旗舰版免激活光盘镜像教程 (安装后自动激活)
    发布C#模块:平面凸包的计算
    凸包计算模块ConvexHull的使用方法
    模块发布——树类模块
  • 原文地址:https://www.cnblogs.com/dnhua/p/10092126.html
Copyright © 2011-2022 走看看