Puis-je utiliser la même variable de compteur pour une boucle for
à l’intérieur d’une boucle for
?
Ou les variables seront-elles mutuellement affectées? Le code suivant devrait-il utiliser une variable différente pour la seconde boucle, telle que j
, ou est-ce que i
vais bien?
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) { } }
Vous pouvez utiliser le même nom (identifiant). Ce sera un object différent. Ils ne s’affecteront pas. À l’intérieur de la boucle interne, il n’y a aucun moyen de faire référence à l’object utilisé dans la boucle externe (à moins que vous ne preniez des dispositions spéciales pour cela, en lui fournissant un pointeur).
Ceci est généralement un mauvais style, est sujet à la confusion et devrait être évité.
Les objects ne sont différents que si celui-ci est défini séparément, comme avec l’ int i
vous avez montré. Si le même nom est utilisé sans définir de nouvel object, les boucles utiliseront le même object et interféreront les unes avec les autres.
Tout d’abord, ceci est absolument légal: le code va comstackr et exécuter, en répétant le corps de la boucle nestede 10 × 10 = 100 fois. Le compteur de boucles à l’intérieur de la boucle nestede cachera le compteur de la boucle externe, les deux compteurs seront donc incrémentés indépendamment les uns des autres.
Comme le i
externe est caché, le code à l’intérieur du corps de la boucle nestede n’aurait access qu’à la valeur de i
de la boucle nestede, pas à celle de la boucle externe. Dans les situations où la boucle nestede n’a pas besoin d’accéder à l’extérieur, ce code pourrait être parfaitement justifiable. Cependant, cela risque de créer plus de confusion chez ses lecteurs. Il est donc préférable d’éviter d’écrire un tel code pour éviter les «obligations de maintenance».
Remarque: Même si les variables de compteur des deux boucles ont le même identifiant i
, elles restnt deux variables indépendantes, c’est-à-dire que vous n’utilisez pas la même variable dans les deux boucles. L’utilisation de la même variable dans les deux boucles est également possible, mais le code serait difficile à lire. Voici un exemple:
for (int i = 1 ; i < 100 ; i++) { for ( ; i % 10 != 0 ; i++) { printf("%02d ", i); } printf("%d\n", i); }
Maintenant, les deux boucles utilisent la même variable. Cependant, il faut du temps pour comprendre ce que fait ce code sans le comstackr ( démo );
Vous pouvez. Mais vous devez être conscient de la scope des i
. si nous appelons le i
externe avec i_1
et le interne i
avec i_2
, la scope des i
s est la suivante:
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 }
Vous devriez remarquer qu'ils ne s’affectent pas et que leur définition est différente.
C’est tout à fait possible mais gardez à l’esprit que vous ne pourrez pas répondre au premier
for(int i = 0; i < 10; i++)//I MEAN THE ONE HERE { for(int i = 0; i < 10; i++) { } }
dans la seconde boucle dans la seconde boucle enfant
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 } }
si vous devez ajuster ou obtenir la valeur du premier i, utilisez j dans la seconde boucle
for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { } }
et si votre créativité est suffisante, vous pouvez faire les deux en une seule boucle
for(int i ,j= 0; i < 10; (j>9) ? (i++,j=0) : 0 ,j++) { printf("%d %d\n",i,j); }
Oui, vous pouvez utiliser le même nom de variable de compteur pour une boucle interne for
boucle externe for
.
De pour la boucle :
for ( init_clause ; cond_expression ; iteration_expression ) loop_statement
L’instruction expression utilisée en tant que loop_statement établit sa propre étendue de bloc, distincte de la scope de init_clause .for (int i = 0; ; ) { long i = 1; // valid C, invalid C++ // ... }
La scope de loop_statement est nestede dans la scope de init_clause .
From C Standards # 6.8.5p5 Énoncés d’itération [emphase sur le mien]
Une instruction d’itération est un bloc dont la scope est un sous-ensemble ssortingct de la scope de son bloc englobant. Le corps de la boucle est également un bloc dont la scope est un sous-ensemble ssortingct de la scope de l’instruction d’itération .
From C Standards # 6.2.1p4 Étendue des identificateurs [emphase sur la mienne]
…. Dans le cadre interne, l’identifiant désigne l’entité déclarée dans le périmètre interne; l’ entité déclarée dans la scope externe est masquée (et non visible) dans la scope interne.
Du sharepoint vue du code / du compilateur, cela serait parfaitement valable et légal. Le int i
déclaré dans la boucle interne for(int i = 0; i < 10; i++)
est dans une nouvelle et plus petite étendue, de sorte que la déclaration masque la déclaration de int i
dans la boucle externe (ou, avec d'autres mots: la scope interne tous accède à la variable i
vais à l' int i
déclaré dans la scope interne, en laissant int i
dans la scope externe intacte).
Cela dit, du sharepoint vue de la qualité du code, c'est absolument horrible. Il est difficile à lire, difficile à comprendre et à comprendre. Ne le fais pas
Oui, vous pouvez certainement utiliser la même variable de nom.
Les variables de programmation C peuvent être déclarées à trois endroits:
variables locales: -Intérieur d’une fonction ou d’un bloc.
Variables globales: -Out de toutes les fonctions.
Paramètres formels: -Dans les parameters de la fonction.
Mais dans votre cas, i scope
faire attention aux choses en dessous
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 }
Remarque: il est recommandé d’utiliser différentes variables pour les boucles internes et externes.
Oui, vous pouvez l’utiliser, mais c’est assez déroutant. La chose la plus importante est la scope de la variable locale dans la boucle. Si une variable est déclarée dans une fonction, la scope de cette variable est cette fonction.
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
De même, le cas des boucles, des variables déclarées dans la boucle interne ont une scope différente et la variable déclarée de la boucle externe a une scope différente.
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 }
La meilleure approche consiste à utiliser différentes variables pour les boucles internes et externes.
for(int i = 0; i < 10; i++){ for(int j = 1; j < 10; j++){ } }
Oui, et encore plus intéressant, vous pouvez réutiliser un nom de variable chaque fois que vous ouvrez un ensemble d’accolades. Ceci est souvent utile lors de l’insertion du code de diagnostic. Tapez une accolade ouverte ‘{‘ suivie d’une déclaration et de l’utilisation de variables, puis fermez l’accolade et les variables disparaissent. Cela garantit que vous n’interférerez avec rien dans le corps principal tout en conservant l’avantage des variables, classes et méthodes déclarées en dehors des accolades.
Règle de scope: Une variable déclarée dans une instruction for ne peut être utilisée que dans cette instruction et dans le corps de la boucle.
Si dans votre code vous avez défini plusieurs instances de i dans les boucles internes, chaque instance occupera son propre espace mémoire. Il n’y a donc pas de quoi s’inquiéter des résultats, ce serait la même chose.
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; }
Mais il n'est pas recommandé d'utiliser le même nom de variable car il est difficile à comprendre et devient un code non maintenable plus tard.
La partie importante est que le paramètre de boucle interne contient int i
. Parce que i
redéfini de cette manière, les deux variables ne s’affectent pas; leurs scopes sont différentes. Voici deux exemples pour montrer ceci:
for(int i = 0; i < 10; i++) // This code will print "Test" 100 times { for(int i = 0; i < 10; i++) { puts("Test"); } }
Notez que le code ci-dessus inclut int i
dans le paramètre de boucle interne, et le code ci-dessous inclut uniquement i
.
for(int i = 0; i < 10; i++) // This code will print "Test" 10 times { for(i = 0; i < 10; i++) { puts("Test"); } }