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

Autres éditeurs Discussion :

post et pré incrémentation


Sujet :

Autres éditeurs

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 11
    Points : 19
    Points
    19
    Par défaut post et pré incrémentation
    Quelle est la difference entre le post incrémentation et le pré incrémentation?
    et a quel moment l'utilser? Comment cela fonction?et merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    La différence, c'est que la "post" incrémentation ne retourne pas la même valeur que la pré-incrémentation:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void UneFonction(void)
    {
    	int i=5, j=5;
     
    	int a = i++;
    	int b = ++j;
     
    	/* Ici, i et j valent tous les deux 6.
    	   Par contre, a vaut 5 et b vaut 6. */
    }
    Naturellement, quand on met i++ ou ++i tout seul, on s'en moque puisqu'on n'utilise pas la valeur de retour.

    En C++, un moyen de de définir la post-incrémentation est dire qu'elle retourne une copie de l'ancienne valeur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre éprouvé
    Avatar de LinkinSelim
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Mars 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Mars 2006
    Messages : 365
    Points : 1 034
    Points
    1 034
    Par défaut
    je vais t'expliquer ca avec des exemple

    1.post-incrementation
    ---------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    j=10;
    i=j++; //post-incrementation
    donnera comme resultat
    i=10;
    j=11;
    parceque l'incrementation se fait aprés l'affectation (post)

    2.pré-incrementation
    --------------------
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    j=10;
    i=++j; //pré-incrementation
    donnera comme resultat
    i=11:
    j=11;
    parceque l'incrementation se fait avant l'affectation (pré)

    3.Melange des deux
    -------------------

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    j=10;
    k=11;
    i=(j++)+(++k);
    donnera comme resultat
    i=22;
    parce que l'incrementation de j se fait aprés l'affectation et
    l'incrementation de k se fait avant l'affectation
    j=11;
    k=12;

    on peut dire que ce code est equivalent au precedent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    j=10;
    k=11;
    k=k+1; //pré-incrementaiton de k
    i=j+k;
    j=j+1; //post-incrementation de j
    j'espere que ca va t'aider sinon jette un coup d'oeil a la faq http://cpp.developpez.com/faq/cpp/

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    Je rebondis un peu sur ce (très) vieux sujet... J'ai fait quelques recherches sur le sujet et je lis plusieurs sons de cloche.
    Pour ce qui est de quand c'est incrémenté ou pas, y'a pas de soucis, tout est clair. Ma question concerne plutôt la "performance". Y'a-t-il un réel intérêt à écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for (int i = 0; i < 42; ++i)
    { ... }
    plutôt que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for (int i = 0; i < 42; i++)
    { ... }
    Le résultat sera évidemment le même mais est-ce que celà change quelques chose pour le compilateur? Et si oui, est-ce vrai pour tous les types (par exemple sur des itérateurs)?

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    En théorie, le code sera le même pour un int, à moins d'avoir un compilateur débile.

    Pour un itérateur, je dirais qu'il faut un vachement bon optimiseur, et que c'est pratiquement mort si le code de l'opérateur ++ postfixe n'est pas connu (ce qui n'est jamais le cas pour un itérateur template).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par caradhras Voir le message
    Le résultat sera évidemment le même mais est-ce que celà change quelques chose pour le compilateur? Et si oui, est-ce vrai pour tous les types (par exemple sur des itérateurs)?
    Pour tous les types natifs (les int dans ton cas), je doute qu'il y ait un compilateur qui produise un code inefficace dans les cas de post incrémentation. Pareil pour les pointeurs... (Medinoc, je ne crois pas que cela pose un problème sur les itérateurs sur types de base ou POD, parce que ce sont, en principe, l'équivalent strict de pointeurs. En fait, si le problème existait, ce serait, pour moi, au moins, une raison de préférer les pointeurs aux itérateurs, car cela reviendrait à dire que le compilateur n'arrive pas à optimiser du code contenant des itérateurs)

    Maintenant, sur des types utilisateur, ou n'importe quoi d'un peu compliqué, rien n'est garanti. En gros, si ton type est assez simple, le compilateur arrivera à voir que les variables qu'il sauvegarde ne servent à rien, et les éliminera à l'optimisation, s'il est plus compliqué, ca peut ne pas marcher.

    Maintenant une boucle comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(TMonType t=montypedep;t!=montypefin;t++)
    serait probablement de toutes façons atrocement inefficace. Donc je ne crois pas qu'il y ait un risque à toujours utiliser la post incrémentation dans les boucles...

    En résumé, je pense que c'est un faux problème.

    Francois
    Dernière modification par Invité ; 17/07/2009 à 14h46.

  7. #7
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    Ok! Merci bien pour vos réponses.

    En fait, il m'avait sembler entendre (tout ça reste très vague ) qu'à la compilation et/ou l'execution, la pré-incrémenation avait des avantages en terme de performance...
    Encore une fois, c'est juste la lecture de ce vieux post qui m'a mis le doute et je voulais juste avoir l'avis d'autres.
    C'est probablement une autre (très) fausse idée reçue!

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par caradhras Voir le message
    En fait, il m'avait sembler entendre (tout ça reste très vague ) qu'à la compilation et/ou l'execution, la pré-incrémenation avait des avantages en terme de performance...
    Encore une fois, c'est juste la lecture de ce vieux post qui m'a mis le doute et je voulais juste avoir l'avis d'autres.
    C'est probablement une autre (très) fausse idée reçue!
    Non ce n'est pas nécessairement une fausse idée, mais comme expliqué par Médinoc et fcharton, c'est à voir au cas par cas.

    Pour les types primitifs (int, size_t, etc.) et pour les pointeurs sur un compilateur décent, il n'y aura pas d'impact.
    Par contre sur des types plus complexe, il va y avoir création d'un objet temporaire lors de la post-incrémetation qui va forcément couté à l'exécution donc il y aura bien un impact et il faut donc préféré la pré-incrémentation.
    Sur des compilateurs très ancien, particulièrement peu efficace voire sur certains compilateurs avec 0 optimisation il est possible d'observer également le phénomène sur des types primitifs.

    Tout ça en partant du principe que les surcharges des opérateurs de pré-incrémentation et de post-incrémentation ont bien le sens habituel.

  9. #9
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    Ok, merci bien!

    Donc, à la limite, dans le doute, il vaut peut-être mieux prendre l'habitude de la pré-incrémentation (là où il n'y a pas d'affectation j'entend)...

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par caradhras Voir le message
    Donc, à la limite, dans le doute, il vaut peut-être mieux prendre l'habitude de la pré-incrémentation (là où il n'y a pas d'affectation j'entend)...
    Oui, dans le doute, il vaut toujours mieux faire ++p que p++. L'habitude d'écrire i++ dans les boucles est cependant très répandue (personnellement, je n'arrive pas à m'en défaire), il est donc utile de savoir que ce n'est pas grave...

    Pour les types utilisateurs, comme le disait gl, il faut se méfier des opérateurs, qui peuvent avoir été redéfinis... Personnellement, dans le doute, je fais p+=1 ou même p=p+1.

    Francois

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Grain de sel : théoriquement, la pré-incrémentation est plus efficace car il n'est pas nécessaire de conserver l'ancienne valeur (=une copie, même si c'est de registre à registre) pour effectuer l'action... La post-incrémentation, elle, requiert cette copie, donc coûte plus en temps CPU.

    Ceci étant dit :
    • La plupart des compilateurs C/C++ transforment automatiquement un "i++" en "++i" lorsque la valeur de retour n'est pas utilisée, y compris en debug (sans optimisations donc). Si des optimisations sont requises pour activer ce point, c'est toujours actif dès le premier niveau d'optimisation.
    • Seuls de très vieux compilateurs sont impactés par ce phénomène : si tu n'utilises que des compilateurs récents, ce sera transparent dans l'écriture classique d'une boucle.
    • Il est bien entendu évident que cette transformation automatique n'est jamais appliquée lorsque la valeur de retour est utilisée...
    • Le problème de redéfinition des opérateurs n'existant qu'en C++, il n'est pas utile de se préoccuper de ce point particulier si tu ne travailles qu'en C. En C++, c'est autre chose, il faut savoir exactement sur quoi on travaille pour ne pas faire d'erreurs.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  12. #12
    Membre à l'essai
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2017
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Grain de sel : théoriquement, la pré-incrémentation est plus efficace car il n'est pas nécessaire de conserver l'ancienne valeur (=une copie, même si c'est de registre à registre) pour effectuer l'action... La post-incrémentation, elle, requiert cette copie, donc coûte plus en temps CPU.

    Ceci étant dit :
    • La plupart des compilateurs C/C++ transforment automatiquement un "i++" en "++i" lorsque la valeur de retour n'est pas utilisée, y compris en debug (sans optimisations donc). Si des optimisations sont requises pour activer ce point, c'est toujours actif dès le premier niveau d'optimisation.
    • Seuls de très vieux compilateurs sont impactés par ce phénomène : si tu n'utilises que des compilateurs récents, ce sera transparent dans l'écriture classique d'une boucle.
    • Il est bien entendu évident que cette transformation automatique n'est jamais appliquée lorsque la valeur de retour est utilisée...
    • Le problème de redéfinition des opérateurs n'existant qu'en C++, il n'est pas utile de se préoccuper de ce point particulier si tu ne travailles qu'en C. En C++, c'est autre chose, il faut savoir exactement sur quoi on travaille pour ne pas faire d'erreurs.
    C'est vieux... je sais ...
    Je m'ennuyais et un collègue me prenait la tête là-dessus, j'ai suivi la discussion ici, et ouf en lisant le dernier, enfin quelqu'un qui connaît LA réponse ... je cherchais à prouver à mon collègue que j'avais raison (faut toujours gonfler les muscles pour se faire entendre).

  13. #13
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est un peu plus compliqué que ça : prises au sein d'un programme C, ces constructions du langage n'ont pas d'équivalent direct en instructions machine. « Transformer i++ en ++i » n'a pas de sens. Le compilateur génèrera le code le plus rapide avec le comportement escompté en fonction du contexte.

    Ce dont tu peux convaincre ton collègue en revanche, c'est que le code généré est le même en comparant les sorties assembleur (-S pour GCC) de deux programmes utilisant respectivement l'une et l'autre des expressions.

  14. #14
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 565
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 565
    Points : 7 642
    Points
    7 642
    Par défaut
    Citation Envoyé par Juniper62 Voir le message
    La plupart des compilateurs C/C++ transforment automatiquement un "i++" en "++i" lorsque la valeur de retour n'est pas utilisée
    Attention, ça n'est vrai que si i est un scalaire où il est évident que l'on souhaite incrémenter la valeur. S'il s'agit d'un type utilisateur ou d'un itérateur. On a dû définir deux fonctions différentes, le compilateur va donc utiliser la bonne (il n'a pas à prendre d'initiative). Et il est possible qu'après optimisation cela revienne au même, mais pas toujours.
    C'est pourquoi en C++, il vaut mieux s'habituer à utiliser la pré-incrémentation si on ne s'intéresse pas à la valeur de retour.
    En C, on peut écrire n'importe laquelle car l'opération n'existe que sur des scalaires.

  15. #15
    Membre à l'essai
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2017
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2017
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Attention, ça n'est vrai que si i est un scalaire où il est évident que l'on souhaite incrémenter la valeur. S'il s'agit d'un type utilisateur ou d'un itérateur. On a dû définir deux fonctions différentes, le compilateur va donc utiliser la bonne (il n'a pas à prendre d'initiative). Et il est possible qu'après optimisation cela revienne au même, mais pas toujours.
    C'est pourquoi en C++, il vaut mieux s'habituer à utiliser la pré-incrémentation si on ne s'intéresse pas à la valeur de retour.
    En C, on peut écrire n'importe laquelle car l'opération n'existe que sur des scalaires.
    oui c'est justement sur ce point que j'insistais, qu'il fallait que ça devienne presque un automatisme... la + part du temps, les codeurs peu expérimentés n'utilisent pas la valeur de retour de la post-incrémentation.
    ceci dit, il est vrai que je parlais du C++ ... j'aurais dû préciser

Discussions similaires

  1. Réponses: 3
    Dernier message: 13/12/2011, 10h44
  2. Opérateur pré ou post incrémentation
    Par cijad dans le forum Langage
    Réponses: 5
    Dernier message: 17/11/2011, 07h29
  3. problème avec la post-incrémentation
    Par peperaleur dans le forum Débuter
    Réponses: 6
    Dernier message: 30/01/2008, 20h54
  4. boucle while et post incrémentation
    Par tut dans le forum C++
    Réponses: 7
    Dernier message: 10/12/2004, 17h24
  5. Post incrémentation?
    Par Defrag dans le forum C
    Réponses: 4
    Dernier message: 08/10/2002, 10h36

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