首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

关于返回值的疑义

2012-12-24 
关于返回值的疑问最近看了几篇帖子基本都是对返回值的疑问有一点我也不是很明白调用函数中的变量是一个局

关于返回值的疑问
最近看了几篇帖子
基本都是对返回值的疑问
有一点我也不是很明白
调用函数中的变量是一个局部变量,生命期是函数级的,函数执行完毕,局部变量就被释放,当然是不能进行返回的
但是我测试了下,下面的却可以返回,局部变量不是存储在栈里面吗,函数完毕,就自动释放了
为什么下面的执行正确

#include <stdio.h>
int sum(int a,int b)
{
int s;
s=a+b;
return s;
}
int main(void)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",sum(a,b));
return 0;
}


但是下面的却又执行不正确
#include <stdio.h>
char*GetMemory(void)
{
char p[]="hello world";
return p;
}
int main(void)
{
char *str=NULL;
str=GetMemory();
printf(str);
return 0;
}


都是局部变量,为什么一个正确一个错误
一个传值,一个传地址,这里面的区别我知道
但是都作为局部变量,这个就有点说不通了
求各位指正
[最优解释]
局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是不涉及函数中变量地址的。如果要返回引用,也就是变量地址,那么它会把这个变量的地址放在eax中,(注意这个地址是位于函数的栈空间里的,出了这个函数,这块内存就会被系统标记为可占用(就是其它程序可以占用)),回到主函数后系统会把这个地址赋值给主函数中的指针变量。此时主函数中的指针变量就指向了一个已经被标记为可占用的内存空间。如果你在不同的时刻输出这个指针所指地址的值会输出不同的结果
[其他解释]
char*GetMemory(void)
{
    char p[]="hello world";
    return p;
}
你這個p是返回了;但是p指向的空間是在棧上,函數退出就無效了,被釋放了。
[其他解释]
第二个错误的代码改成:
p[]改成 * p就行了:
#include <stdio.h>
char*GetMemory(void)
{
    char * p="hello world";
    return p;
}
int main(void)
{
    char *str=NULL;
    str=GetMemory();
    printf(str);
    return 0;
}
[其他解释]
#include <stdio.h>
char*GetMemory(void)
{
char *q=NULL;
char p[]="hello world";
q=p;
return q;
}
int main(void)
{
char *str=NULL;
str=GetMemory();
printf(str);
return 0;
}

这样也是不行的
[其他解释]
引用:
char*GetMemory(void)
{
    char p[]="hello world";
    return p;
}
你這個p是返回了;但是p指向的空間是在棧上,函數退出就無效了,被釋放了。

恩,这个我理解,前面加个static的关键字是可以解决的,让其生命期进行延长
但是我的疑问是为什么第一个函数里面的也是局部变量,为什么函数结束的时候却没有释放?而是可以进行传递?
[其他解释]
引用:
局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是不涉及函数中变量地址的。如果要返回引用,也就是变量地址,那么它会把这个变量的地址放在eax中,(注意这个地址是位于函数的栈空间里的,出了这个函数,这块内存就会被系统标记为可……

你的意思就是传值的话,就是一个简单的压栈和出栈的操作,不涉及到地址的问题,函数结束,就进行出栈的操作,在主函数中把这个变量传递给另外的变量或者输出,这是没问题的
但是指针的话,是存储在空间栈上的,函数退出就自动销毁了,但是这样来说的,上面的函数不也是这样吗?这一点有点小纠结了
[其他解释]
改成静态变量的话是可以解决这个问题的
#include <stdio.h>
char *GetMemory(void)
{
static char p[]="hello world";
return p;
}
int main(void)
{
printf("%s\n",GetMemory());
return 0;
}

------其他解决方案--------------------


引用:
第二个错误的代码改成:
p[]改成 * p就行了:
#include <stdio.h>
char*GetMemory(void)
{
    char * p="hello world";
    return p;
}
int main(void)
{
    char *str=NULL;
    str=GetMemory();
    p……


这个我知道
字符串常量是存放在静态区,我刚才在另外的帖子里面就是帮别人这样改的,呵呵
只是由那个帖子引发了一些对返回值的疑问而已
就是为什么指针返回会发生错误,数值返回就没错误
不过还是谢谢你的解答
[其他解释]
引用:
引用:局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是不涉及函数中变量地址的。如果要返回引用,也就是变量地址,那么它会把这个变量的地址放在eax中,(注意这个地址是位于函数的栈空间里的,出了……


在被调用的函数结束后,其返回值存储在寄存器eax中,在主函数中直接从这里读取,但是如果这里存储的是一个地址的话(即返回值为指针的函数),这个地址的值是不变的,但是它还要去找这个地址所对应的值,这个值在另外一个地方,但这个值所在内存会被系统标记为可占用,有可能已经改变。
  不变的是寄存器eax中的内容。不同的是一个直接读取即可,而指针的话还要去找值。。
[其他解释]
引用:
引用:引用:局部变量是存在于栈中的,函数被调用时先在栈中为变量申请空间,调用完成释放变量空间。函数在返回参数的时候是这样的,先把要返回的数放在寄存器eax中,然后回到主函数中取出eax中的数值放在变量里,所以这样是不涉及函数中变量地址的。如果要返回引用,也就是变量地址,那么它会把这个变量的地址放在eax中……

恩,谢谢了
明白了

热点排行