C++ 为什么这个递归函数可以工作?

C++ 为什么这个递归函数可以工作?,c++,C++,因此,我的一个朋友正在学习他的第一个CS类,并提到他在他的第一个程序中使用递归。他把下面的代码发给我。一开始我就注意到他没有捕捉到递归调用的返回值,我认为这不会起作用。但他坚持认为它确实有效,所以我尝试了他的程序,令我惊讶的是,它的功能完全符合预期。忽略这是一种从a点到B点的愚蠢方式这一事实,为什么这会起作用 我在玩弄他寄给我的东西,并在if语句后添加了一个cout。除此之外,第一个代码块和第二个代码块是相同的 如果我为第一个程序输入以下内容,以下是我得到的 输入一个数字:10 您输入了:10这

因此,我的一个朋友正在学习他的第一个CS类,并提到他在他的第一个程序中使用递归。他把下面的代码发给我。一开始我就注意到他没有捕捉到递归调用的返回值,我认为这不会起作用。但他坚持认为它确实有效,所以我尝试了他的程序,令我惊讶的是,它的功能完全符合预期。忽略这是一种从a点到B点的愚蠢方式这一事实,为什么这会起作用

我在玩弄他寄给我的东西,并在if语句后添加了一个
cout
。除此之外,第一个代码块和第二个代码块是相同的

如果我为第一个程序输入以下内容,以下是我得到的

输入一个数字:10

您输入了:10这是正确的吗?(是/否):否

输入一个数字:12

您输入了:12这是正确的吗?(是/否):是

main()=12

然后如果我对第二个程序做同样的事情,我得到的是

输入一个数字:10

您输入了:10这是正确的吗?(是/否):否

输入一个数字:12

您输入了:12这是正确的吗?(是/否):是

main()=63000096

发生什么事了

#include <iostream>
#include <cstring>
#include <cctype>

using namespace std;

int getNum() 
{
    cout << "Enter a Number: ";
    int x;
    cin >> x;
    cin.ignore(100, '\n');

    while(x < 0) {
        cout << "Please enter amount greater than 0: ";
        cin >> x;
        cin.ignore(100, '\n');
    }

    cout << "You entered: " << x << " Is this correct? (Y/N): ";
    char response;
    cin >> response;
    cin.ignore(100, '\n');

    if (response != 'Y') {
        getNum();
    } else {
        return x;
    }
}

int main() {

    cout << "\nmain() = " << getNum() << endl;

    return 0;
}

<>在C++中,编译器不彻底检查函数没有返回语句结束它的流,因为检查所有控制路径不是一件容易的任务。此代码的行为未定义,实际发生的情况取决于调用约定

我想他们只是忘记了
return
之前的
getNum()
。它将工作,不会污染堆栈,因为如果尾部递归优化


但对于第一个CS类来说,这段代码很奇怪 我想他们只是忘记了
return
之前的
getNum()
。它将工作,不会污染堆栈,因为如果尾部递归优化


但对于第一个CS类来说,这段代码很奇怪

在机器代码级别,通常在特定处理器寄存器中返回足够小的函数结果

在一些调用
getNum
时,代码没有执行
return
语句,因此在形式上代码具有未定义的行为,但发生的情况可能是:

  • 调用
    getNum()
    ,用户回答
    N

  • getNum()
    递归调用自身,用户回答
    Y

  • getNum()
    执行
    返回x。通过一个典型的C++实现,将返回值登记在寄存器中,我们称之为R.< /P> 
  • 执行返回的最大值为
    getNum()
    (原始调用),它现在通过执行通过函数末尾返回,不返回
    return

  • 调用代码按预期在寄存器R中查找值

  • 因此,它可以“工作”


    但是它是形式上未定义的行为,如果使用其他编译器和/或选项,它可能无法工作。

    在机器代码级别,通常在特定处理器寄存器中返回足够小的函数结果

    在一些调用
    getNum
    时,代码没有执行
    return
    语句,因此在形式上代码具有未定义的行为,但发生的情况可能是:

  • 调用
    getNum()
    ,用户回答
    N

  • getNum()
    递归调用自身,用户回答
    Y

  • getNum()
    执行
    返回x。通过一个典型的C++实现,将返回值登记在寄存器中,我们称之为R.< /P> 
  • 执行返回的最大值为
    getNum()
    (原始调用),它现在通过执行通过函数末尾返回,不返回
    return

  • 调用代码按预期在寄存器R中查找值

  • 因此,它可以“工作”


    但这是一种形式上未定义的行为,如果使用其他编译器和/或选项,它可能无法工作。

    if(response!=“Y”)
    中,是否应该
    返回getNum()?当你这样写的时候,如果
    response!='Y'
    ,您从未返回任何内容,因此您的第一个程序工作的事实主要是运气。是的,您是对的,但我问的是运气部分。我的错,不理解您的问题。我重新打开了问题以提供。我相信这(为什么它“起作用”)并没有包含在最初确定的可能的副本中。在
    if(response!=“Y”)
    中,您不应该
    返回getNum()?当你这样写的时候,如果
    response!='Y'
    ,您从未返回任何内容,因此您的第一个程序工作的事实主要是运气。是的,您是对的,但我问的是运气部分。我的错,不理解您的问题。我重新打开了问题以提供。我相信这(为什么它“起作用”)并没有包含在最初确定的可能的副本中。这也解释了为什么它不适用于
    cout@TonyD:Good point,谢谢。)这也解释了为什么它不适用于
    cout@TonyD:Good point,谢谢。:)
    
    #include <iostream>
    #include <cstring>
    #include <cctype>
    
    using namespace std;
    
    int getNum() 
    {
        cout << "Enter a Number: ";
        int x;
        cin >> x;
        cin.ignore(100, '\n');
    
        while(x < 0) {
            cout << "Please enter amount greater than 0: ";
            cin >> x;
            cin.ignore(100, '\n');
        }
    
        cout << "You entered: " << x << " Is this correct? (Y/N): ";
        char response;
        cin >> response;
        cin.ignore(100, '\n');
    
        if (response != 'Y') {
            getNum();
        } else {
            return x;
        }
        cout << "returning... " << x;
    }
    
    int main() {
    
        cout << "\nmain() = " << getNum() << endl;
    
        return 0;
    }