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 in i
Ordnung?
for(int i = 0; i < 10; i++)
{
for(int i = 0; i < 10; i++)
{
}
}
i
mit unterschiedlichen Gültigkeitsbereichen. Verwenden Sie diese-Wshadow
Option mit GCC, um solche Probleme automatisch zu melden.-Wshadow
das nicht enthalten ist-Wall
.-Wshadow
warnt auch vor dem Abschatten globaler Variablen, was bei größeren Projekten leicht ärgerlich werden kann.-Wextra
nicht enthalten-Wshadow
. Ich denke, es ist in einigen Projekten häufig genug, oder ein gcc- Entwickler liebt Shadowing als Codierungsstil, um zu rechtfertigen, dass er so ausgelassen wird.-Wshadow
hat eine schreckliche Falsch-Positiv-Rate, die es völlig unbrauchbar macht. Der Geltungsbereich besteht aus einem bestimmten Grund, und das Abschatten ist von vornherein nicht problematisch. Jetzt-Wshadow-local
(Anmerkung: nicht-Wshadow=local
) ist ganz anders. Leider hat sich GCC bisher geweigert, es in den Kofferraum aufzunehmen (obwohl es anscheinend Gabeln von GCC gibt, die es enthalten).Antworten:
Sie können denselben 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 hierfür besondere 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 ist, wie bei dem von
int i
Ihnen gezeigten. Wenn derselbe Name verwendet wird, ohne ein neues Objekt zu definieren, verwenden die Schleifen dasselbe Objekt und stören sich gegenseitig.quelle
Erstens ist dies absolut legal: Der Code wird kompiliert und ausgeführt, wobei der Hauptteil der verschachtelten Schleife 10 × 10 = 100 Mal wiederholt wird. Der Schleifenzähler
i
innerhalb der verschachtelten Schleife verbirgt den Zähler der äußeren Schleife, sodass die beiden Zähler unabhängig voneinander inkrementiert werden.Da das Äußere
i
ausgeblendet ist, hat der Code im Körper der verschachtelten Schleife nur Zugriff auf den Werti
der verschachtelten Schleife, nichti
von der äußeren Schleife. In Situationen, in denen die verschachtelte Schleife keinen Zugriff auf den äußereni
Code benötigt, kann ein solcher Code durchaus gerechtfertigt sein. Dies führt jedoch wahrscheinlich zu mehr Verwirrung bei den Lesern. Daher ist es eine gute Idee, das Schreiben eines solchen Codes zu vermeiden, um "Wartungsverpflichtungen" zu vermeiden.Hinweis: Obwohl die Zählervariablen beider Schleifen denselben Bezeichner haben
i
, bleiben sie zwei unabhängige Variablen, dh Sie verwenden nicht dieselbe Variable 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:Jetzt verwenden beide Schleifen dieselbe Variable. Es dauert jedoch eine Weile, um herauszufinden, was dieser Code tut, ohne ihn zu kompilieren ( Demo ).
quelle
int
innere for-Schleife weglassen , dh tatsächlich dieselbe Zählervariable verwenden , wird die äußere Schleife nur einmal ausgeführt, da die innere Schleife verlassen wirdi == 10
. Dies ist trivial, aber gedacht, es bietetSie können. Sie sollten sich jedoch des Umfangs der
i
s bewusst sein . Wenn wir das Äußerei
miti_1
und das Innerei
mit nenneni_2
, ist der Umfang desi
s wie folgt:Sie sollten beachten, dass sie sich nicht gegenseitig beeinflussen und nur ihr Definitionsumfang unterschiedlich ist.
quelle
Das ist durchaus möglich, aber denken Sie daran, dass Sie das erste deklarierte i nicht ansprechen können
in der zweiten Schleife innerhalb der zweiten untergeordneten Schleife
Wenn Sie den Wert des ersten i anpassen oder abrufen müssen, verwenden Sie j in der zweiten Schleife
und wenn Sie kreativ genug sind, können Sie beide in einer Schleife ausführen
quelle
Ja, Sie können für eine innere
for
Schleife denselben Zählervariablennamen verwenden wie für die äußerefor
Schleife.Von for-Schleife :
Der Bereich von loop_statement ist im Bereich von init_clause verschachtelt .
Aus C-Standards # 6.8.5p5 Iterationsanweisungen [Hervorhebung von mir]
Aus C-Standards # 6.2.1p4 Identifikationsbereiche [Schwerpunkt Mine]
quelle
Aus Sicht des Codes / Compilers wäre dies eine absolut gültige und legale Angelegenheit. Die
int i
in der inneren erklärtfor(int i = 0; i < 10; i++)
Schleife ist in einem neuen, kleineren Umfang, so dass in der Erklärung shadows die Erklärung derint i
in der äußeren Schleife (oder, mit anderen Worten: In dem Innenumfang alle Zugriffe auf die Variablei
Show dieint i
in dem inneren Umfang erklärt, dasint i
im äußeren Bereich unberührt lassen).Aus Sicht der Codequalität ist dies jedoch absolut schrecklich. Es ist schwer zu lesen, schwer zu verstehen und leicht zu missverstehen. Tu es nicht.
quelle
Ja, Sie können es verwenden, aber es ist ziemlich verwirrend. Das Wichtigste ist der Umfang der lokalen Variablen innerhalb der Schleife. Wenn eine Variable innerhalb einer Funktion deklariert ist, ist der Umfang dieser Variablen diese Funktion.
In ähnlicher Weise haben Variablen, die innerhalb der inneren Schleife deklariert wurden, unterschiedliche Gültigkeitsbereiche und Variablen, die innerhalb der inneren Schleife deklariert wurden, unterschiedliche Gültigkeitsbereiche.
Der bessere Ansatz besteht darin, unterschiedliche Variablen für innere und äußere Schleifen zu verwenden.
quelle
Ja, definitiv können Sie dieselbe Namensvariable verwenden.
C-Programmiervariablen können an drei Stellen deklariert werden:
lokale Variablen: -In einer Funktion oder einem Block.
Globale Variablen: -Aus allen Funktionen.
Formale Parameter: -In den Funktionsparametern.
Aber in Ihrem Fall
i scope
müssen Sie unten Dinge beachtenHinweis: Es wird empfohlen, unterschiedliche Variablen für innere und äußere Schleifen zu verwenden
quelle
Ja - und noch interessanter ist, dass Sie einen Variablennamen jedes Mal wiederverwenden können, wenn Sie eine Reihe von Klammern öffnen. Dies ist häufig beim Einfügen von Diagnosecode hilfreich. Geben Sie eine offene Klammer '{' ein, gefolgt von der Deklaration und Verwendung von Variablen, 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 behalten, die außerhalb der geschweiften Klammern deklariert sind.
quelle
Geltungsbereichsregel: Eine in einer for-Anweisung deklarierte Variable kann nur in dieser Anweisung und im Hauptteil 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 das gleiche.
Es wird jedoch nicht empfohlen, denselben Variablennamen zu verwenden, da dieser schwer zu verstehen ist und später zu nicht wartbarem Code wird.
quelle
Der wichtige Teil ist, dass der innere Schleifenparameter enthält
int i
. Dai
dies 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:Beachten Sie, dass der obige Code
int i
im Parameter der inneren Schleife enthalten ist und der folgende Code nur enthälti
.quelle
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
quelle