Может ли цикл 'for' внутри цикла 'for' использовать одно и то же имя переменной счетчика?

Могу ли я использовать одну и ту же переменную счетчика для цикла for внутри цикла for?

Или переменные влияют друг на друга? Должен ли следующий код использовать другую переменную для второго цикла, например j, или i порядке?

for(int i = 0; i < 10; i++)
{
  for(int i = 0; i < 10; i++)
  {
  }
}

Ответ 1

Вы можете использовать одно и то же имя (идентификатор). Это будет другой объект. Они не будут влиять друг на друга. Внутри внутреннего цикла нет способа ссылаться на объект, используемый во внешнем цикле (если только вы не делаете для этого специальных положений, например, указав на него указатель).

Это, как правило, плохой стиль, склонный к путанице, и его следует избегать.

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

Ответ 2

Во-первых, это абсолютно легально: код будет компилироваться и выполняться, повторяя тело вложенного цикла 10 × 10 = 100 раз. Счетчик цикла i внутри вложенного цикла будет скрывать счетчик внешнего цикла, поэтому два счетчика будут увеличиваться независимо друг от друга.

Так как наружная i скрыта, код внутри тела вложенного цикла будет иметь доступ только к значению i из вложенного цикла, а не i от внешнего контура. В ситуациях, когда вложенный цикл не требует доступа к внешнему i такому коду может быть вполне оправданными. Однако это, скорее всего, создаст больше путаницы в своих читателях, поэтому рекомендуется избегать написания такого кода, чтобы избежать "обязательств по обслуживанию".

Примечание. Несмотря на то, что переменные счетчика обеих циклов имеют одинаковый идентификатор i, они остаются двумя независимыми переменными, то есть вы не используете одну и ту же переменную в обеих циклах. Использование одной и той же переменной в обоих циклах также возможно, но код будет трудно читать. Вот пример:

for (int i = 1 ; i < 100 ; i++) {
    for ( ; i % 10 != 0 ; i++) {
        printf("%02d ", i);
    }
    printf("%d\n", i);
}

Теперь обе циклы используют одну и ту же переменную. Однако для выяснения того, что делает этот код без компиляции (demo), требуется некоторое время;

Ответ 3

Вы можете. Но вы должны знать о масштабах i. если мы будем называть внешний i с i_1 и внутренним i с i_2, область действия i такова:

for(int i = 0; i < 10; i++)
{
     // i means i_1
     for(int i = 0; i < 10; i++)
     {
        // i means i_2
     }
     // i means i_1
}

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

Ответ 4

Это вполне возможно, но имейте в виду, вы не сможете адресовать первый объявленный i

for(int i = 0; i < 10; i++)//I MEAN THE ONE HERE
{

  for(int i = 0; i < 10; i++)
    {

    }
}

во втором цикле во втором дочернем цикле

for(int i = 0; i < 10; i++)
{

  for(int i = 0; i < 10; i++)//the new i
    {
        // i cant see the i thats before this new i here
    }
}

если вам нужно настроить или получить значение первого i, используйте j во втором цикле

for(int i = 0; i < 10; i++)
{

  for(int j = 0; j < 10; j++)
    {

    }
}

и если ваше творчество достаточно, вы можете сделать оба из них в одном цикле

for(int i ,j= 0; i < 10; (j>9) ? (i++,j=0) : 0 ,j++)
{
    printf("%d %d\n",i,j);
}

Ответ 5

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

Из цикла for:

for ( init_clause; cond_expression; iteration_expression ) loop_statement
Оператор выражения, используемый как loop_statement, устанавливает свою собственную область блока, отличную от области init_clause.

for (int i = 0; ; ) {
    long i = 1;   // valid C, invalid C++
    // ...
}  

Область loop_statement вложена в область init_clause.

Из стандартов С# 6.8.5p5 Итерационные утверждения [акцент мой]

Оператор итерации представляет собой блок, область видимости которого является строгим подмножеством области его охватывающего блока. Тело цикла также является блоком, область видимости которого является строгим подмножеством области действия итерации.

Из стандартов С# 6.2.1p4 Области идентификаторов [акцент мой]

.... В пределах внутренней области идентификатор обозначает объект, объявленный во внутренней области; объект, объявленный во внешней области, скрыт (и не отображается) во внутренней области.

Ответ 6

С точки зрения кода/компилятора это было бы совершенно правильной и законной задачей. int i объявленный во внутреннем for(int я = 0; я < 10; i++) цикл находится в новой и меньшей области, так что объявление затеняет объявление int i во внешнем цикле (или, другими словами: Во внутренней области все обращения к переменной i идут в int i объявленные во внутренней области, оставляя int i во внешней области нетронутой).

Тем не менее, с точки зрения качества кода это совершенно ужасно. Трудно читать, трудно понять и легко понять. Не делай этого.

Ответ 7

Да, определенно вы можете использовать одну и ту же переменную имени.

Переменные программирования C могут быть объявлены в трех местах:
локальные переменные: -Inside функция или блок.
Глобальные переменные: -Out всех функций.
Формальные параметры: -In параметры функции.

Но в вашем случае i scope буду иметь в виду ниже вещей

for(int i = 0; i < 10; i++)
{
     // i means 1st for loop variable
     for(int i = 0; i < 10; i++)
     {
        // but here i means 2nd for loop  variable
     }
     //interesting thing here i means 1st for loop variable
}

Примечание. Лучше всего использовать разные переменные для внутренних и внешних циклов

Ответ 8

Да, вы можете использовать его, но это довольно запутанно. Самое важное - это область локальной переменной внутри цикла. Если переменная объявлена внутри функции, область действия этой переменной является этой функцией.

int a = 5;
// scope of a that has value 5
int func(){
    int a = 10;
   // scope of a that has value 10
}
// scope of a that has value 5

Аналогично, случай с циклами, переменная, объявленная внутри внутреннего цикла, имеет разную область действия, а переменная, объявленная внешним контуром, имеет разную область.

for(int i = 0; i < 10; i++){
    // In first iteration, value of i is 0

    for(int i = 1; i < 10; i++){
        // In first iteration, value of i is 1
    }
    // In first iteration, value of i is 0
}

Лучший подход - использовать разные переменные для внутренних и внешних циклов.

for(int i = 0; i < 10; i++){

    for(int j = 1; j < 10; j++){

    }

}

Ответ 9

Да - и даже более интересно, вы можете повторно использовать имя переменной каждый раз, когда вы открываете набор фигурных скобок. Это очень удобно при вставке диагностического кода. Введите открытую скобку '{', за которой следует объявление и использование переменных, затем закройте скобку и переменные уйдут. Это гарантирует, что вы не будете вмешиваться в что-либо в основном теле, сохраняя при этом все преимущества переменных, классов и методов, объявленных вне фигур.

Ответ 10

Правило области действия: переменная, объявленная в операторе for, может использоваться только в этом выражении и в теле цикла.

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

int main(void) {

    int i = 2; //defined with file global scope outside of a function and will remain 2
    if(1)
    {       //new scope, variables created here with same name are different
        int i = 5;//will remain == 5
        for(int i = 0; i < 10; i++)
        {   //new scope for "i"

            printf("i value in first loop: %d \n", i); // Will print 0 in first iteration
            for(int i = 8; i < 15; i++) 
            {   //new scope again for "i", variable with same name is not the same
                printf("i value in nested loop: %d \n", i); // Will print 8 in first iteration
            }
        }

    }

    return 0;
}

Но не рекомендуется использовать одно и то же имя переменной, так как это трудно понять, и позже он будет не поддерживаемым кодом.

Ответ 11

Важная часть состоит в том, что внутренний параметр цикла содержит int i. Поскольку i переопределяется таким образом, эти две переменные не влияют друг на друга; их области различны. Вот два примера, чтобы показать это:

for(int i = 0; i < 10; i++) // This code will print "Test" 100 times
{
 for(int i = 0; i < 10; i++)
 {
  puts("Test");
 }
}

Обратите внимание, что приведенный выше код включает int i во внутренний параметр цикла, а приведенный ниже код включает только i.

for(int i = 0; i < 10; i++) // This code will print "Test" 10 times
{
 for(i = 0; i < 10; i++)
 {
  puts("Test");
 }
}

Ответ 12

Ну, вы можете сделать это без проблем с вашими скриптами, но вы должны избегать этой структуры. Это обычно приводит к путанице