Как ключевое слово "static" влияет на расчеты? - PullRequest
0 голосов
/ 11 октября 2019

У меня есть проблема в этом коде с использованием ключевого слова 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 во всех случаях. Пожалуйста, может кто-нибудь помочь мне в этом.

1 Ответ

2 голосов
/ 11 октября 2019

Если у вас есть оператор static int r = 5;, это сигнализирует компилятору, что переменная r будет инициализирована значением 5 во время компиляции . Это означает, что не будет сбрасываться на 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;

Когда компилятор встречает этот оператор, он«выделяет» часть памяти для программы, достаточно большую, чтобы вместить int, и дает этому фрагменту памяти значение, представляющее 42. Компилятор не генерирует какие-либо инструкции машинного кода для перемещения значения, заданного в эту память;на самом деле, он не может сгенерировать такой код - поскольку нет «контекста» для запуска этого кода.

Однако, если вы позже (где-то вфункция, или в main) имеет такой оператор:

StatInt1 = 9;

, тогда компилятор сгенерирует код, который перемещает представление значения 9 в память ранее«выделено» для переменной. То, каким именно будет этот код, зависит от компилятора и целевой машины, но, скажем, это инструкция MOVE 9 TO @StatInt1 (где @ StatInt1 - адрес выделенного блока памяти).

Теперь, если выесли переместить оператор static int StatInt1 = 42; в тело функции (как и у вас), это (по определению) не изменит способа, которым компилятор интерпретирует оператор! Все, что он делает - это делает доступ к переменной 'local' для этой функции. До сих пор не создан код для перемещения значения в переменную!

Но переменная внутри функции, которая не , объявлена ​​статическойтрактуется по-разному - мы иногда называем такие переменные как «автоматические»! Блок памяти для такой переменной «выделяется» только тогда, когда функция фактически вызывается, и тогда ему будет присвоено значение, данное в инициализаторе каждый раз, когда вызывается функция. (Как правило, большинство компиляторов создают память в стеке: кратковременную память, которая «стирается» после завершения функции.)

В вашем коде static int r = 5; не генерирует никакого кода, поэтому«автоматического» переназначения значения 5 при вызове функции не происходит. Таким образом, как только функция была вызвана таким образом, чтобы присвоить значение 50 значению r, она будет сохранять это значение до тех пор, пока вы явно не передадите ей другое значение.

Я прошу прощения, если это бессвязно, но я надеюсь, что это прояснит (э), что происходит!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...