静态函数中可以递归吗?

发布于 2024-09-02 17:11:20 字数 26 浏览 2 评论 0原文

是否可以用 C 语言编写递归静态函数?

Is it possible to write a recursive static function in C?

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

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

发布评论

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

评论(2

就是爱搞怪 2024-09-09 17:11:21

是的,确实如此。当您将static应用于函数时,它与递归函数中的静态变量不同(如果在计算中使用它就会出现问题)。

当应用于函数(或函数外部的对象)时,static 只是控制该事物在编译单元外部是否可见(例如,对于链接器)。

当应用于函数内的对象时,静态意味着该变量在函数持续时间之外存在。在递归函数的上下文中,这还意味着所有递归级别只有一个变量副本,而不是每个递归级别一个, em> 这通常是所需要的。

所以这(你的问题似乎在问什么)是完全可以的:

static unsigned int fact (unsigned int n) {
    if (n == 1U) return 1;
    return n * fact (n-1);
}

另一方面,这不行可以,因为静态变量的单个副本将可能会被较低的递归层破坏。

static unsigned int fact (unsigned int n) {
    static unsigned int local_n;
    local_n = n;
    if (local_n == 1U) return 1;
    return fact (local_n - 1) * local_n;
}

更详细地说,考虑对 fact(3) 的调用:

  • 在第一个递归层中,local_n 设置为 3,然后调用是根据fact(2)进行。
  • 在第二层中,local_n 设置为 2,并调用 fact(1)
  • 在第三层,local_n 设置为 1,我们只返回 1,因为这是递归的基本情况。

这时事情似乎开始出错(尽管从技术上来说,一旦我们为 local_n 声明符输入 static 关键字,它们就开始出错)

  • :第二层,我们接收 1 并将其乘以 local_n。现在,如果该变量不是是静态的,它将具有(本地)值2。不幸的是,它是静态的,因此在上一步中设置为1。因此,我们返回 1 * 1 或者,...等等,让我在计算器上检查一下...,1 :-)
  • 同上回到第一个层,我们收到 1 并将其乘以 local_n,当然,它仍然具有值 1。因此,我们再次乘以 1 * 1 并返回 1

如果您想尝试一下,这里有一个完整的程序:

#include <stdio.h>

static unsigned int fact (unsigned int n) {
    static unsigned int local_n; // bad idea!
    local_n = n;
    if (local_n == 1U) return 1;
    return fact (local_n - 1) * local_n;
}

int main() {
    printf("%d\n", fact(3));
    return 0;
}

它会输出错误的 1 但是,如果您去掉 local_nstatic 关键字code> 声明符,它将返回正确的 6

Yes, it most certainly is. When you apply static to a function, it's not the same as a static variable within a recursive function (which is a problem if it's used in the calculations).

When applied to a function (or an object outside of a function), static simply controls whether that thing is visible outside the compilation unit (for the linker, for example).

When applied to an object within a function, static means that the variable exists beyond the duration of the function. In the context of a recursive function, it also means that there is only one copy of the variable for all recursion levels rather than one per recursion level, which is usually what's needed.

So this (what your question appears to be asking about) is perfectly okay:

static unsigned int fact (unsigned int n) {
    if (n == 1U) return 1;
    return n * fact (n-1);
}

This, on the other foot, is not okay, since the single copy of the static variable will probably be corrupted by the lower recursive layers.

static unsigned int fact (unsigned int n) {
    static unsigned int local_n;
    local_n = n;
    if (local_n == 1U) return 1;
    return fact (local_n - 1) * local_n;
}

In more detail, consider a call to fact(3):

  • In the first recursive layer, local_n is set to 3, then a call is made to fact(2).
  • In the second layer, local_n is set to 2, and a call is made to fact(1).
  • In the third layer, local_n is set to 1, and we just return 1 because that's the base case of the recursion.

That's when things seem to start going wrong (although, technically, they started going wrong as soon as we typed in that static keyword for the local_n declarator):

  • Back up into the second layer, we receive the 1 and multiply it by local_n. Now, had that variable not been static, it would have the (local) value of 2. Unfortunately, it is static, so was set to 1 in the previous step. Hence we return 1 * 1 or, ... hang on, let me check this on the calculator ..., 1 :-)
  • Ditto coming back up to the first layer, we receive the 1 and multiply it by local_n which, of course, still has the value 1. So we again multiply 1 * 1 and return 1.

If you want to try it out, here's a complete program:

#include <stdio.h>

static unsigned int fact (unsigned int n) {
    static unsigned int local_n; // bad idea!
    local_n = n;
    if (local_n == 1U) return 1;
    return fact (local_n - 1) * local_n;
}

int main() {
    printf("%d\n", fact(3));
    return 0;
}

That outputs the erroneous 1 but, if you get rid of the static keyword in the local_n declarator, it will return the correct 6.

乖不如嘢 2024-09-09 17:11:21
#include <stdio.h>

static void count_to_five(void)
{
   static int i = 0;

   while (i < 5) {
     i++;
     printf("%d\n", i);
     count_to_five();
   }

  puts("You are seeing this because I counted to five! (did not enter loop)\n");    
  return;
}

int main(void)
{
    count_to_five();
    return 0;
}

所以,是的。请注意,i 的静态存储意味着每次调用 count_to_ Five() 时它都会保留其值。但是,count_to_ Five() 不需要定义为static

很难说出你在问什么。

#include <stdio.h>

static void count_to_five(void)
{
   static int i = 0;

   while (i < 5) {
     i++;
     printf("%d\n", i);
     count_to_five();
   }

  puts("You are seeing this because I counted to five! (did not enter loop)\n");    
  return;
}

int main(void)
{
    count_to_five();
    return 0;
}

So, yes. Note, static storage for i means it retains its value with each call of count_to_five(). However, count_to_five() need not be defined as static.

Its very hard to tell what you're asking.

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