C return语句在哪里保存数据? #包括 int-add(int,int); int main() { INTA; a=添加(5,7); printf(“%d”,a); } 整数相加(整数x,整数y) { x=x+y; 返回(x); }

C return语句在哪里保存数据? #包括 int-add(int,int); int main() { INTA; a=添加(5,7); printf(“%d”,a); } 整数相加(整数x,整数y) { x=x+y; 返回(x); },c,C,昨晚我对退货声明有疑问。参见x是在add函数中定义的一个自动变量,正如ANSI所说,自动变量存在且仅在函数中存在,但这里的return语句可以使变量a甚至存在于函数之外。它在哪里存储值?堆栈还是堆?既不在堆栈上,也不在堆上 至少在x86体系结构中,函数的返回值通常被复制到eax寄存器中,因此它在函数外部保持不变。这就是为什么不能返回数组而只能返回指向它的指针的原因之一 但是,您可以按值返回结构和其他较大的变量,在这种情况下,编译器会使用堆栈和附加寄存器(如edx)执行一些操作。add函数的返回值

昨晚我对退货声明有疑问。参见
x
是在
add
函数中定义的一个自动变量,正如ANSI所说,自动变量存在且仅在函数中存在,但这里的
return
语句可以使变量a甚至存在于函数之外。它在哪里存储值?堆栈还是堆?

既不在堆栈上,也不在堆上

至少在x86体系结构中,函数的返回值通常被复制到
eax
寄存器中,因此它在函数外部保持不变。这就是为什么不能返回数组而只能返回指向它的指针的原因之一


但是,您可以按值返回结构和其他较大的变量,在这种情况下,编译器会使用堆栈和附加寄存器(如
edx

)执行一些操作。add函数的返回值会复制回主函数中的“a”。函数中声明的自动变量存在于调用堆栈上该函数的激活记录中,并且在将任何返回值复制回调用方变量后,在函数执行结束时删除激活记录。

它存储在我所知的大多数平台的寄存器中,但这可以通过编译器实现来改变


值得注意的是,虽然
return x
中x是一个值而不是指针,例如在您的情况下是合法的,但是如果
x
是指针,您应该确保它指向的缓冲区/数据在函数返回时是有效的,否则,它将是指向无效位置的有效指针。

如果您是CS学生,这很可能在编程语言课程中涉及。不管怎样,你可以去看看


实际上,它存储在.

中,
返回
的实际功能取决于编译代码的机器体系结构。在带有寄存器的机器上,
x
的值被复制到寄存器中。调用者将从那里获取值并对其进行处理。在这里,该值被复制到名为
a
的变量中

如果此代码是在堆栈计算机上编译的,则返回值可能正好留在堆栈本身上。调用
add
函数的目标代码如下所示:

#include<stdio.h>

int add(int,int);

int main()
{
    int a;
    a=add(5,7);
    printf("%d",a);
}

int add(int x,int y)
{
    x=x+y;
    return(x);
}

add
将弹出堆栈中的值,将它们相加,并将结果推回到堆栈中。(如果函数处理的数据结构在堆栈上的插槽中找不到,则会推送它们的地址。)
seti
是一种操作,它将从堆栈中弹出一个值,并将其分配给特定地址处的整数变量。(这里,
0x28ccf4
a
的地址)。由于堆栈顶部现在将包含添加
5
7
的结果,
a
的值将变为
12

情况各不相同。在典型情况下,您可以指望在某些寄存器(例如,x86上通常是eax,MIPS上通常是v0-$v1,ARM上通常是r0)中返回小于等于
int
大小的任何内容

在许多计算机上,较大的返回值(例如,具有多个成员的结构)将导致调用方在堆栈上分配空间来保存返回值,并将指向该空间的指针作为隐藏参数传递给函数,或者函数隐式知道该空间相对于的位置(例如)输入函数时的堆栈指针


虽然问题是标记C,但我也要提到C++中有一些关于返回值的特殊规则。具体来说,有一个返回值优化和一个命名的返回值优化。这些允许编译器删除用于复制返回值的代码,即使(例如)副本通常会有明显的副作用。这些函数用于优化函数在调用代码需要时构造返回值,而不是在函数中本地构造返回值,然后复制回调用代码可以使用的地方。

事实上我是一名电子专业的学生。但对编程很感兴趣。所以我把工作转移到了这些方面。@niko如果你喜欢这种东西,我推荐一本名为《编程语言语用学》的书,这是一本激动人心的书,它可能会让你比大多数人更了解语言。是的,C是一种“基于堆栈的”语言。Niko如果你想知道退货是如何处理的,你可以试试这个。您还可以阅读一篇关于C代码如何在机器代码中翻译的文章,在堆栈上推送参数和返回值并检索它们。使用堆栈只是一种可能的实现,语言不需要任何东西。也许你要补充的是,对于更大的/复杂的值和浮点值,它将不适用。更大的类型(如float/structure)将被推到堆栈上。我对你的答案不太满意,我发现它太具体了:C是一种基于堆栈的语言,因此,无论架构如何,退出函数时都应将返回值推送到堆栈上。现在,你说得对,当微体系结构允许时,编译器可以执行一些优化,比如将它推到未使用的寄存器上以加速函数返回,但这不应被视为通用性。@Gui-C不是基于堆栈的语言。使用堆栈只是一种可能的实现,语言不需要任何东西。在您的帖子中,真正的问题是,为什么值仍然存在于
add
函数之外,而不是为什么变量仍然存在。您能否访问
x
变量外部的
add
功能?不,它已经不存在了。
push 7
push 5
call add
seti 0x28ccf4