为什么 "Return" 不是必需的?

Why isn't "Return" necessary?

以下代码用于实验 https://cs50.harvard.edu/x/2021/labs/1/population/

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    //Prompt for start size
    int startPop;
    do
    {
        startPop = get_int("Starting population: ");
    }
    while (startPop < 9);
    
    //Prompt for end size
    int endPop;
    do
    {
        endPop = get_int("Ending population: ");
    }
    while (endPop < startPop);
    
    int Years = 0;
    
    while (startPop < endPop)
    {
        startPop = startPop + (startPop/3) - (startPop/4);
        Years++;
    }
   
    printf("Total Years: %i", Years);
    
}

为什么在收到每个整数后不使用 return?像这样

  int startPop;
    do
    {
        startPop = get_int("Starting population: ");
    }
    while (startPop < 9);
    return startPop;

我怎么知道何时何地使用它? return 的目的是什么?

似乎每次我尝试解决问题时,我都完全偏离了基础,甚至 where/how 都不知道如何开始,即使经过数小时的思考,然后解决方案也让我感到困惑。

return 将退出您当前所在的函数,并且该函数的其余部分将不会执行。如果它是一个非空函数,它也可能 return 来自该函数的值。这是一个例子:

int main(void)
{
    foo()
}

void foo()
{
    //...some code...
    return;
    //..some more code...
}

在这种情况下,将调用 foo 并将 运行 直到它命中 return,此时执行将 return 到 main,并且 foo 之后的所有代码main 不会执行。

在你的程序中,只有一个函数(main),从main调用return会退出程序(这不是我们想要的)。

main 末尾的 return XX 不是必需的,因为 C 标准是这样说的:

C18 §5.1.2.2.3 Program termination

... reaching the } that terminates the main function returns a value of 0.

换句话说,如果没有 return xx,则 int main() 函数被假定为 return 0

对于 return 值的所有其他函数,该函数必须显式 return 值。

对于 void 函数,return 语句是可选的。

Return 是告诉汇编程序创建 ret 指令的 C 语法。

什么是 ret 指令?来自 Intel's x86 manual:

RET — Return from Procedure
Transfers program control to a return address located on the top of the stack. The address is usually placed on the stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.

当您从一个函数(此处称为 过程)调用 and return 时,实际上您是在汇编级别执行以下代码:

push    rbp // push rbp (base pointer) to the stack
mov     rbp, rsp //  store rsp (stack pointer) into rbp.
...
mov     rsp, rbp // get back the value of rsp
pop     rbp // pop rbp from the stack
ret

"The caller" 是调用另一个函数 "the callee" 的原始函数。

请注意,默认情况下,C 语言会(正确地)假设每个函数都有一个 return 点,这就是为什么对于 void 函数和 main,一个书面的 return没有必要。

return 连同一个值(比方说 20)被翻译为(英特尔语法):

mov eax, 20
ret

跟你的问题有什么关系?

在您的示例中,没有调用被调用函数,您在函数内部执行代码(与添加“内联”时发生的情况相同)因此您当前正在计算的变量 startPop 不需要 return.

PS:顺便说一句,用 = 玩一会没有多大意义。