首页 > 解决方案 > “静态”关键字如何影响计算?

问题描述

我在这段代码中有一个问题,使用static关键字。这里,在n = 3之后,我以为r是5,结果发现r是50!我不知道static这里是如何工作的:

int magic(int n)
{
    static int r = 5;
    if (n <= 0) return 10;

    if (n > 3)
    {
        r = 50;
        return(r + magic(n-1));
    }
    return(r - magic(n-1));
}

int main()
{
    int x;
    x = magic(8);
    printf("%d",x);
}

这里的输出是 290,因为r在所有情况下的值都是 50。请有人可以帮助我。

标签: crecursionstatic

解决方案


当您有语句时static int r = 5;,这会向编译器发出信号,表明该变量r5 在编译时初始化为该值。这意味着,它不会5在每次调用该函数时重置!

此外,该行if (r > 3)无法按照您的建议工作(请参阅我在您的问题中的评论)!改成按if (n > 3)你说的做。

无论如何,下面的代码做了一些不同的事情(输出 245),但我不确定你期望输出是什么:

#include <stdio.h>

int magic(int n)
{
    int r = 5; // NOT STATIC - so this is reset to 5 at the start of each call!
    if (n <= 0) return 10;
    else if (n > 3) { // Your "if (r > 3)" means the block will ALWAYS execute!
        r = 50;
        return(r + magic(n - 1));
    }
    return(r - magic(n - 1));
}

编辑:我将尝试添加一些说明!考虑一个声明和初始化“全局”范围内的静态变量的语句(即不在任何函数内,甚至不在main):

static int StatInt1 = 42;

当编译器遇到此语句时,它会为程序“分配”一部分内存,大到足以容纳 a int,并为那块内存赋予表示 的值42。编译器不会生成任何机器代码指令来将给定的值移动到该内存中;事实上,它不可能生成这样的代码——因为没有运行该代码的“上下文”。

但是,如果您稍后(在某个函数中或在 中main)有这样的语句:

StatInt1 = 9;

然后编译器生成代码,将值的表示移动9到先前为变量“分配”的内存中。这段代码的确切内容取决于编译器和目标机器,但假设它是一条指令MOVE 9 TO @StatInt1(其中@StatInt1 是“已分配”内存块的地址)。

现在,如果您要将static int StatInt1 = 42;语句移动到函数体中(就像您所做的那样),这(根据定义)不会改变编译器解释语句的方式!它所做的只是访问该函数的变量“本地”。仍然没有生成代码来将值移动到变量中!

但是函数中声明为静态的变量的处理方式非常不同 - 我们有时将此类变量称为“自动”!此类变量的内存块仅在实际调用函数时才“分配”,然后每次调用函数时都会为其分配初始化程序中给出的值。(通常,大多数编译器会在堆栈上创建内存:函数结束时“清除”的短期内存。)

在您的代码中,static int r = 5;不会生成任何代码,因此在5调用函数时不会“自动”重新分配值。50因此,一旦以将值分配给的方式调用该函数r,它将保留该值,直到您显式地给它另一个值。

如果这是漫无边际的,我深表歉意 - 但我希望它能让你清楚(呃)发生了什么!


推荐阅读