объявление переменной в цикле while C / C

#c #while-loop #variable-declaration

#c #цикл while #объявление переменной

Вопрос:

по моему мнению, следующий цикл while должен быть бесконечным, но он выполняется только трижды

    main()
   {
   int i=3;       
   while(i--)
    {
      int i=100;
      i--;
      printf("%d..",i);
    }
   }
  

выводит 99..99..99

но, по моему мнению, оно должно выполняться бесконечно, поскольку каждый раз, когда элемент управления входит в цикл while, он получает значение 100.so она никогда не достигнет нуля. просто для эксперимента я заменил int i=100; на i=100; в стороне цикл while, и теперь он выполняется бесконечно .. ПОЧЕМУ???

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

1. Спасибо за общие ответы. я думал, что все переменные, имеющие одинаковое имя, хранят в себе только одно значение и являются локальными для функции и объявлений

2. Технический термин для этого — «тень»: вы затеняете i определенную перед while циклом. gcc может предупредить об этом с помощью -Wshadow .

Ответ №1:

Переменная, i которая проверяет условие, является той, которую вы объявили в main() , а не той, которая находится внутри цикла.

Это разные переменные, вы путаете их как одну, компилятор не запутывается так легко, как вы.

Внутри цикла i ссылается на ту, которую вы объявили внутри { } , а за пределами { } i — на ту, которая была объявлена в main()

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

1. означает ли это, что это две разные переменные?

2. @Yadnesh: Да, это так. Проверьте мой ответ.

Ответ №2:

Переменная i в while(i--) отличается от переменной, i определенной внутри цикла.

По сути, int i = 100 затемняет предыдущую int i = 3 и внутри блока, на while который вы ссылаетесь, новую переменную.

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

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

1. означает ли это, что это две разные переменные?

2. @Yadnesh Совершенно другое.

3. Переменные обычно не затеняются намеренно. Более удобно предотвращать загрязнение локального пространства имен глобальным пространством имен.

Ответ №3:

 while(i--)
    {
      int i=100; // gets created every time the loop is entered
      i--;
      printf("%d..",i);
    } // the i in the loop keeps getting destroyed here
  

Почему бы вам также не попробовать:

 while(i--)
{

              {
                  int i=100; //Visible only in this scope
                  i--;
                  printf("inner i=%d..",i);
              } //gets destroyed here
        printf("nouter i=%d..n",i);
}
  

Ответ №4:

Каждая переменная ссылается на свое самое последнее объявление (которое, конечно, допустимо в этой области):

 main()
{
   int i=3;       
   while(i--)             // this i is the one defined in the line above
   {
       int i=100;
       i--;               // this i is the one defined in the line above
       printf("%d..",i);  // this i is the one defined two lines above
   }
}
  

Итак, ваш цикл while повторяется 3 раза, потому что это зависит от того, i что объявлено int i = 3; Внутри цикла, который он печатает, 99 потому что там i ссылается на i то, что объявлено int i = 100; , которое -- редактируется.

Если вы измените int i = 100; на i = 100 , то вы изменяете первую i и не вводите другую переменную. Отсюда и бесконечный цикл.

Редактировать Некоторые люди говорили, что вместо «самого последнего» я должен сказать «самое внутреннее объявление, доступное в текущей области», приводя этот пример:

 int a=4;
{
    int a=10;
}
printf("%d", a);
  

Поскольку вторая a не видна с помощью printf , очевидно printf("%d", a); , что на нее нельзя ссылаться. Я предположил, что читатель знает достаточно, чтобы знать, что переменная доступна только внутри области, в которой она определена. В остальном, да, фразы в первых двух комментариях более точны.

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

1. Если быть точным, не «самой последней», а «в самой локальной области».

2. Я бы не сказал «самое последнее» (как это происходит в некоторых языках сценариев), но самое внутреннее объявление, доступное в текущей области видимости (пример: int a=4; { int a=10;} printf("%d", a); выводит 4, а не 10).

3. «Самая последняя» — это точно технически правильно, но для этого требуется, чтобы вы понимали, когда были созданы все различные переменные. Скорее всего, если бы вы это понимали, вам бы это правило все равно не понадобилось.

4. Поскольку это начинает сбивать людей с толку, я собираюсь немного отредактировать это

Ответ №5:

Каждая область в C (грубо говоря, каждая пара фигурных скобок, которая не используется для специальной цели, такой как инициализация массива) может содержать свои собственные объявления локальных переменных. Запись int i = 100; в цикле указывает другую переменную с именем, i отличным от имени вне цикла, и вызывает код в области видимости, который по умолчанию использует для ссылки на внутреннюю i вместо внешней. i Тем не менее, i-- в условии цикла все еще используется внешняя i .

При замене int i = 100 на i = 100 теперь остается только одна переменная, которой присваивается значение 100, дважды уменьшается (один раз внутри цикла и один раз самим циклом) и повторно присваивается значение 100, неоднократно.

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

1. Нет, i- в теле цикла уменьшает внутреннее значение i, а printf выводит внутреннее значение i. Внешний i не виден в пределах тела цикла.

2. Извините, не тело цикла, а условие цикла. Я это исправлю.