Автоматическая переменная в C не инициализирована, но имеет фиксированное значение в цикле

Я читал, что автоматические переменные в C, если они не инициализированы значениями, содержат значения мусора. Однако я нашел то, что не соответствовало моему пониманию. Рассмотрим следующий фрагмент кода.

#include <stdio.h>

main() 
{
    int i = 0;

    for (i = 0 ; i< 10; i++)
    {   
        int x;
        int a = 500;
        printf("%d\t%d\n", a, x);

    }
}

Выход:

500     2
500     2
500     2
500     2
500     2
500     2
500     2
500     2
500     2
500     2

У меня вопрос - разве я не должен ожидать значения мусора вместо 2s? Я запустил программу на Dev-C++ на компьютере с Windows.

6 ответов

Uninitialized означает объявленное, но не установленное известное значение, прежде чем оно будет использовано.

Это будет иметь НЕКОТОРОЕ значение, но не предсказуемое. В вашем случае это 2, В другой системе это может быть что-то еще.

Причина состоит в том, что каждый цикл итерации равен 2, потому что вы каждый раз используете одно и то же расположение стека. Для каждой итерации:

  1. Int создается на вершине стека - его значение неинициализировано - 2 в вашем случае
  2. Другой int создается и инициализируется до 500.
  3. printf () вызывается
  4. 2 созданных целых удаляются из стека
  5. Повторите вышеуказанные шаги, пока я == 10

После прочтения вашего комментария, я думаю, что вы имеете в виду, что код такой:

   #include <stdio.h>

   main()
   {
       int i = 0;
       int x = 1;
       printf("%d\n", x);
      for (i = 0 ; i< 10; i++)
       {
          int x;
          int a = 500;
          printf("%d\t%d\n", a, x);

      }
  }

Снимок экрана:

1
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736
500     -1216424736

В то время как значимый код:

   #include <stdio.h>

   main()
   {
       int i = 0;
       int x = 1;
       printf("%d\n", x);
       for (i = 0 ; i< 10; i++)
       {
          //int x;
          int a = 500;
          printf("%d\t%d\n", a, x);

      }
  }

Скриншот экрана:

1
500     1
500     1
500     1
500     1
500     1
500     1
500     1
500     1
500     1
500     1

В первом коде я создаю новый x в цикле, диапазон выживания нового x - это только цикл, так как я не инициализировал его, его значение неизвестно. (один раз это 0, другой раз -121642736 и ваш 2).

Второй код, х в цикле - это в точности тот, который в цикле, это 1.

Вы забыли инициализировать переменную x:

#include <stdio.h>

main() 
{
    int i = 0;

    for (i = 0 ; i< 10; i++)
    {   
        int x = 0;//change this to whatever you want. The most common initial value is 0
        int a = 500;
        printf("%d\t%d\n", a, x);//this should print: "500    0" correctly, now
    }
}

То, что вы видите, это информация из предыдущих программ - то есть мусорные данные.

Уход x неинициализированный даст ему некоторое значение из предыдущей программы или стека кадра. В C блоки памяти внутри стекового фрейма не обязательно заполнены нулями, как это делают некоторые языки, они остаются в своем предыдущем (или старом) состоянии. Это более широко известно как значение мусора.

Это просто совпадение, что это 2, это может быть легко 1000 или 1293. Вероятный капот - вам очень повезло и ваша переменная x был назначен на тот же блок памяти для каждого выполнения вашей программы.

int x определяет хранилище (в MS Windows ints 4 байта). Это хранилище, как и любое другое хранилище, содержит данные, в вашем случае это просто 2.

Другие вопросы по тегам