C语言函数中局部变量的返回
来源:互联网 发布:dede分类目录源码 编辑:程序博客网 时间:2024/05/18 00:59
http://blog.csdn.net/misskissc/article/details/10757975
http://blog.csdn.net/jackystudio/article/details/11523353
C/C++中,函数内部的一切变量(函数内部局部变量,形参 )都是在其被调用时才被分配内存单元。子函数运行结束时,所有局部变量的内存单元会被系统释放。形参和函数内部的局部变量的生命期和作用域都是在函数内部( static变量的生命期除外)。
在C中,函数被调用时的传参方式有两种形式:传值和传址。
传址的好处:
(1)能在函数内部通过实参地址间接地改变实参的值。
(2)当所传实参内容比较庞大时,传址只是复制了整个实参的地址过去,指针依据同一个地址访问实参变量。而传值就会将实参内容整个拷贝过去,形参会跟实参占一样大的内存,栈空间是有限的。当然了,在弱小的程序中,传址的这个优点不会被体现出来。
在函数中,可以随意的返回一个局部变量。但如果返回一个局部变量的地址(指针 ),编译器就会给出警告(编译器也不可能那么完美能够彻底的检查出段错误)。在函数内部返局部指针这的确是一个危险的操作。
Linux等的C语言中return返回值的机制为:将返回值存入eax寄存器中,然后系统再将eax中的值赋给变量(i)。
其实,只要遵守一句话即可:函数不能返回指向栈内存的指针!
为什么?因为返回的都是值拷贝!
我们知道,局部变量的作用域是函数内部,函数一旦执行结束,栈上的局部变量会进行销毁,内存得到释放。因此,此时函数返回的是该局部变量的值拷贝,这是没有问题的。但是如果返回的是局部变量的地址,那么返回的只是该局部变量指针的拷贝,而随着函数运行结束,该拷贝指针所指向的栈内存已经被释放,那么指向一个未知区域就会导致调用的错误。
1.正确。最normal的情况。
int returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<returnValue(); return 0;}char returnValue(){ int value=3; return value;}
2.错误。最normal错误。虽然value被释放,但是它的值不一定会被清除,所以有时候你这么用看起来结果好像也是对的,但是隐患无穷。
int* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<*(returnValue()); return 0;}int* returnValue(){ int value=3; return &value;}
3.正确。不用奇怪,“HelloJacky”是一个字符串常量,储存在只读数据段,return str只是返回了该字符串在只读数据段所在的首地址,当函数退出后,该字符串所在的内存不会被回收,所以是正常的。
char* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<returnValue(); return 0;}char* returnValue(){ char* str="HelloJacky"; return str;}
4.错误。这一回“HelloJacky”是栈内的局部变量,函数退出时内存被释放,因此返回栈内局部变量的地址是错误的。
char* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<returnValue(); return 0;}char* returnValue(){ char str[]="HelloJacky"; return str;}
5.正确。如果你非要返回一个局部变量的地址,那么加上static吧。
char* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<returnValue(); return 0;}char* returnValue(){ static char str[]="HelloJacky"; return str;}
6.错误,一样的,数组也不能作为函数的返回值,因为数组名其实是局部变量的首地址。
int* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<*(returnValue()); return 0;}int* returnValue(){ int value[3]={1,2,3}; return value;}
7.正确。加上static修饰符吧,那数组也可以返回了。
int* returnValue();int _tmain(int argc, _TCHAR* argv[]){ std::cout<<*(returnValue()); return 0;}int* returnValue(){ static int value[3]={1,2,3}; return value;}
8.正确。函数内申请空间,调用后释放空间,只是这样做的坏处就如上面所说接口不灵活。
char* newMemory(int size);int _tmain(int argc, _TCHAR* argv[]){ char* p=newMemory(2); if(p!=NULL) { *p='a'; } std::cout<<*p; delete [] p; return 0;}char* newMemory(int size){ char* p=NULL; p=new char[size]; return p;}
- C语言中函数返回局部变量的方法
- C语言函数中局部变量的返回
- C语言之函数返回局部变量
- C语言---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言函数不能返回局部变量的地址
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- C语言的那些秘密之---函数返回局部变量
- 线程实现打字小游戏代码
- 四个默认成员函数和运算符重载
- db2数据导入编码问题
- ios设备中 h5页面 点击 会出现闪一下 或者 黑一下
- 13、Python time&timeit 模块
- C语言函数中局部变量的返回
- git常见问题
- 为什么在集合框架中已经继承了抽象类还要实现接口
- 哪种公司能干 哪种不能
- JavaScript正则表达式学习笔记
- 统计代码行数
- Android之实现倒计时的那点事儿
- 模板匹配
- android 沉浸式设计方案总结