转来的 http://blog.csdn.net/haiwil/article/details/6691854/

一般的来说,函数是可以返回局部变量的。 局部变量的作用域只在函数内部,在函数返回后,局部变量的内存已经释放了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。但是如果返回的是局部变量的地址(指针)的话,程序运行后会出错。因为函数只是把指针复制后返回了,但是指针指向的内容已经被释放了,这样指针指向的内容就是不可预料的内容,调用就会出错。准确的来说,函数不能通过返回指向栈内存的指针(注意这里指的是栈,返回指向堆内存的指针是可以的)。

下面以函数返回局部变量的指针举几个典型的例子来说明:

1:

  1. #include <stdio.h>
  2. char *returnStr()
  3. {
  4. char *p="hello world!";
  5. return p;
  6. }
  7. int main()
  8. {
  9. char *str;
  10. str=returnStr();
  11. printf("%s\n", str);
  12. return 0;
  13. }
 

这个没有任何问题,因为"hello world!"是一个字符串常量,存放在只读数据段,把该字符串常量存放的只读数据段的首地址赋值给了指针,所以returnStr函数退出时,该该字符串常量所在内存不会被回收,故能够通过指针顺利无误的访问。

2:

  1. #include <stdio.h>
  2. char *returnStr()
  3. {
  4. char p[]="hello world!";
  5. return p;
  6. }
  7. int main()
  8. {
  9. char *str;
  10. str=returnStr();
  11. printf("%s\n", str);
  12. return 0;
  13. }
 

"hello world!"是局部变量存放在栈中。当returnStr函数退出时,栈要清空,局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以有可能打印出来的是乱码。

 

3:

  1. int func()
  2. {
  3. int a;
  4. ....
  5. return a;    //允许
  6. }
  7. int * func()
  8. {
  9. int a;
  10. ....
  11. return &a;    //无意义,不应该这样做
  12. }

局部变量也分局部自动变量和局部静态变量,由于a返回的是值,因此返回一个局部变量是可以的,无论自动还是静态,

因为这时候返回的是这个局部变量的值,但不应该返回指向局部自动变量的指针,因为函数调用结束后该局部自动变量

被抛弃,这个指针指向一个不再存在的对象,是无意义的。但可以返回指向局部静态变量的指针,因为静态变量的生存

期从定义起到程序结束。

 

4:如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型。如下:

  1. #include <stdio.h>
  2. char *returnStr()
  3. {
  4. static char p[]="hello world!";
  5. return p;
  6. }
  7. int main()
  8. {
  9. char *str;
  10. str=returnStr();
  11. printf("%s\n", str);
  12. return 0;
  13. }

5: 数组是不能作为函数的返回值的,原因是编译器把数组名认为是局部变量(数组)的地址。返回一个数组一般用返回指向这个数组的指针代替,而且这个指针不能指向一个自动数组,因为函数结束后自动数组被抛弃,但可以返回一个指向静态局部数组的指针,因为静态存储期是从对象定义到程序结束的。如下:

  1. int* func( void )
  2. {
  3. static int a[10];
  4. ........
  5. return a;
  6. }

6:返回指向堆内存的指针是可以的

  1. char *GetMemory3(int num)
  2. {
  3. char *p = (char *)malloc(sizeof(char) * num);
  4. return p;
  5. }
  6. void Test3(void)
  7. {
  8. char *str = NULL;
  9. str = GetMemory3(100);
  10. strcpy(str, "hello");
  11. cout<< str << endl;
  12. free(str);
  13. }

程序在运行的时候用 malloc 申请任意多少的内存,程序员自己负责在何时用 free释放内存。动态内存的生存期由程序员自己决定,使用非常灵活。

转来的。。。 关于return 的一些事情的更多相关文章

  1. jquery事件函数和原生事件绑定函数中return false的区别

    一直听说jquery中事件函数返回false,相当于调用了event.preventDefault()和event.stopPropagation()两个方法,今天就想看看dom中0级.1级.2级事件 ...

  2. MVC5 条件查询异步刷新

    学校要做一个数据查询,按条件并且能下载 20160312  使用HTML.ajax异步刷新 视图层 @Html.Partial("_men") <div class=&quo ...

  3. 130行C语言实现个用户态线程库——ezthread

    准确的说是除掉头文件,测试代码和非关键的纯算法代码(只有双向环形链表的ADT),核心代码只有130行左右,已经是蝇量级的用户态线程库了.把这个库取名为ezthread,意思是,这太easy了,人人都可 ...

  4. 【玩转开源】Linux C 检测网口热插拔

    int NetDetect(char *net_name, int *statue) { int ret = 0; ; struct ifreq ifr; skfd = socket(AF_INET, ...

  5. C++ vc中怎么使用SendMessage自定义消息函数

    vc中怎么使用SendMessage自定义消息函数: SendMessage的基本结构如下:SendMessage(    HWND hWnd,  //消息传递的目标窗口或线程的句柄.    UINT ...

  6. [转]VC传递消息sendmessage

    SendMessage的基本结构如下: SendMessage( HWND hWnd,  //消息传递的目标窗口或线程的句柄. UINT Msg, //消息类别(这里可以是一些系统消息,也可以是自己定 ...

  7. spring(13)------全面深入解析spring的AOP

    一,AOP的基本思想 AOP(Aspect Oriented Programming)翻译成中文的大意是面向切面编程,主要目的解决让不该牵扯在一起的代码分离开来. (1)认识AOP 应用程序中通常包含 ...

  8. QT+event() + 事件过滤器

    其存在的意义: mywidget.h: #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> namespace Ui { cl ...

  9. Javascript中Promise的简单使用

    // 函数功能:1秒以后创建一个10以内的随机整数,并判断这个数是否为偶数:如果是偶数则做一件事情,如果是奇数则做另一件事情 function doSomthing() { var promise = ...

随机推荐

  1. 一张图让你看懂各开源License[转]

    你是否遇到过开源License,精炼而又晦涩的文字通常要读半天才能理解,而且大多数License差别不大,容易混淆.下面这张图让你段时间迅速掌握各种开源的License. 图片来源:阮一峰的博客. f ...

  2. iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)

    iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接) 这里推荐两款好用的Xcode插件,并提供下载链接. 一.插件和使用如下: 1.两款插件 对项目中图片提供自动提示功能的插件:KSImag ...

  3. iOS开发UI篇—Quartz2D使用(矩阵操作)

    iOS开发UI篇—Quartz2D使用(矩阵操作) 一.关于矩阵操作 1.画一个四边形 通过设置两个端点(长和宽)来完成一个四边形的绘制. 代码: - (void)drawRect:(CGRect)r ...

  4. Swift学习

    Swift 中文教程(一)基础数据类型 基础类型 虽然Swift是一个为开发iOS和OS X app设计的全新编程语言,但是Swift的很多特性还是跟和Objective-C相似. Swift也提供了 ...

  5. 关于GSM基站定位

    一、基站定位两个参数 1、什么是LAC:Location Area Code(LAC)地区区域码,用来划分区域 2、什么是CellID:Cell Tower ID(Cid)CellID代表一个移动基站 ...

  6. Windows 95 vs. Windows 10

  7. 批处理与python代码混合编程的实现方法

    批处理可以很方便地和其它各种语言混合编程,除了好玩,还有相当的实用价值, 比如windows版的ruby gem包管理器就是运用了批处理和ruby的混合编写, bathome出品的命令工具包管理器bc ...

  8. juqey.html(),text(),val()

    .html()用为读取和修改元素的HTML标签 .text()用来读取或修改元素的纯文本内容 .val()用来读取或修改表单元素的value值. 这三个方法功能上的对比 .html(),.text() ...

  9. 安装生物信息学软件-Biopython

    其实好多东西装过好多次,然而每次都要翻文档,经常掉进前面掉进过的坑...所以这里重新写一份指南,以防下次再装又忘了(魂淡我并不想再装了啊不要立flag) 1. 安装biopython 1.1 因为bi ...

  10. Python 字符串关键字过滤

    问题:把给定字符串中的关键字用与关键字等长的“*”串代替. Solution: 方法1: string 中的 replace 函数 方法2: def censor(text, word): words ...