如何检测根递归调用?

发布于 2024-08-30 02:09:06 字数 546 浏览 2 评论 0原文

假设我们正在编写一个简单的递归函数 fib(n) 来计算第 n 个斐波那契数。现在,我们希望函数打印第 n 个数字。由于重复调用同一函数,因此必须存在一个条件,仅允许根调用进行打印。问题是:如何在不传递任何附加参数或使用全局/静态变量的情况下编写此条件。

所以,我们正在处理这样的事情:

int fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    if(???) cout << fn << endl;
    return fn;
}

int main() {
    fib(5);
    return 0;
}

我认为根调用与所有子调用不同,它返回到不同的调用者,即本例中的 main 方法。我想知道是否可以使用这个属性来编写条件以及如何使用。

更新:请注意,这是一个人为的示例,仅用于展示想法。从标签中应该可以清楚地看出这一点。我不是在寻找标准解决方案。谢谢。

Say we're writing a simple recursive function fib(n) that calculates the nth Fibonacci number. Now, we want the function to print that nth number. As the same function is being called repeatedly, there has to be a condition that allows only the root call to print. The question is: how to write this condition without passing any additional arguments, or using global/static variables.

So, we're dealing with something like this:

int fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    if(???) cout << fn << endl;
    return fn;
}

int main() {
    fib(5);
    return 0;
}

I thought that the root call differs from all children by returning to a different caller, namely the main method in this example. I wanted to know whether it is possible to use this property to write the condition and how.

Update: please note that this is a contrived example that only serves to present the idea. This should be clear from the tags. I'm not looking for standard solutions. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

美胚控场 2024-09-06 02:09:06

我执行此操作的方法是使用辅助函数:

int _fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = _fib(n-2) + _fib(n-1);
    return fn;
}

int fib(int n) {
    int fn=_fib(n);
    cout << fn << endl;
    return fn;
}

或者,您可以这样编写(c++):

int fib(int n, bool f=true) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2, false) + fib(n-1, false);
    if(f) cout << fn << endl;
    return fn;
}

The way I would do this is with a helper function:

int _fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = _fib(n-2) + _fib(n-1);
    return fn;
}

int fib(int n) {
    int fn=_fib(n);
    cout << fn << endl;
    return fn;
}

Alternatively, you could write it like this (c++):

int fib(int n, bool f=true) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2, false) + fib(n-1, false);
    if(f) cout << fn << endl;
    return fn;
}
偷得浮生 2024-09-06 02:09:06

根递归调用是调用递归的点,即main中的调用。鉴于此,您可以稍微重写您的代码(如下所示):

int fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    return fn;
}

int main() {
    cout << fib(5) << endl;
    return 0;
}

The root recursive call is the point the recursion is invoked, namely the invocation in main. Given that, you could rewrite your code slightly (something like this):

int fib(int n) {
    if(n <= 0) return 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    return fn;
}

int main() {
    cout << fib(5) << endl;
    return 0;
}
一绘本一梦想 2024-09-06 02:09:06

如果您确实想问 C 是否可以访问某种 API,允许函数体中的代码找出调用执行函数的位置,那么答案是

If you really mean to ask whether C has access to some sort of API that allows code in a function body to find out from where the executing function was called, the answer is no.

这里有一个棘手的方法,尽管我不确定这是否值得:):

int fib(int n) {
//    if(n <= 0) return 0;
    int isRoot;
    if ( n <= 0 ){
        isRoot = 1;
        n = -n;
    }
    else isRoot = 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    if(isRoot) cout << fn << endl;
    return fn;
}

int main() {
    fib(-5);
    return 0;
}

但是,该函数要求您不要真正发送负值:)。

Here comes a tricky way, although i'm not sure that's worth it :):

int fib(int n) {
//    if(n <= 0) return 0;
    int isRoot;
    if ( n <= 0 ){
        isRoot = 1;
        n = -n;
    }
    else isRoot = 0;
    int fn = 1;
    if(n > 2) fn = fib(n-2) + fib(n-1);
    if(isRoot) cout << fn << endl;
    return fn;
}

int main() {
    fib(-5);
    return 0;
}

But, the function requires you not to really mean sending a negative value :).

初见你 2024-09-06 02:09:06

我认为您可以从堆栈中获取返回地址,并以某种方式将其与 fib 函数的地址进行比较。返回地址应该位于接近参数 n 的地方,除非 n 在某个寄存器中传递,但在标准 C 中不应该。您只需知道返回地址相对于参数的位置即可。

I think You could get the return address from the stack and compare it somehow with the address of the fib function. The return address should be somewhere close to the parameter n unless n is passed in some register, but in standard C it shouldn't. You just have to know where the return address is relative to the parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文