return 语句在 C 中如何工作?

How does the return statement work in C?

我有一个关于 C 中的 return 语句的问题,它实际上是 returns:

int base(int a)
{
   if(a == 1)
     return 0;
}

int inherit()
{
   base(1);
   // the rest of the code
}

所以在inherit()函数中,调用了base(),在本例中它执行了return 0inherit() 中的其余代码是否仍然执行? return 语句如何真正起作用?

因为您没有 return 编辑 base 的结果,所以 inherit 没有理由不执行其余的行。

函数继续执行,直到到达 return 语句。在 inherit 中,它遇到了一个函数调用 - base。调用一个 return 值的函数并不意味着 return 那个结果。

例如,如果有人派我去商店取收据 - 那家商店给了我收据并不意味着我一定把它给了最初派我来的人。

另一方面,这将 return base 的结果并且不会执行其余代码。

int inherit()
{
   return base(1);
   // the rest of the code
}

如果您在代码中调用 return,该函数中的代码将在到达该点后停止工作。然后控件将移回调用它的函数,或者程序将结束,具体取决于 return 在程序中的位置。

当然是继续执行剩下的代码了。 base 方法 return 仅在其中的显式 return 上。这也适用于 inherit 方法。

如果您想要 inherit 方法 return base 的值,请添加 return 关键字。

int inherit()
{
   return base(1);
   // the rest of the code can now be left out actually
}

吹毛求疵: 在您的示例中,编译器可能会抱怨,因为在 a != 1 的情况下没有 return 值。 所以你必须添加类似

的内容
int base(int a)
{
   if(a == 1)
     return 0;
   else
     return 1;
}

So within the inherit() function, base() is called, and it return 0, in this case, does the rest of code in inherit() still execute?

是的,它会执行。 return in function base 会将控制权(或 value )交还给调用函数。

然后调用函数 inherit() 的其余部分将被执行,直到其作用域结束或在 inherit() 中遇到 return

注意 - 如果不满足 if 条件,函数 base 也应该 return 值。正如其他人所指出的,如果不是,它将调用未定义的行为。

是的,在调用base()之后,代码会继续运行,但是undefined behavior.下面的编辑说明了捕获 return 值并在分支语句中使用它。您应该始终为非空函数包含一个 return 语句:

int base(int a)
{
   if(a == 1)
     return 0;
   else return -1;//function is provided alternative return path
}

int inherit()
{
   int status = base(1);
   if(status == 0)
   {
      // the rest of the code
   }
   return status;
}

return 语句 return 是调用者可以使用的值。 return 值不会影响调用者代码中的任何内容,除非调用者使用该值(例如检查 if 语句中的值)。一旦 return 被执行,被调用的函数停止执行并且所有局部变量都被释放。

return 语句可以 return 单个字大小的值,例如 int 或指针。在较新的 C 版本中,return 语句可以 return 复合值(例如结构);在这种情况下,编译器会立即执行复制操作,因为 struct returned 可能是被调用函数的局部(自动)变量。由于这些变量是在堆栈上分配的,它们将在调用者的下一次调用时被销毁(覆盖);因此,编译器必须立即保存它们。请注意 return 指向被调用函数的局部(自动)变量的指针是错误的,因为该变量将在 return 时被释放并且可能已被覆盖。

通常 returned 在寄存器中 returned。传统上,在英特尔中,这是 eax 寄存器。

示例:

 return i;    // return the value of an int.
 return p;    // return a pointer p

 struct MY_STRUCT S= {0};   // local struct S is on the stack
 return S;                  // return the whole structure
 //caller:
 struct MY_STRUCT S2= myFunction(); // compiler copies S to S2

struct MY_STRUCT S= {0};    // local struct S is on the stack
return &S;                  // return pointer to S !!error:
//caller:
struct MY_STRUCT *S= myFunction();  // S will be overwritten with nex call!!

如果你写

int inherit()
{
  int x=99;

  x=base(1);

  dothis();
  // the rest of the code
}

然后 x 现在是 0,程序进入下一行 dothis();

你的代码有点太简单了。我会更开心:

int base(int a)
{
    if (a == 1)
        return 0;
    return 37;
}

int inherit(void)
{
    int n = base(1);
    printf("Base(1) is %d\n", n);
    return n + 3;
}

inherit()调用base()时,它的当前状态被存储,函数base()是运行,它return是一个值。在此代码中,return 值在变量 n 中捕获,然后在 printf() 调用和 inherit() 中的 return 中使用。这就是 return 的工作原理:它单方面停止当前函数的执行并继续调用函数。

即使在 main() 中,return 会终止当前函数,并且 return 会向调用函数发送一个值,即 C 运行time — 以及 C 运行time 确保进程退出,通常将 returned 值中继到 'environment'(例如 Unix 上的 shell 程序)。

请注意,修改后的代码确保 base() 始终 return 是一个值。不这样做通常会导致未定义的行为。如果仅使用值 1 作为参数调用该函数,则它将是 'OK',但您为什么首先调用该函数。因此,始终确保如果一个函数应该 return 一个值,那么函数中的所有 returns(特别是包括函数末尾的那个)returns a价值。在原始代码中,末尾没有 return — 这很糟糕!

不考虑遗漏 return 值的明显错误:

int inherit(){
 int return_value =  base(1);
 // ------^
 // the rest of the code
}

How does the return statement really work?

对于函数调用(在您的情况下 inherit() 调用 base()),我们需要 return 到函数调用之后的指令,以便程序继续执行循环。这个return需要两条信息:

1.一条return语句表示函数执行结束,在低级和高级语言中具有相同的语义。1

2.Return 地址:处理器如何知道在完成函数调用后return 去哪里?这条信息通常在调用函数时存储。因此,当函数被调用时,除其他外 2,return 地址被存储。主要使用两个特殊的地方:一个特殊的寄存器或堆栈。因此,当到达 return 语句时, 控制流 被转移到 函数调用 [=48 之后的指令地址=]3.

除此之外,您还可以 return 特定值,例如计算等的结果,如函数签名中预定义的 returning type 其值对执行是否继续没有直接影响。在您的情况下,如果您 return 来自函数 base() 的任何其他类型 int 的有效值,它将对其余执行具有未定义的含义,因为 base() 确实没有为所有可能的输入提供 return 语句,这将导致 未定义的行为

Does the rest of code in inherit() still execute?

对于您调用它的值,即:1 它会在 base() 函数 return 的值之后继续执行 inherit() 中的任何内容。


1.高级语言允许默认的 fall-through 机制。也就是说,如果我们没有明确指定过程的结束,控制将在块的末尾 returned。

2。修改 PC(程序计数器)。

3。实际存储的 return 地址取决于处理器。一些 SPARC 等处理器存储调用指令本身的地址。其他 例如 MIPS 和 Pentium 存储调用后指令的地址 说明.

C is Procedure Oriented Programming langauge and unlike OOP the focus is on is on variable, Data Structures & Subroutines.(However here OOP also works the same way)

当您的程序在

中执行时

int inherit() function

它调用

int base(int a)

为 a.This 提供值 1 是一个 subroutine.Since,子例程本质上是一组由程序员出于各种原因分组的计算指令,这些原因可能是易于编码或更好的组织,等等

base(1); 子程序完成执行后,下一条指令 loaded/executed 是紧随其后的指令。

现在您需要知道您的 inherit() 函数一直在执行,直到遇到向 stop.the 发出信号的代码,其中最常见的是

exit(0);//exit entire program
return val;//where val stores an integer(control returns to calling function,or program exits if it the only function

上面的代码在 function/routine 中执行后,同一函数中它下面的所有代码都不会执行)

您甚至可以通过键入 :

从 void 函数中 return
return;

return 语句的行为由 ISO C 标准定义。引用 N1570 草案,第 6.8.6.4 节:

A return statement terminates execution of the current function and returns control to its caller. A function may have any number of return statements.

If a return statement with an expression is executed, the value of the expression is returned to the caller as the value of the function call expression. If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.

所以如果你有这样的函数:

int func(void) {
    return 42;
}

你从其他函数调用它(或者甚至从同一个函数;参见递归):

#include <stdio.h>
int main(void) {
    int result = func();
    printf("%d\n", result);
}

那么函数调用 func() 是一个 表达式 产生值 42.

用 return 类型 void 定义的函数没有 return 值。此类函数中的 return 语句只是没有表达式的 return;。它终止函数的执行,但没有值被 returned.