您好,登录后才能下订单哦!
这篇文章给大家分享的是有关C语言中return返回函数局部变量的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
在计算机中,释放空间并不需要将空间中的内容全部置成0或者1,而是只要设置这一块空间的数据无效即可。比如在下载文件时需要花很长时间,但是删除文件却只要几秒钟,这是因为操作系统只是把文件标识(文件头链接)删掉了,文件原文还保留着,我们没了文件标识就找不到这个文件了。所以删除后的文件,还可以用特殊的办法被找回来。
这也就意味着,当函数结束调用的时候,函数中的局部变量实际上还是在的,只是函数原来的空间还给编译器(释放)了,也就是说函数中的局部变量是可以被编译器修改的。
虽然函数结束后空间还给了编译器,但是我们依然可以通过指针找到对应的局部变量的空间。
通过上面的分析,如果我们返回局部变量的指针,是不是可以直接找到这个局部变量呢?
返回了一个局部变量的指针,而恰好局部变量偏偏又在函数结束后销毁,但指针并没有被销毁,而是被返回,那也就是说,指针指向的正是一个被销毁了的对象。
比如下面的代码:
#include <stdio.h> char* returnStr() { char p[] = "hello world!"; return p; } int main() { char* str; str = returnStr(); printf("%s\n", str); return 0; }
可以看到原来p的空间已经被修改了,但是很奇怪,是谁进行的修改呢?
通过调试可以发现,当函数结束后,运行printf打印之前,str指向的空间中的字符串是在的:
但是一运行printf打印操作,str指向的空间中的字符串就会被修改:
这其实很好解释,因为printf本身也是一个函数,函数都是在栈区开辟的,而函数开辟的空间叫做栈帧,函数结束栈帧就还给了编译器:
了解了这些,那是不是只要我们多建立几个函数栈帧,是不是就可以使returnStr的函数栈帧不被覆盖了?答案是肯定的:
#include <stdio.h> char* fun6() { char p[] = "hello world"; return p; } char* fun5() { return fun6(); } char* fun4() { return fun5(); } char* fun3() { return fun4(); } char* fun2() { return fun3(); } char* fun1() { return fun2(); } char* fun() { return fun1(); } int main() { char* str; str = fun(); printf("%s\n", str); return 0; }
不过随着函数栈帧的逐渐增多,原来的fun6函数空间迟早也会被覆盖。
在函数体内定义的局部变量是有临时性的,当局部变量释放后随时都有可能会被修改,所以我们不能通过指针使用已经被释放的局部变量。
如果我们不返回指针,而是返回局部变量会怎么样呢?
按理来说局部变量也会被修改。
#include<stdio.h> int test() { int a = 10; return a; } int main() { int b = test(); printf("%d", b); }
通过反汇编可以看到,局部变量a的值10通过寄存器交给了调用的b,所以即使局部变量a空间的10已经被修改,也不会影响b的内容:
如果返回只读字符串则不会被覆盖,因为数据不是在栈区,而是在静态区:
同理如果将字符串用static修饰也是如此:
另外,返回堆内的指针也是可以的。
感谢各位的阅读!关于“C语言中return返回函数局部变量的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。