IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Instancier avant ou dans une boucle ?


Sujet :

C++

  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Instancier avant ou dans une boucle ?
    Dans la foulée de discussions récentes à propos d'habitudes et bonnes pratiques, ceci est un exemple récurrrent où j'hésite entre l'une ou l'autre écriture.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	std::string s;
    	for ( ...; ...; ...)
    	{
    		s.clear();
    		get_string(s);
    		....
    	}
    	std::vector<unsigned> v;
    	for ( ...; ...; ...)
    	{
    		v.clear();
    		get_vector(v);
    		....
    	}
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	for ( ...; ...; ...)
    	{
    		std::string s;
    		get_string(s);
    		....
    	}
    	for ( ...; ...; ...)
    	{
    		std::vector<unsigned> v;
    		get_vector(v);
    		....
    	}
    La 2ème écriture est la plus "naturelle", mais je me demande si la 1ère n'est pas plus performante. Des allocations/désallocations de mém ont lieu systématiquement à chaque itération dans le 2ème cas, avec un "peu de chance" elle seront moins fréquentes dans le 1er.

    On peut généraliser le pb à toute classe autre que string ou vector. Vaut-il mieux instancier un type à l'interieur d'une boucle, ou en dehors juste avant d'y entrer ?

    Merci

  2. #2
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    J'utilise perso la 2eme forme, car elle me semble plus naturelle.
    Mais effectivement la première forme sera très certainement plus performante : clear reset le contenu, mais ne touche pas à la capacité, on évite donc quelques allocations / désallocations.

    edit : Et si on veut le meilleur des 2 mondes, on peut limiter le scope du vector / string
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {
       std::string str;
       for(;;) {
          str.clear();
          // ...
       }
    }

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Je crois qu'en fait, il y a deux aspects clairement distincts à prendre en compte:

    L'aspect purement pratique d'une part:

    Il est généralement plus facile de déterminer l'usage fait d'une variable lorsque sa déclaration est "aussi proche que possible" de son utilisation.

    Cela a, en outre, l'énorme avantage d'en restreindre généralement la portée et donc d'éviter que l'on essaye d'y accéder de manière indue, et c'est, de manière générale, la manière que tend à privilégier C++.

    En cela, la définition d'une variable à l'intérieur de la boucle semble effectivement plus naturelle (et cohérent )

    D'un autre coté, il y a l'aspect des performances, et, comme l'a fait remarquer Iradrille, clear ne fait que changer la taille (comprends : modifier la valeur du nombre d'éléments contenu), sans changer la capacité.

    Tu peux donc très certainement gagner "un peu" de performances en sortant la définition de la boucle.

    Mais...

    Pour que ce gain de performances soit visible (on ne parle jamais que de "quelques cycles" d'horloge), il faudra déjà que ce soit une boucle effectuant de nombreuses itération : il y aura sans doute un intérêt "visible" pour 10 000 ou un million d'itérations, mais si c'est pour n'en faire que dix ou vingt...

    Cela dépend également très fort de ce que tu fais de ta collection (de manière générale) dans la boucle.

    Tu parles d'utiliser clear(), cela implique que le contenu est recréé à chaque fois, et cela implique qu'il faudra sans doute très certainement se poser des questions à ce sujet, comme:

    • Est-il cohérent de recréer le contenu à chaque fois
    • Le contenu varie-t-il si fort d'une itération à l'autre que je ne puisse de rajouter / retirer des éléments d'une itération à l'autre
    • La quantité d'éléments à placer (je considère ici std::string comme une collection de caractères ) dans la collection est-elle suffisamment petite pour que je puisse me permettre de les replacer à chaque fois (recréer une chaine de 10 caractères te le permettra sans doute alors remplir un tableau de 100 000 éléments complexes plaiderait en faveur du fait d'essayer de l'éviter )
    • j'en oublie surement
    Je crois donc qu'il faut, comme toujours, essayer de voir ce qui s'avère le plus adapté à une situation donnée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Je vous recommande l'usage de la deuxième forme pour toutes les raisons que Koala01 a citées.

    Pour les performances, ne vous inquiétez pas, le compilateur s'occupera tout seul de sortir l'allocation de la variable de la boucle. Le clear ne paraît pas très utile avant un get pour la string, il est rare qu'un get de string fasse un append dessus plutôt qu'une assignation.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Pour les performances, ne vous inquiétez pas, le compilateur s'occupera tout seul de sortir l'allocation de la variable de la boucle.
    Je me mets toujours en position d'un disciple de Saint Thomas quant aux optimisations de compilateur. À moins de tomber sur un article approfondi.

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    dans un cas comme celui-là, je pense qu'une autre approche serait envisageable voire préférable selon le code réel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::vector<Item> vec;
    for (..)
    {
     get_vector(vec);
    }
    // je traite ici tout ce que j'ai récupéré
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Pour la string, on va pas gagner grand chose, mais pour le vector, c'est intéressant oui.

    Mais si c'est une list par exemple, ça ne marche plus. C'est vraiment lié à la nature de vector et à son modèle d'allocation.

  8. #8
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    J'ai tendance à préférer limiter la portée, et travailler avec return (j'aime bien les invariants). Avec un peu de RVO/rvalues, il y a moyen de ne pas payer trop d'allocations. Mais au moins une sera toujours payée à cause de la variable que l'on crée à chaque fois.

    La forme avec la variable à l'extérieur, et un paramètre sortant va faire très rapidement des économies sur les allocations. Cela peut valoir le coup si beaucoup d'appels sont faits, et que l'on peut réutiliser la mémoire du conteneur (i.e., s'il n'est pas confié ailleurs). Un des talks du Going Native 2013 en parlait. Celui d'Andrei Alexandrescu si mes souvenirs sont bons.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par jblecanard Voir le message
    Pour la string, on va pas gagner grand chose, mais pour le vector, c'est intéressant oui.

    Mais si c'est une list par exemple, ça ne marche plus. C'est vraiment lié à la nature de vector et à son modèle d'allocation.
    Pour la string c'est ridicule oui, je préfère l'allouer là où j'en ai besoin.

    Vector, List, Dequeue, ... peu importe, tous proposent des méthodes d'append et sont plus ou moins similaires dans leur utilisation.
    Et on peut en faire une utilisation similaire de chacun avec un parcours itératif!
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Pour la string c'est ridicule oui, je préfère l'allouer là où j'en ai besoin.

    Vector, List, Dequeue, ... peu importe, tous proposent des méthodes d'append et sont plus ou moins similaires dans leur utilisation.
    Et on peut en faire une utilisation similaire de chacun avec un parcours itératif!
    Heu... oui mais non...

    Autant je verrais parfaitement un vecteur faire un (équilvalent à) lastIndex = 0 lors de son clear, autant je ne serais pas plus étonné que cela que les liste, file et autres te fasse quelque chose de ressemblant à un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (next){
        temp =next->next_;
        delete next;
        next=temp;
    }
    lors du clear.

    Je n'ai pas vérifié l'implémentation des différents conteneurs en profondeurs, mais il n'y a aucune garantie ni dans un sens ni dans l'autre, et la seule nature du vecteur est d'assurer un accès aléatoire en temps constant alors que les autres assurent un acces séquentiel
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Laissons le code parler:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <iostream>
    #include <vector>
    #include <deque>
    #include <string>
    #include <chrono>
    #include <list>
     
    using namespace std;
    using namespace chrono;
     
    template <typename T> void get(T& v) {
        v.clear();
        for(int i=0;i<1e4;++i) v.push_back("roger");
    }
     
    template <typename T> void evaluate() {
      auto t_start = high_resolution_clock::now();
      for(int j =  0; j < 1e4; ++j) {
        T result;
        get(result);
      }
      auto t_step1 = high_resolution_clock::now();
      T result;
      for(int j =  0; j < 1e4; ++j) {
        get(result);
      }
      auto t_step2 = high_resolution_clock::now();
      cout << duration_cast<milliseconds>(t_step1 - t_start).count() << " ms versus " << duration_cast<milliseconds>(t_step2 - t_step1).count() << " ms" << endl;
    }
     
    int main() {
      evaluate< vector<string> >();
      evaluate< list<string> >();
      evaluate< deque<string> >();
      return 0;
    }
    Compilé avec GCC 4.4.5 (je fais avec ce que j'ai sous la main), -O3 activé. Résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    13318 ms versus 6801 ms (vector)
    10819 ms versus 11484 ms (list)
    8500 ms versus 7426 ms (deque)
    La liste est même moins performante si déclarée en dehors mais c'est pas flagrant. Pour le vector, la messe est dite. Pour la deque, intéressant, mais le teste n'est pas super pertinent car l'implémentation de la deque n'est pas simpliste. A noter que pour le vector, si on connait la taille de la boucle avant, on peut faire un reserve. Pas possible dans le cas de figure montré (je ne sais pas forcément comment "get" est implémenté).

  12. #12
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Intéressant, mais c'est plutôt T result = get() qu'il faudrait écrire. (même si cela ne va pas faire une grosse différence ici)

    (tiens, on dirait que clang 3.4 (compilé il y a deux jours -> r191286) est un chouilla plus rapide que gcc 4.6.3 chez moi)
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Intéressant, mais c'est plutôt T result = get() qu'il faudrait écrire.
    Pour respecter, l'op, je dirais que non car ce n'est pas l'exemple présenté. QU'à cela ne tienne, essayons. Tout d'abord, les résultats du précéndent programme avec des versions plus récentes.

    GCC 4.8.1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    8484 ms versus 5860 ms
    9244 ms versus 9259 ms
    6984 ms versus 5802 ms
    Clang 3.3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    8353 ms versus 5528 ms
    8875 ms versus 8862 ms
    6962 ms versus 5817 ms
    Et maintenant, avec la version suggérée par Luc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <iostream>
    #include <vector>
    #include <deque>
    #include <string>
    #include <chrono>
    #include <list>
     
    using namespace std;
    using namespace chrono;
     
    template <typename T> T get() {
      T v;
      for(int i=0;i<1e4;++i) v.push_back("roger");
      return v;
    }
     
    template <typename T> void evaluate() {
      auto t_start = high_resolution_clock::now();
      for(int j =  0; j < 1e4; ++j) {
        T result = get<T>();
      }
      auto t_step1 = high_resolution_clock::now();
      T result;
      for(int j =  0; j < 1e4; ++j) {
        result = get<T>();
      }
      auto t_step2 = high_resolution_clock::now();
      cout << duration_cast<milliseconds>(t_step1 - t_start).count() << " ms versus " << duration_cast<milliseconds>(t_step2 - t_step1).count() << " ms" << endl;
    }
     
    int main() {
      evaluate< vector<string> >();
      evaluate< list<string> >();
      evaluate< deque<string> >();
      return 0;
    }
    GCC 4.8.1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    8632 ms versus 8140 ms
    9211 ms versus 9204 ms
    7024 ms versus 7298 ms
    Clang 3.3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    8524 ms versus 8066 ms
    9127 ms versus 9108 ms
    7014 ms versus 7213 ms
    Là fort peu de différence entre les techniques. Clang a l'air un peu mieux loti que gcc mais c'est pas énorme et il faudrait faire plein de tests et des moyennes pour le conclure.

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Heu... oui mais non...

    Autant je verrais parfaitement un vecteur faire un (équilvalent à) lastIndex = 0 lors de son clear, autant je ne serais pas plus étonné que cela que les liste, file et autres te fasse quelque chose de ressemblant à un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while (next){
        temp =next->next_;
        delete next;
        next=temp;
    }
    lors du clear.

    Je n'ai pas vérifié l'implémentation des différents conteneurs en profondeurs, mais il n'y a aucune garantie ni dans un sens ni dans l'autre, et la seule nature du vecteur est d'assurer un accès aléatoire en temps constant alors que les autres assurent un acces séquentiel
    Je ne comprends pas ta remarque, la mienne disait juste que de parcourir un vector ou une list est équivalent pour peu qu'on utilise les itérateurs et qu'on parle de parcourir le container. (nb: http://fr.wiktionary.org/wiki/parcourir parcourir = traverser un espace, c'est séquentiel et non aléatoire)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::vector<Item> vec; // ou list
    for(..)
     AppendToContainer(vec);
     
    for(it = vec.begin(); it != vec.end(); ++it)
     it
    Que ce soit un vector, list, dequeue, ... ne change strictement rien à ce parcours final de mon container.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  15. #15
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Mais, à la base, camboui posait la question de savoir s'il valait mieux déclarer ses objet dans la boucle ou les vider avec clear() (en les ayant déclarés hors boucle).

    Ma réflexion était basée sur la question de base de camboui
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    De fait, koala voit juste
    Il s'agit bien de cas où l'usage de variables potentiellement 'lourdes' n'auront qu'une portée locale (les containers STL n'étant qu'un exemple).

    Il est clair que la rigueur voudrait que leur déclaration se trouve dans la boucle, principe que l'on a tous appris lors de l'apprentissage de la prog procédurale (en C ). Merci pour tous vos avis et tests.

    Si on veut sortir l'instantiation locale d'une classe 'lourde' avant la boucle avec 'rigueur', on pourrait ramener le code sous une forme un peu plus poussée (pour peu que cela soit possible).
    L'instantiation serait effectuée de facto 'avant'. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct MyFunctor
    {
      std::vector<unsigned> v;
     
      void operator() (Data const & d)
      {
        v.clear();
        ...
      }
    };
     
    AnyDataContainer<Data> brol;
    ...
    std::for_each (brol.begin(), brol.end(), MyFunctor());
    Et si quelqu'un peut proposer une écriture avec lambda, je suis preneur
    Parce que parfois, les foncteurs c'est lourd...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 05/07/2012, 23h01
  2. test avant d'entrer dans une boucle For each cell in selection
    Par totoro02 dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 13/01/2009, 09h27
  3. swf dans une boucle asp
    Par Chucky69 dans le forum Flash
    Réponses: 11
    Dernier message: 10/02/2004, 17h07
  4. [Vb.net] Indexé un objet crée dans une boucle
    Par picpic dans le forum Windows Forms
    Réponses: 10
    Dernier message: 17/12/2003, 14h37
  5. Pause dans une boucle
    Par HT dans le forum Langage
    Réponses: 4
    Dernier message: 03/06/2003, 08h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo