在递归中使用return的位置

SHA*_*HAR 3 c python recursion greatest-common-divisor

在C这个代码工作,这里我没有使用return递归调用函数.它提供了正确的输出

int gcd(int a, int b)
{
    if(b == 0)
        return a;
    gcd(b, a % b);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在python中编写相同的代码,则此代码返回None(我认为值应该从if语句中的return语句返回)

def gcd(a, b):
    if b == 0:
        return a
    gcd(b, a % b)
Run Code Online (Sandbox Code Playgroud)

为了使这段代码有效,我必须添加return

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)
Run Code Online (Sandbox Code Playgroud)

但为什么?在C和Python中执行代码之间的差异是什么?如果我在递归调用时添加额外的返回,C中的代码也可以工作,为什么不抛出错误?

Ant*_*ala 7

为什么?错误的假设.顺便说一句,这不是关于Python的问题,而是关于C的问题.

您的C代码无效.它具有未定义的行为,因为您使用函数调用的返回值,其中控制路径未使用该return语句实际返回一个.如果使用正确的选项/设置进行编译,您的编译器可能会对此发出警告.即,这不是你编译C程序的方式:

% gcc -c 123.c
Run Code Online (Sandbox Code Playgroud)

相反,您启用所有警告,使其成为错误.例如在GCC -Wall-Wextra,-Werror-pedantic

% gcc -c 123.c -Wall -Wextra -Werror -pedantic
123.c: In function ‘gcd’:
123.c:6:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
cc1: all warnings being treated as errors
Run Code Online (Sandbox Code Playgroud)

不幸的是,有各种各样的坏代码,这意味着C编译器默认情况下比实际需要更宽松.另一个问题是return在C 中省略语句甚至没有错 - 只是使用垃圾返回值是.

Python没有类似C的未定义行为,因此当您省略return语句时,该函数会None隐式返回,并且您不会得到一些随机垃圾,看起来好像您的代码破坏了.


一个更正确的函数定义

int gcd(int a, int b)
{
    if(b == 0)
        return a;
    return gcd(b, a % b);
}
Run Code Online (Sandbox Code Playgroud)

然而,也许这些论点应该是unsigned ints,这样你就不会认为这对负数一直有效.