it-swarm.com.de

Kann eine 'for'-Schleife innerhalb einer' for'-Schleife denselben Namen für die Zählervariable verwenden?

Kann ich dieselbe Zählervariable für eine for -Schleife innerhalb einer for -Schleife verwenden?

Oder beeinflussen sich die Variablen gegenseitig? Sollte der folgende Code eine andere Variable für die zweite Schleife verwenden, z. B. j, oder ist i in Ordnung?

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

Sie können den gleichen Namen (Bezeichner) verwenden. Es wird ein anderes Objekt sein. Sie werden sich nicht gegenseitig beeinflussen. Innerhalb der inneren Schleife gibt es keine Möglichkeit, auf das in der äußeren Schleife verwendete Objekt zu verweisen (es sei denn, Sie treffen spezielle Vorkehrungen, indem Sie einen Zeiger darauf bereitstellen).

Dies ist im Allgemeinen ein schlechter Stil, neigt zu Verwirrung und sollte vermieden werden.

Die Objekte unterscheiden sich nur, wenn das innere separat definiert wird, wie bei der int i Sie haben gezeigt. Wenn derselbe Name verwendet wird, ohne ein neues Objekt zu definieren, verwenden die Schleifen dasselbe Objekt und interferieren miteinander.

136

Erstens ist dies absolut legal: Der Code wird kompiliert und ausgeführt, wobei der Hauptteil der verschachtelten Schleife 10 × 10 = 100 Mal wiederholt wird. Schleifenzähler i innerhalb der verschachtelten Schleife wird hide der Zähler der äußeren Schleife, so dass die beiden Zähler unabhängig voneinander inkrementiert werden.

Da das äußere i verborgen ist, hat der Code im Hauptteil der verschachtelten Schleife nur Zugriff auf den Wert von i der verschachtelten Schleife, nicht auf i in der äußeren Schleife. In Situationen, in denen die verschachtelte Schleife keinen Zugriff auf den äußeren i benötigt, kann ein solcher Code durchaus gerechtfertigt sein. Dies führt jedoch wahrscheinlich zu größerer Verwirrung bei den Lesern. Daher ist es eine gute Idee, das Schreiben eines solchen Codes zu vermeiden, um "Wartungspflichten" zu vermeiden.

Hinweis: Obwohl die Zählervariablen beider Schleifen den gleichen Bezeichner i haben, bleiben sie zwei unabhängige Variablen, dh Sie sind nicht Verwenden derselben Variablen in beiden Schleifen. Die Verwendung derselben Variablen in beiden Schleifen ist ebenfalls möglich, der Code ist jedoch schwer zu lesen. Hier ist ein Beispiel:

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

Jetzt verwenden beide Schleifen dieselbe Variable. Es dauert jedoch eine Weile, um herauszufinden, was dieser Code macht, ohne ihn zu kompilieren ( demo );

55
dasblinkenlight

Du kannst. Sie sollten sich jedoch des Umfangs der is bewusst sein. Wenn wir das äußere i mit i_1 und das innere i mit i_2 aufrufen, ist der Gültigkeitsbereich des is wie folgt:

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
}

Sie sollten beachten, dass sie sich nicht gegenseitig beeinflussen und nur der Definitionsbereich unterschiedlich ist.

25
OmG

Das ist durchaus möglich, aber denken Sie daran, Sie werden nicht in der Lage sein, das erste deklarierte i anzusprechen

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

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

    }
}

in der zweiten Schleife innerhalb der zweiten Kindschleife

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

wenn Sie den Wert des ersten i anpassen oder abrufen müssen, verwenden Sie j in der zweiten Schleife

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

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

    }
}

und wenn Sie kreativ genug sind, können Sie beide in einer Schleife ausführen

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

Ja, Sie können für eine innere for Schleife den gleichen Namen für die Zählervariable verwenden wie für die äußere for Schleife.

Von für Schleife :

for ( init_clause ; cond_expression ; iteration_expression ) loop_statement
Die Ausdrucksanweisung, die als loop_statement verwendet wird, erstellt einen eigenen Blockbereich, der sich vom Bereich von = unterscheidet init_clause.

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

Der Geltungsbereich von loop_statement ist verschachtelt im Geltungsbereich von init_clause.

Aus C-Standards # 6.8.5p5 Iterationsanweisungen [Hervorhebung von mir]

Eine Iterationsanweisung ist ein Block, dessen Gültigkeitsbereich eine strikte Teilmenge des Gültigkeitsbereichs seines einschließenden Blocks ist. Der Schleifenkörper ist ebenfalls ein Block, dessen Gültigkeitsbereich eine strikte Teilmenge des Gültigkeitsbereichs der Iterationsanweisung ist.

Aus C-Standards # 6.2.1p4 Bereiche von Bezeichnern [Hervorhebung von mir]

.... Im inneren Gültigkeitsbereich bezeichnet der Bezeichner die im inneren Gültigkeitsbereich deklarierte Entität. Die im äußeren Gültigkeitsbereich deklarierte Entität ist im inneren Gültigkeitsbereich verborgen (und nicht sichtbar).

12
H.S.

Aus Code-/Compiler-Sicht wäre dies eine absolut gültige und legale Angelegenheit. Die in der inneren for(int i = 0; i < 10; i++) -Schleife deklarierte int i Befindet sich in einem neuen und kleineren Bereich, sodass die Deklaration Schatten die Deklaration von int i In der äußeren loop (oder mit anderen Worten: Im inneren Gültigkeitsbereich gehen alle Zugriffe auf die Variable i zu dem im inneren Gültigkeitsbereich deklarierten int i, wobei das int i im äußeren Gültigkeitsbereich verbleibt unberührt).

Allerdings ist dies aus Sicht der Codequalität absolut schrecklich. Es ist schwer zu lesen, schwer zu verstehen und leicht zu missverstehen. Tu es nicht.

9
CharonX

Ja, Sie können es verwenden, aber es ist ziemlich verwirrend. Das Wichtigste ist der Gültigkeitsbereich der lokalen Variablen innerhalb der Schleife. Wenn eine Variable in einer Funktion deklariert ist, ist der Gültigkeitsbereich dieser Variablen diese Funktion.

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

Ähnlich wie bei Schleifen haben Variablen, die innerhalb der inneren Schleife deklariert wurden, einen unterschiedlichen Geltungsbereich und Variablen, die als äußere Schleife deklariert wurden, einen unterschiedlichen Geltungsbereich.

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
}

Der bessere Ansatz besteht darin, unterschiedliche Variablen für innere und äußere Schleifen zu verwenden.

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

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

    }

}
8
Safwan Shaikh

Ja, auf jeden Fall können Sie dieselbe Namensvariable verwenden.

C-Programmiervariablen können an drei Stellen deklariert werden:
lokale Variablen: -Innerhalb einer Funktion oder eines Blocks.
Globale Variablen: -Aus allen Funktionen.
Formale Parameter: -In den Funktionsparametern.

Aber in deinem Fall i scope wird unter Dinge zu beachten haben

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
}

Hinweis: Es wird empfohlen, für innere und äußere Schleifen unterschiedliche Variablen zu verwenden

8

Ja - und noch interessanter ist, dass Sie einen Variablennamen jedes Mal wiederverwenden können, wenn Sie einen Satz von Klammern öffnen. Dies ist häufig beim Einfügen von Diagnosecodes hilfreich. Geben Sie eine offene Klammer '{' gefolgt von der Deklaration und Verwendung von Variablen ein, schließen Sie die Klammer und die Variablen verschwinden. Dies garantiert, dass Sie nichts im Hauptteil stören, während Sie den Vorteil von Variablen, Klassen und Methoden beibehalten, die außerhalb der geschweiften Klammern deklariert sind.

6
SuwaneeCreek

Bereichsregel: Eine in einer for-Anweisung deklarierte Variable kann nur in dieser Anweisung und im Rumpf der Schleife verwendet werden.

Wenn Sie in Ihrem Code mehrere Instanzen von i in inneren Schleifen definiert haben, belegt jede Instanz ihren eigenen Speicherplatz. Es gibt also nichts, worüber man sich Sorgen machen müsste. Es wäre also dasselbe.

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

Es wird jedoch nicht empfohlen, denselben Variablennamen zu verwenden, da dies schwer zu verstehen ist und später nicht mehr wartbarer Code wird.

3
Subash J

Der wichtige Teil ist, dass der innere Schleifenparameter int i Enthält. Da i auf diese Weise neu definiert wird, beeinflussen sich die beiden Variablen nicht gegenseitig. Ihre Bereiche sind unterschiedlich. Hier sind zwei Beispiele, um dies zu zeigen:

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

Beachten Sie, dass der obige Code int i Im inneren Schleifenparameter enthält und der folgende Code nur i enthält.

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

Nun, Sie können dies tun, ohne dass Ihre Skripte ein Problem haben, aber Sie sollten diese Struktur vermeiden. Dies führt normalerweise zu Verwirrung

0
Bonfire