为什么这个递归函数有效?

DPM*_*itu 1 c++

所以我的一个朋友正在参加他的第一个CS课程,并提到他在他的第一个课程中使用递归.他发给我下面的代码.马上,我注意到他没有抓住他的递归调用的返回值,我认为它不起作用.但是他坚持认为它确实有效,所以我尝试了他的程序,令我惊讶的是它的功能完全符合预期.忽略这一事实,这是从A点到B点的愚蠢方式,为什么这甚至有效?

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

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

输入一个数字:10

你输了:10这是对的吗?(是/否):N

输入一个数字:12

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

main()= 12

如果我对第二个程序做同样的事情,这就是我得到的......

输入一个数字:10

你输了:10这是对的吗?(是/否):N

输入一个数字:12

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

main()= 6300096

这是怎么回事!?

#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;
}
Run Code Online (Sandbox Code Playgroud)

顶部和底部之间的唯一区别是coutif语句之后的语句.

#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;
}
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 6

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

正式地,代码具有未定义的行为,因为return在某些调用中没有执行语句getNum,但可能会发生以下情况:

  1. getNum()被叫,用户回答N.

  2. getNum()用户回答,递归调用自己Y.

  3. getNum()执行return x;.使用典型的C++实现,将返回值放在寄存器中,我们称之为R.

  4. 执行返回getNum()(原始调用),现在通过执行函数结束返回,否return.

  5. 调用代码按预期查找寄存器R中的值.

所以,它可以"工作".

但它是正式的未定义行为,并且对于其他一些编译器和/或选项,它可能不起作用.