web-dev-qa-db-fra.com

Initialisation multiple en C # boucle 'pour'

Comment puis-je (si cela est possible) initialiser plusieurs variables de types différents dans une boucle C # for? Exemple:

for (MyClass i = 0, int j = 1; j<3; j++,i++)
45
Lukas

Cela ne peut pas être fait. Placez l'une des déclarations avant la boucle:

MyClass i = 0;
for (int j = 1; j < 3; j++, i++)

Ou pour la symétrie, les deux:

MyClass i = 0;
int j = 1;
for (; j < 3; j++, i++)

Il est également possible que l'une des variables soit plus primaire que l'autre. Dans ce cas, il serait peut-être plus judicieux d'en avoir une comme variable de boucle et de traiter l'autre séparément, comme ceci:

MyClass i = 0;
for (int j = 0; j < 3; j++)
{
    ...
    i++;
}

Notez que si i et j étaient du même type, vous pouvez les déclarer tous les deux dans la boucle for:

for (int i = 0, j = 1; j < 3; j++, i++)
72
Joren

Bien sûr, cela peut être fait. Utilisez simplement le mot clé dynamic :

public static void Main(string[] args) {
    for (dynamic x = 0, y = new MyClass { a = 20, b = 30 }; x < 100; x++, y.a++, y.b--) {
        Console.Write("X=" + x + " (" + x.GetType() + "\n" +
                      "Y.a=" + y.a + ",Y.b=" + y.b + " (" + y.GetType() + "\n");
     }
}

class MyClass {
    public int a = 0, b = 0;
}

Passez une bonne journée!

32

Oui, ça peut se faire. Vous pouvez initialiser des variables de types différents dans une instruction for, mais vous ne pouvez pas declare des variables de types différents dans une instruction for. Pour initialiser des variables de types différents dans une instruction for, vous devez déclarer tous les types avant la boucle for. Par exemple:

int xx;
string yy;
for(xx=0, yy=""; xx<10; xx++)
    {
    ....
    }

[EDIT] Ajout de plus d'informations pour être complet. Cela va au-delà de ce que l'OP a demandé, mais peut être utile pour d'autres . Il est simple d'initialiser des variables du même type dans une boucle for, il suffit de séparer l'initialisation par des virgules. Vous pouvez également avoir plusieurs variables modifiées dans la troisième section. Vous ne pouvez pas avoir plusieurs sections séparées par des virgules dans la seconde section de comparaison, mais vous pouvez utiliser && || et ! créer une section booléenne complexe basée sur plusieurs variables.

for(int i=0, j=0, k=99; i<10 && k<200; i++, j++, k += 2)

Cependant, ce n’est pas une bonne pratique de faire une déclaration tellement complexe qu’il est difficile de comprendre ce qui se passe.

14
Bill W

Est-ce dangereux?

Oui, vraiment. Un analyseur de langage a deux tâches importantes. L'un est le travail que tout le monde connaît, convertir du texte en un programme exécutable. Mais very est également important: il peut détecter un programme invalide et générer un diagnostic significatif pour le programmeur afin qu’il puisse corriger son code.

À un niveau très fondamental, un analyseur de langage fait la distinction entre déclarations, instructions et expressions. Les langages en accolades masquent cette distinction, vous pouvez transformer n'importe quelle expression en une déclaration, en mettant simplement un point-virgule après celle-ci. Et dans certains cas, accepter une déclaration dans une instruction, l'instruction for (;;) est un bon exemple. Plus précisément, cette syntaxe est parfaitement acceptable dans les langages C ou C++:

int x = 42;
x;

Ce n'est pas vraiment une bonne chose, c'est un code insensé. Le langage C # a élevé la barre, il le rejettera. Mais non:

int x = 42;
x++;

Une règle spéciale ajoutée à l'analyseur de langue pour accepter ceci.

Ce qu’aucun des langages en accolades n’acceptera, c’est de transformer une déclaration en expression. De cette façon, la folie, les dragons au bout de la carte, le navire tombe du bord sans aucun message positif à signaler. L'opérateur de virgule requiert que les opérandes gauches et droits soient des expressions. Une déclaration n'est pas une expression, une fin d'histoire.

8
Hans Passant

Je mets généralement les déclarations avant loop et utilise des accolades supplémentaires pour limiter la portée des déclarations:

{ //limit the scope: i, count, iDivisibleBy2, iDivisibleBy3, iDivisibleBy5
    int i = 0, count = 100;
    bool iDivisibleBy2 = true, iDivisibleBy3 = true, iDivisibleBy5 = true;
    for( ; i < count; ++i, iDivisibleBy2 = (i % 2 == 0), iDivisibleBy3 = ( i % 3 == 0 ), iDivisibleBy5 = ( i % 5 == 0 ) )
    {
        //...
    }
}
5
Vladimir Liubimov
for (initializer; condition; iterator)
{
    //body
}

Le initialiseur section définit les conditions initiales. Les instructions de cette section ne sont exécutées qu’une seule fois, avant que vous ne commenciez la boucle. La section ne peut contenir qu'une des deux options suivantes.

1) La déclaration et l’initialisation d’une variable de boucle locale. La variable est locale à la boucle et n'est pas accessible de l'extérieur.

2) Zéro ou plusieurs expressions d'instruction de la liste suivante, séparées par des virgules:

  • Déclaration de mission;

  • Invocation d'une méthode;

  • Expression d'incrément de préfixe ou postfix, telle que ++ i ou i ++;

  • Préfixe ou postfixe décrémentant l'expression, telle que --i ou i--;

  • Création d'un objet en utilisant new;

  • Attendre l'expression;

Comme nous le savons, le compilateur n’est pas conçu pour accepter ce que nous attendons. Donc, ce qui précède est les règles doivent être suivies avant d'écrire un section d'initialisation dans une boucle for.

http://msdn.Microsoft.com/en-us/library/ch45axte.aspx

1
Hash

Vous ne pouvez pas définir plus d'une variable dans une structure en boucle. Essayez le code ci-dessous: 

Option 1: Une variable déclarée avant boucle et incrémentée manuellement en boucle une fois par itération.

MyClass i = 0;
for (int j = 1; j<3; j++)
{
  //do stuff
  i++
}

Option 2: les deux variables définies auparavant pour la boucle et une incrémentée dans la structure de la boucle, et les autres dans la boucle manuellement. 

MyClass i = 0;
int j = 1
for (; j<3; j++)
{
  //do stuff
  i++
}

Option 3: les deux variables sont définies avant la structure de la boucle for, et les deux variables sont incrémentées dans la boucle, laissant la boucle uniquement à la recherche d'une condition qui, à ce stade, ne permet de faire qu'une boucle while.

MyClass i = 0;
int j = 1
for (; j<3)
{
  //do stuff
  j++
  i++
}

Option 4: écrire comme une boucle while

MyClass i = 0;
int j = 1
while (j<3)
{
  //do stuff
  j++
  i++
}
0
PhoenixLament

À partir de C # 7, utilisez un tuple:

for (var foo = (i:new MyClass(0), j:1); foo.j < 3; foo.i++, foo.j++)) { … }
0
agentnega

Amusons-nous. Je vous laisse le soin de décider si vous devriez réellement l'utiliser n'importe où ...: P

Il est possible (indirectement) de déclarer et d’initialiser autant de variables que vous le souhaitez de types différents dans l’initialiseur de boucle for sans utiliser la clé dynamique Word. Utilisez simplement une structure personnalisée pour votre variable d’index.

for(var i = new I1<MyClass>(0, 1); i < 3; i++, i.a++) {
    MyClass myClass = i.a;
}

Les opérateurs surchargés signifient que vous pouvez utiliser "i" comme un int partout. Pour une syntaxe propre, initialisez avec 0:

for(I1<float> i = 0; i < array.Length; i++) {
    i.a += array[i]; // accumulate a float value
}

Quelques exemples plus stupides:

// Three variables
for(I3<object, string, int> i = 0; i < 100; i++) {
    i.a = new object();
    i.b = "This is index " + i;
    i.c = 100 - i;
}

// A class
for(var i = new I1<SomeClass>(0, new SomeClass()); i < 20; i += 2) {
    i.a.someVar1 = "We can have even more variables in here! Woot!";
    i.a.DoSomething(i);
}

// An array
for(var i = new I1<string[]>(0, new[] { "Hi", "Mom" }); i < 10; i++) {
    for(int j = 0; j < i.a.Length; j++) {
        Log(i.a[j]);
    }
}

Voici les structs. Ils fonctionnent mais ne sont pas testés en profondeur, donc il peut y avoir des bugs:

public struct I1<T> {

    public int index;
    public T a;

    public I1(int index) {
        this.index = index;
        this.a = default(T);
    }
    public I1(int index, T a) {
        this.index = index;
        this.a = a;
    }

    public override bool Equals(object obj) {
        if(!(obj is I1<T>)) return false;
        I1<T> other = (I1<T>)obj;
        return index == other.index && EqualityComparer<T>.Default.Equals(a, other.a);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I1<T>(int other) {
        return new I1<T>(other);
    }

    public static implicit operator int(I1<T> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I1<T> a) {
        return +a.index;
    }

    public static int operator -(I1<T> a) {
        return -a.index;
    }

    public static int operator ~(I1<T> a) {
        return ~a.index;
    }

    public static I1<T> operator ++(I1<T> a) {
        a.index++;
        return a;
    }

    public static I1<T> operator --(I1<T> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I1<T> operator +(I1<T> a, int b) {
        a.index += b;
        return a;
    }
    public static I1<T> operator +(int a, I1<T> b) {
        b.index += a;
        return b;
    }

    public static I1<T> operator -(I1<T> a, int b) {
        a.index -= b;
        return a;
    }
    public static I1<T> operator -(int a, I1<T> b) {
        b.index = a - b.index;
        return b;
    }

    public static I1<T> operator *(I1<T> a, int b) {
        a.index *= b;
        return a;
    }
    public static I1<T> operator *(int a, I1<T> b) {
        b.index *= a;
        return b;
    }

    public static I1<T> operator /(I1<T> a, int b) {
        a.index /= b;
        return a;
    }
    public static I1<T> operator /(int a, I1<T> b) {
        b.index = a / b.index;
        return b;
    }

    public static I1<T> operator %(I1<T> a, int b) {
        a.index %= b;
        return a;
    }
    public static I1<T> operator %(int a, I1<T> b) {
        b.index = a % b.index;
        return b;
    }

    public static I1<T> operator &(I1<T> a, int b) {
        a.index &= b;
        return a;
    }
    public static I1<T> operator &(int a, I1<T> b) {
        b.index = a & b.index;
        return b;
    }

    public static I1<T> operator |(I1<T> a, int b) {
        a.index |= b;
        return a;
    }
    public static I1<T> operator |(int a, I1<T> b) {
        b.index = a | b.index;
        return b;
    }

    public static I1<T> operator ^(I1<T> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I1<T> operator ^(int a, I1<T> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I1<T> operator <<(I1<T> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I1<T> operator >>(I1<T> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I1<T> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I1<T> b) {
        return a == b.index;
    }

    public static bool operator !=(I1<T> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I1<T> b) {
        return a != b.index;
    }

    public static bool operator <(I1<T> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I1<T> b) {
        return a < b.index;
    }

    public static bool operator >(I1<T> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I1<T> b) {
        return a > b.index;
    }

    public static bool operator <=(I1<T> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I1<T> b) {
        return a <= b.index;
    }

    public static bool operator >=(I1<T> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I1<T> b) {
        return a >= b.index;
    }
}

public struct I2<T1, T2> {

    public int index;
    public T1 a;
    public T2 b;

    public I2(int index) {
        this.index = index;
        this.a = default(T1);
        this.b = default(T2);
    }
    public I2(int index, T1 a) {
        this.index = index;
        this.a = a;
        this.b = default(T2);
    }
    public I2(int index, T1 a, T2 b) {
        this.index = index;
        this.a = a;
        this.b = b;
    }

    public override bool Equals(object obj) {
        if(!(obj is I2<T1, T2>)) return false;
        I2<T1, T2> other = (I2<T1, T2>)obj;
        return index == other.index && EqualityComparer<T1>.Default.Equals(a, other.a) && EqualityComparer<T2>.Default.Equals(b, other.b);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T1).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        if(typeof(T2).IsValueType && !object.ReferenceEquals(b, null)) hash = hash * 29 + b.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I2<T1, T2>(int other) {
        return new I2<T1, T2>(other);
    }

    public static implicit operator int(I2<T1, T2> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I2<T1, T2> a) {
        return +a.index;
    }

    public static int operator -(I2<T1, T2> a) {
        return -a.index;
    }

    public static int operator ~(I2<T1, T2> a) {
        return ~a.index;
    }

    public static I2<T1, T2> operator ++(I2<T1, T2> a) {
        a.index++;
        return a;
    }

    public static I2<T1, T2> operator --(I2<T1, T2> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I2<T1, T2> operator +(I2<T1, T2> a, int b) {
        a.index += b;
        return a;
    }
    public static I2<T1, T2> operator +(int a, I2<T1, T2> b) {
        b.index += a;
        return b;
    }

    public static I2<T1, T2> operator -(I2<T1, T2> a, int b) {
        a.index -= b;
        return a;
    }
    public static I2<T1, T2> operator -(int a, I2<T1, T2> b) {
        b.index = a - b.index;
        return b;
    }

    public static I2<T1, T2> operator *(I2<T1, T2> a, int b) {
        a.index *= b;
        return a;
    }
    public static I2<T1, T2> operator *(int a, I2<T1, T2> b) {
        b.index *= a;
        return b;
    }

    public static I2<T1, T2> operator /(I2<T1, T2> a, int b) {
        a.index /= b;
        return a;
    }
    public static I2<T1, T2> operator /(int a, I2<T1, T2> b) {
        b.index = a / b.index;
        return b;
    }

    public static I2<T1, T2> operator %(I2<T1, T2> a, int b) {
        a.index %= b;
        return a;
    }
    public static I2<T1, T2> operator %(int a, I2<T1, T2> b) {
        b.index = a % b.index;
        return b;
    }

    public static I2<T1, T2> operator &(I2<T1, T2> a, int b) {
        a.index &= b;
        return a;
    }
    public static I2<T1, T2> operator &(int a, I2<T1, T2> b) {
        b.index = a & b.index;
        return b;
    }

    public static I2<T1, T2> operator |(I2<T1, T2> a, int b) {
        a.index |= b;
        return a;
    }
    public static I2<T1, T2> operator |(int a, I2<T1, T2> b) {
        b.index = a | b.index;
        return b;
    }

    public static I2<T1, T2> operator ^(I2<T1, T2> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I2<T1, T2> operator ^(int a, I2<T1, T2> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I2<T1, T2> operator <<(I2<T1, T2> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I2<T1, T2> operator >>(I2<T1, T2> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I2<T1, T2> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I2<T1, T2> b) {
        return a == b.index;
    }

    public static bool operator !=(I2<T1, T2> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I2<T1, T2> b) {
        return a != b.index;
    }

    public static bool operator <(I2<T1, T2> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I2<T1, T2> b) {
        return a < b.index;
    }

    public static bool operator >(I2<T1, T2> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I2<T1, T2> b) {
        return a > b.index;
    }

    public static bool operator <=(I2<T1, T2> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I2<T1, T2> b) {
        return a <= b.index;
    }

    public static bool operator >=(I2<T1, T2> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I2<T1, T2> b) {
        return a >= b.index;
    }
}

public struct I3<T1, T2, T3> {

    public int index;
    public T1 a;
    public T2 b;
    public T3 c;

    public I3(int index) {
        this.index = index;
        this.a = default(T1);
        this.b = default(T2);
        this.c = default(T3);
    }
    public I3(int index, T1 a) {
        this.index = index;
        this.a = a;
        this.b = default(T2);
        this.c = default(T3);
    }
    public I3(int index, T1 a, T2 b) {
        this.index = index;
        this.a = a;
        this.b = b;
        this.c = default(T3);
    }
    public I3(int index, T1 a, T2 b, T3 c) {
        this.index = index;
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public override bool Equals(object obj) {
        if(!(obj is I3<T1, T2, T3>)) return false;
        I3<T1, T2, T3> other = (I3<T1, T2, T3>)obj;
        return index == other.index && EqualityComparer<T1>.Default.Equals(a, other.a) &&
            EqualityComparer<T2>.Default.Equals(b, other.b) &&
            EqualityComparer<T3>.Default.Equals(c, other.c);
    }

    public override int GetHashCode() {
        int hash = 17;
        hash = hash * 29 + index.GetHashCode();
        if(typeof(T1).IsValueType && !object.ReferenceEquals(a, null)) hash = hash * 29 + a.GetHashCode();
        if(typeof(T2).IsValueType && !object.ReferenceEquals(b, null)) hash = hash * 29 + b.GetHashCode();
        if(typeof(T3).IsValueType && !object.ReferenceEquals(c, null)) hash = hash * 29 + c.GetHashCode();
        return hash;
    }

    public override string ToString() {
        return index.ToString();
    }

    public static implicit operator I3<T1, T2, T3>(int other) {
        return new I3<T1, T2, T3>(other);
    }

    public static implicit operator int(I3<T1, T2, T3> other) {
        return other.index;
    }

    // Unary operators

    public static int operator +(I3<T1, T2, T3> a) {
        return +a.index;
    }

    public static int operator -(I3<T1, T2, T3> a) {
        return -a.index;
    }

    public static int operator ~(I3<T1, T2, T3> a) {
        return ~a.index;
    }

    public static I3<T1, T2, T3> operator ++(I3<T1, T2, T3> a) {
        a.index++;
        return a;
    }

    public static I3<T1, T2, T3> operator --(I3<T1, T2, T3> a) {
        a.index--;
        return a;
    }

    // Binary operators

    public static I3<T1, T2, T3> operator +(I3<T1, T2, T3> a, int b) {
        a.index += b;
        return a;
    }
    public static I3<T1, T2, T3> operator +(int a, I3<T1, T2, T3> b) {
        b.index += a;
        return b;
    }

    public static I3<T1, T2, T3> operator -(I3<T1, T2, T3> a, int b) {
        a.index -= b;
        return a;
    }
    public static I3<T1, T2, T3> operator -(int a, I3<T1, T2, T3> b) {
        b.index = a - b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator *(I3<T1, T2, T3> a, int b) {
        a.index *= b;
        return a;
    }
    public static I3<T1, T2, T3> operator *(int a, I3<T1, T2, T3> b) {
        b.index *= a;
        return b;
    }

    public static I3<T1, T2, T3> operator /(I3<T1, T2, T3> a, int b) {
        a.index /= b;
        return a;
    }
    public static I3<T1, T2, T3> operator /(int a, I3<T1, T2, T3> b) {
        b.index = a / b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator %(I3<T1, T2, T3> a, int b) {
        a.index %= b;
        return a;
    }
    public static I3<T1, T2, T3> operator %(int a, I3<T1, T2, T3> b) {
        b.index = a % b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator &(I3<T1, T2, T3> a, int b) {
        a.index &= b;
        return a;
    }
    public static I3<T1, T2, T3> operator &(int a, I3<T1, T2, T3> b) {
        b.index = a & b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator |(I3<T1, T2, T3> a, int b) {
        a.index |= b;
        return a;
    }
    public static I3<T1, T2, T3> operator |(int a, I3<T1, T2, T3> b) {
        b.index = a | b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator ^(I3<T1, T2, T3> a, int b) {
        a.index ^= b;
        return a;
    }
    public static I3<T1, T2, T3> operator ^(int a, I3<T1, T2, T3> b) {
        b.index = a ^ b.index;
        return b;
    }

    public static I3<T1, T2, T3> operator <<(I3<T1, T2, T3> a, int b) {
        a.index <<= b;
        return a;
    }

    public static I3<T1, T2, T3> operator >>(I3<T1, T2, T3> a, int b) {
        a.index >>= b;
        return a;
    }

    // Comparison operators

    public static bool operator ==(I3<T1, T2, T3> a, int b) {
        return a.index == b;
    }
    public static bool operator ==(int a, I3<T1, T2, T3> b) {
        return a == b.index;
    }

    public static bool operator !=(I3<T1, T2, T3> a, int b) {
        return a.index != b;
    }
    public static bool operator !=(int a, I3<T1, T2, T3> b) {
        return a != b.index;
    }

    public static bool operator <(I3<T1, T2, T3> a, int b) {
        return a.index < b;
    }
    public static bool operator <(int a, I3<T1, T2, T3> b) {
        return a < b.index;
    }

    public static bool operator >(I3<T1, T2, T3> a, int b) {
        return a.index > b;
    }
    public static bool operator >(int a, I3<T1, T2, T3> b) {
        return a > b.index;
    }

    public static bool operator <=(I3<T1, T2, T3> a, int b) {
        return a.index <= b;
    }
    public static bool operator <=(int a, I3<T1, T2, T3> b) {
        return a <= b.index;
    }

    public static bool operator >=(I3<T1, T2, T3> a, int b) {
        return a.index >= b;
    }
    public static bool operator >=(int a, I3<T1, T2, T3> b) {
        return a >= b.index;
    }
}
0
Guavaman

Ce n’est pas particulièrement mon expertise, mais voici ma réflexion sur le sujet:

Dans la théorie des langages de programmation, la syntaxe d'un langage doit être définie sans ambiguïté. Je ne peux pas entrer dans les détails, car cela fait deux ans que j'ai étudié ces sujets. Mais vous pouvez vérifier Forme Backus-Naur C'est une technique de notation pour décrire la "grammaire" du langage. Et c'est le seul que je connaisse.

Donc, cette description est utilisée lors de l'analyse du code. Et votre analyseur doit pouvoir relier chaque partie de votre code aux "règles" de la grammaire. Vous pouvez voir C # Grammar ici . C'est un peu sous une forme similaire.

(1) Jetez un coup d'œil à la syntaxe for-statement

for-statement:
    for(for-initializer;for-condition;for-iterator)   
        embedded-statement

puis pour la syntaxe d'initialisation

for-initializer:
    local-variable-declaration
    statement-expression-list

Notez que statement-expression-list est uniquement utilisé dans les boucles for. C'est aussi une liste d'expressions d'instructions séparées par des virgules.

Je vais laisser quelques étapes intermédiaires ici, mais vous pouvez suivre la grammaire pour vous mettre à l'aise avec l'idée.

Ici est un bon ensemble de diapositives de base qui montre à quel point les choses peuvent être compliquées même avec une grammaire trivialement simple.

(2) Ce que nous avons observé dans 1 est ce que nous pouvons mettre pour la partie initialisation de la boucle for. Et nous savons que votre proposition ne fonctionne pas. Pour être le chasseur de primes, analysons la raison de ce choix de conception.

Tout d'abord, c'est un choix de conception. Vous pouvez concevoir ou trouver un langage qui le permet. Cela devrait être possible en changeant la grammaire, cependant quelques modifications syntaxiques pourraient être nécessaires. Voici pourquoi;

Si vous voulez placer plusieurs instructions de déclaration, vous voudrez peut-être quelque chose comme liste de déclarations. Et ce que vous allez utiliser pour séparer, vous ne voudriez probablement pas utiliser; car un point-virgule est utilisé pour séparer des parties de la boucle for. Ainsi, vous pouvez toujours choisir une virgule, mais si vous utilisez virgule, la règle de déclaration-liste ne peut être utilisée que dans les boucles for, car il serait déroutant d'avoir des déclarations séparées par des virgules dans tout votre code.

Deuxièmement, qu'est-ce qui ne va pas avec ça? Si vous me demandez, je ne vois rien de mal non plus. S'ils ont conçu la langue, cela aurait dû fonctionner. (Je ne dis pas que le croquis que je viens de faire est correct à 100%, il ne peut être utilisé que comme point de départ d'une session de brainstorming.)

Alors, pourquoi ont-ils choisi de ne pas le faire? Qu'est-ce qui les a poussés à éviter cela? 

  • Quelle complication introduisez-vous en ajoutant cette règle à votre grammaire ?__? 
  • Pensez-vous également combien de règles supplémentaires devez-vous ajouter pour rendre le langage sans ambiguïté?
  • Vous rendez-vous compte à quel point les règles existantes peuvent être compliquées?
  • Quelle charge de travail ajoute-t-on à votre analyseur puis au compilateur?

Après toutes ces considérations et bien d’autres, 

  • Combien ajoutez-vous à la convivialité et à la lisibilité de votre langue?
  • Ou perdez-vous même de la lisibilité?
  • Estimez-vous à quelle fréquence les programmeurs ont besoin de ce type de boucles for ?
  • Même s'ils en ont souvent besoin, devriez-vous les encourager ou les décourager pour ce type de codage?

... et tant d'autres questions comme celles-ci, doivent être considérées avec soin. Et en regardant ces questions et leur analyse, je dirais que le choix de conception des concepteurs de compilateurs était à peu près l'approche la plus acceptable. 

0

Il y a peu de raisons de ne pas avoir un indexeur alternatif initialisé dans la bande. Il préserve l'environnement des affectations trashy var.

for (int x=0,y = 0; x < 100; x++)
{
    if (true) {  y++; }
    // ... use y as a conditional indexer
    // ... x is always the loop indexer
    // ... no overflows
}
0
Zorro Borealis

Je ne pense pas que vous puissiez définir plus d'un type dans une boucle for . Uniquement pour (int i = 0, j = 3; j <7; j ++, i ++)

0
Dani