Переменная сохраняет свое состояние, даже если не объявлена как статическая

#c

#c

Вопрос:

Я играю со статическим ключевым словом. В приведенном ниже коде я не могу понять, почему x сохраняет его перед состоянием и увеличивает. Я ожидал напечатать 1 дерево раз. Насколько я знаю, такое поведение должно произойти, если я объявлю x как статический.

 void print_it(void);

    int main (int argc,  const char * argv[])
    {
        print_it();
        print_it();
        print_it();
        exit(EXIT_SUCCESS);
    }

    void print_it(void)
    {
        int x;
        printf("%dn", x  );
    }
  

Ответ №1:

Вы не инициализировали x каким-либо значением. Следовательно, начальное значение в x будет мусором, и, как это бывает, этот мусор увеличивается каждый раз, потому что он, вероятно, использует одну и ту же ячейку памяти каждый раз.

Попробуйте изменить свой код на это:

 void print_it(void);
int main (int argc,  const char * argv[])
{
    print_it();
    print_it();
    print_it();
    exit(EXIT_SUCCESS);
}

void print_it(void)
{
    int x = 0;
    printf("%dn", x  );
}
  

Комментарии:

1. Я думаю, что он пропустил статическое объявление и инициализацию x, и он хочет ссылаться на этот x в своей print_it функции, поэтому строка int x = 0; должна быть полностью удалена, а x должна быть глобальной.

2. «потому что она, вероятно, использует одну и ту же ячейку памяти каждый раз». Совершенно верно, переменная находится в стеке, и поскольку нет промежуточного кода для ее удаления, она остается неизменной.

3. иногда автоматическая переменная инициализации всегда имеет значение 0. это не для той же ячейки памяти.

Ответ №2:

Это потому, что все 3 стека функций print_it занимают одно и то же адресное пространство.

 //    before print_it()                   1st print_it();             back to main()                 2nd print_it();            and so on...
//
//    ..................                ..................          ..................               .................. 
//    ... Stack data ...                ... Stack data ...          ... Stack data ...               ... Stack data ... 
//    ..................                ..................          ..................               ..................
//                       <- stack_P     |call  print_it()|                            <- stack_P     |call  print_it()| 
//                                              ||                                                           ||               
//                                              /                                                           /
//                                      ... some  data ...          ... some  data ...               ... some  data ...
//                                      | 4 bytes  of x  |          | X still  here  |               | Old  X  Bytes  |
//                                      ... some  data ...          ... some  data ...               ... some  data ...
//                                                        <- stack_P                                                   <- stack_P
//  
//                                       x got incremented                                         x got incremented again
  

Попробуйте этот основной:

 int main (int argc,  const char * argv[])
{
    print_it();
    int a;
    a  = 1; 
    print_it();
    int b;
    b  = 2
    print_it();
    exit(EXIT_SUCCESS);
}
  

Ответ №3:

Начальное значение неинициализированных локальных переменных не определено. В этом случае значение просто находится в стеке и используется повторно, потому что вы вызываете одну и ту же функцию три раза подряд. Если вы вызываете другие функции, у которых есть локальные переменные, значение изменится, потому что другие функции будут использовать ту же память стека.

Ответ №4:

Нет, чувак, ты не прав. Переменная не сохраняет свое значение. вы не инициализируете int x, поэтому каждый раз, когда у него есть значение garbase, вы увеличиваете его и печатаете это увеличенное значение garbase.

Вы получаете то же самое, но стандарт говорит, что это может быть не так.

в миллион раз вы получаете то же значение, что и раньше, и не может быть принято, что локальная переменная сохраняет свое значение.

в разных системах с другой средой ваша программа может иметь разное значение ..!

Редактировать: в большинстве случаев локальная переменная имеет значение 0. таким образом, она не сохраняет свое предыдущее значение.

 void print_it(void);

int main (int argc,  const char * argv[])
{
    print_it();
    print_it();
    print_it();
    return 1;
}

void print_it(void)
{
    int x;
    printf("starting %dn", x);
    x  ;
    printf("after increment %dn", x);
}
  

если переменная сохраняет свое состояние, то ее вывод должен быть

 starting 0
after increment 1
starting 1
after increment 2
starting 2
after increment 3
  

но ее реальный вывод

 starting 0
after increment 1
starting 0
after increment 1
starting 0
after increment 1
  

итак, теперь получаем точку ..??

локальная переменная не сохраняет свое состояние, но при инициализации локальная переменная всегда имеет значение 0.