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


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

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

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

11 ответов:

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

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

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

во-первых, это абсолютно законно: код будет компилироваться и выполняться, повторяя тело вложенного цикла 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);
}

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

вы можете. Но вы должны знать о масштабах is. Если мы называем внешний i С i_1 и внутри i С i_2, объем i s выглядит следующим образом:

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
}

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

это вполне возможно, но имейте в виду, что вы не сможете решить первым заявил Я

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);
}

Да, вы можете использовать то же имя переменной счетчика для внутреннего 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 is вложенные в рамках init_clause.

из стандартов C#6.8. 5p5 итерационные операторы [выделено мной]

оператор итерации-это блок, область действия которого является строгим подмножеством области действия его заключающего блока. тело цикла также является блоком, область действия которого является строгим подмножеством области действия оператора итерации.

из стандартов C#6.2. 1p4 области идентификаторов [выделено мной]

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

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

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

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

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++){

    }

}

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

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

но в вашем случае 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
}

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

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

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

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

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;
}

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

важной частью является то, что параметр внутреннего цикла содержит 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");
 }
}