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 :

[D�butant] utilisation du & salvatrice ou pas...


Sujet :

C++

  1. #1
    Membre habitu�
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    9
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 9
    Par d�faut [D�butant] utilisation du & salvatrice ou pas...
    Voila dans certaines de mes procedures, j'obtenais des resultats faux, alors que tous les calculs y marchaient bien, et que le r�sultat juste avant la derniere accolade etait correcte...

    En gros dans la procedure tout marchait, mais impossible de sortir les resultat de la procedure... (ce sont des procedure void que j'ecris en faisant :

    void procedure(r�sultat1,..resultatN, variable1,...variableN)...

    Je me suis apercu qu'en mettant un & devanat r�sultatI �a marchait bien mieux... mais apr�s �a ne marche pas pour tous les types, car si resultatI est un tableau par exemple, il me dit que c'est illegal de faire un tableau de references...

    Existe-t-il donc un �quivalent du "&" pour les tableaux ?


    Merci

  2. #2
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    Je me suis apercu qu'en mettant un & devanat r�sultatI �a marchait bien mieux... mais apr�s �a ne marche pas pour tous les types, car si resultatI est un tableau par exemple, il me dit que c'est illegal de faire un tableau de references...
    Existe-t-il donc un �quivalent du "&" pour les tableaux ?
    Ca marchait mieux parce que, dans ce cas, tes variables r�sultatI d�signaient les objets que tu avais pass�s en argument. Il te fait r�fl�chir � �a.
    Pour les tableaux, c'est diff�rent : Si tu passes un tableau en argument, la fonction va manipuler les objets d'origine du tableau, donc il suffit dans ce cas de passer tout simplement le tableau.

  3. #3
    Membre �m�rite Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    D�tails du profil
    Informations personnelles :
    �ge : 53

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Par d�faut
    Bonjour,
    Le mode de passage par d�faut des arguments n'est pas le passage par valeur.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    int Echange(int a, int b) {
     
    int temp = b;
     
    b = a;
    a = temp;
     
    }
    Tu verras si tu testes, que a et b sont inchang�.

    Car dans ce mode de passage des arguments, le compilateur g�n�re de copies des arguments, puis en sortie de fonction recopie les valeurs initiales des arguments. Les arguments ne sont donc pas modifi�s.

    Le symbole & permet un passage par valeur, qui �vite la solution C des pointeurs.

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    int Echange(int& a, int& b) {
     
    int temp = b;
     
    b = a;
    a = temp;
    }

    Ici, int& a passe en argument l'adresse de la variable pass�e en premier argument.

    Pour mieux comprendre, le code �quivalent en C c'est ceci:

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    int Echange(int* a, int* b) {
     
    int temp = *b;
     
    *b = *a;
    *a = temp;
    }

  4. #4
    jmv
    jmv est d�connect�
    Membre chevronn� Avatar de jmv
    Profil pro
    Enseignant
    Inscrit en
    Mai 2004
    Messages
    395
    D�tails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activit� : Enseignant

    Informations forums :
    Inscription : Mai 2004
    Messages : 395
    Par d�faut
    en C++, les arguments sont pass�s par valeurs, si une fonction modifie un de ses arguments, cette modification se fait sur la valeur de l'argument et non sur la variable d'origine. Exemple, dans le code suivant, n n'est pas modifi�.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f(int arg)
    {
        arg = 0;
    }
     
    int main()
    {
        int n = 1;
        f(n);
        // ici n vaut toujours 1
    }
    Pour qu'une fonction puisse modifier une variable qui lui est externe, elle a besoin de l'adresse de cette variable, et non de sa valeur. Il y a 2 solutions :
    1� avec pointeur
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f(int *arg)
    {
        *arg = 0;
    }
     
    int main()
    {
        int n = 1;
        f(&n);
        // ici n vaut 0
    }
    2� avec r�f�rence
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f(int &arg)
    {
        arg = 0;
    }
     
    int main()
    {
        int n = 1;
        f(n);
        // ici n vaut 0
    }
    Pour les tableaux, c'est diff�rents, il sont toujours pass�s par adresse, une fonction peut donc modifier les �l�ments d'un tableau
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f(int arg[]) // ou void f(int *arg)
    {
        arg[0] = 0;
    }
     
    int main()
    {
        int n[] = {1,2,3,4};
        f(n);
        // ici n[0] vaut 0
    }

  5. #5
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    Caine dixit :
    Le mode de passage par d�faut des arguments n'est pas le passage par valeur.
    Il y a deux m�thodes : le passage par valeur (comme en C) et le passage par r�f�rence
    Car dans ce mode de passage des arguments, le compilateur g�n�re de copies des arguments,
    Oui, Le compilateur cr�e des variables locales initialis�es avec la valeur des arguments
    puis en sortie de fonction recopie les valeurs initiales des arguments
    . En sortie de fonction, il n'y a pas de recopie des valeurs initiales des arguments. Il y a destruction des variables locales (y compris les param�tres). Toute modification de la valeur des param�tres modifie les variables locales et donc laisse inchang�es les variables pass�es en argument.

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    180
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 180
    Par d�faut
    Bon, clairement, les arguments de tes fonctions (ou proc�dures) sont g�r�s diff�rement selon qu'ils sont ou non des tableaux!

    Imagine que c'est une barrette de RAM! Ta fonction � deux argument: x et y.

    Tu appelle cette fonction dans le main et tu lui donne en argument a et b

    Il y'a quatres variables et non pas deux dans la m�moire!

    |----|--|----|--|----|--|----|
    --a-------b-------x------y

    Quand tu appelles la fonction x prend la valeur de a et y celle de b!

    Ensuite la fonction bosse sur les variables x et y sans se pr�occuper de a et de b!

    Mais si tu met un '&' devant le type, sache que c'est correct du point de vue de la syntaxe mais n'en met pas syst�matiquement! R�fl�chi bien si tu as vraiment besoin de travailler directement sur les variables!
    Donc si tu met un '&' devant le type le programme ne cr�e pas d'emplacement m�moire x et y mais travaille directment sur a et b.
    Autrement dit si tu �cris x=3 dans ta fonction! apr�s appel de cette fonction dans le main a aura pour valeur 3!

    Pour les tableaux c'est un peu diff�rent! Tu n'as pas besoin de mettre le '&' devant le type du tableau, la fonction traville directment sur le tableau pass� en argument donc pas besoin de '&'!!

    En esp�rant t'avoir aid�!

    Spartan03

  7. #7
    Membre Expert
    Avatar de xavlours
    Inscrit en
    F�vrier 2004
    Messages
    1 832
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2004
    Messages : 1 832
    Par d�faut
    Attention, le passage de tableau par r�f�rence (avec un &) peut etre n�cessaire si tu le r�alloues : tu le d�places en m�moire et tu changes la variable du pointeur. Par exemple :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    void putToThree(int* i) {
      i = new int(3);
    }
    Ce code ne changera pas le pointeur (ou le tableau) que tu as pass� en param�tre.

    2e truc : j'ai d�j� eu des probl�mes de copie du r�sultat : parfois il faut mettre un & devant le type retourn� (mais bon l� c'est des cas assez tordus).
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'�trenne." B.V.
    Non au langage SMS ! Je ne r�pondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  8. #8
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    xavlours :
    Attention, le passage de tableau par r�f�rence (avec un &) peut etre n�cessaire si tu le r�alloues : tu le d�places en m�moire et tu changes la variable du pointeur. Par exemple :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    void putToThree(int* i) { 
      i = new int(3); 
    }
    Je ne comprend pas : ceci n'est pas un passage par r�f�rence. De plus, le param�tre i est �cras� et devrait �tre une variable locale. Comme la fonction ne renvoie pas i, l'allocation dynamique part dans la nature. Enfin new int(3) n'alloue pas un tableau ( new int[3] ) mais un int initialis� avec la valeur 3
    2e truc : j'ai d�j� eu des probl�mes de copie du r�sultat : parfois il faut mettre un & devant le type retourn� (mais bon l� c'est des cas assez tordus).
    C'est surtout lorsque la fonction doit retourner un objet (ce qui est une des bonnes raisons des r�f�rences d'exister)

  9. #9
    Membre � l'essai
    Inscrit en
    Ao�t 2004
    Messages
    5
    D�tails du profil
    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5
    Par d�faut
    le & en C++ permet de cr�er un alias dans le code. Il est tout a fait l�gal d'�crire :
    a et b sont alors exactement le meme objet. Par contre, une fois une r�f�rence affect�e, tu ne peux pas la changer et une r�ference ne peux pas etre initialis�e par d�faut :
    L'avantage aussi de passer une r�f�rence (ou un pointeur, l'id�e �tant tres similaire) est d'�viter un appel au constructeur de copie de l'object que tu passes en paramettre. Prends cette structure en exemple :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct Dummy
    {
       const Dummy & Dummy(const Dummy &other )
       { /* realise la copie */
       }
     
       int[1000] m_Array;
    };
    et la fonction suivante :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int NonNul( const Dummy dummy )
    {
       int nbFound(0);
       for(int i(0); i != 1000; ++i)
       {
          if(dummy.m_Array[i] != 0) ++nbFound;
       }
       return nbFound;
    }
    si tu fais un appel a cette fonction, elle va devoir r�aliser une copie complete de l'objet dummy donc du tableau de 1000 int dedans, soit pour un int � 4 byte, 4 kbyte, ce qui prends de la place et du temps.
    en modifiant simplement la d�finition de la fonction � :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    int NonNul( const Dummy &dummy )
    {
       // meme code ...
    }
    tu ne fais qu'une r�f�rence � l'objet dummy, ce qui prends la taille d'un pointeur si je me rappelle bien = normalement 4 byte... Le gain de temps et d'espace m�moire est non n�gligeable.

    en gros tu devrais passer tes variables par r�f�rence dans les cas suivant (c'est de tete et au boulot donc y'aura peut etre des oublis):
    - le type n'est pas un scalaire de base.
    - le type n'a pas de constructeur de copie.
    - tu veux modifier l'objet sans devoir passer un pointeur � cet objet (car le d�f�rencement prends plus de temps).

    ce sont les trois principales situations mais il y en a surement d'autre

  10. #10
    Expert confirm�
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par d�faut
    Ca$ul :
    en gros tu devrais passer tes variables par r�f�rence dans les cas suivant ...
    - tu veux modifier l'objet sans devoir passer un pointeur � cet objet (car le d�f�rencement prends plus de temps).
    Le temps d'ex�cution ne doit �tre diff�rent, car la r�f�rence va �tre implant�e conmme un pointeur. Ce qui change, c'est la syntaxe d'acc�s � l'int�rieur de la fonction et �vite l'�criture explicite des *...
    Personnellement, je pr�f�re souvent pour ce type d'application le passage d'un pointeur car la syntaxe utilis�e lors de l'appel montre que la fonction peut modifier l'argument. Avec les r�f�rences, cela ne se voit pas imm�diatement
    Une autre raison, de passer une r�f�rence est lorsque la fonction doit renvoyer une r�f�rence

  11. #11
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    En fait, il y a deux �coles: les uns pr�f�rent les pointeurs pour la raison cit�e par diogene, et viennent souvent du C (comme moi). Pour moi, les r�f�rences ne servent que lorsque les pointeurs ne marchent pas (redef. d'op�rateurs par exemple)

    Les autres pr�f�rent les r�f�rences, qui ont l'avantage d'�tre obligatoires: On ne peut pas passer de r�f�rence NULL � une fonction, ce qui �vite d'avoir � tester dans la fonction si l'objet pass� est NULL ou non. Pour eux, les pointeurs sont � utiliser uniquement l� o� on ne peut utiliser de r�f�rence (arguments optionnels, par exemple).
    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.

  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
    Pour les autres, dont je fais parti, documentation et utilisation syst�matique des const font que les pointeurs seuls sont rares.

    Un param�tre entrant est forc�ment r�f�rence-constante, pointeur-constant, ou pris-par-valeur-et-donc-copi�. L'int�r�t du pointeur c'est pour l'optionel ou pour quand je d�sire expliciter la dur�e de vie de l'objet. Mais l�, je peux le prendre juste pointeur car il s'agit de transf�rer sa responsabilit� � un autre objet.

    Un param�tre en "out" ou "in-out" sera document� comme tel. Et le nom de la fonction fera en sorte de bien signaler le sens de passage.

    A noter de plus qui si il y a une s�mantique de valeur l'utilisation de pointeurs me choque g�n�ralement et donc j'ai tendance � l'�viter.

    Voil� d'autres points rapides donn�es tard le soir. Il y avait eu un autre fil plus abouti sur le sujet dans le pass�.
    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 habitu�
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    9
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 9
    Par d�faut
    Ouh la merci beaucoup je ne m'attendais pas � tant d'explications, c'est g�nial !!!

    Bon c'est pas dit que j'assimile tout, mais �a me sera de toute fa�on tr�s utile !

    Encore merci !

Discussions similaires

  1. [MYSQL] [d�butant] utiliser replace avec mysql.pas
    Par alex01pernot dans le forum Bases de donn�es
    R�ponses: 2
    Dernier message: 30/08/2006, 21h23
  2. [D�butant] Utiliser un SGBD ou pas (VC++) ?
    Par skual dans le forum D�buter
    R�ponses: 7
    Dernier message: 30/01/2006, 14h08
  3. [D�butant] Utilisation du mot cl� ASSERT
    Par analysiz dans le forum Eclipse Java
    R�ponses: 2
    Dernier message: 29/07/2004, 11h43
  4. [CR8.5] Oblig� d'utiliser un sous-rapport ou pas ?
    Par liberio dans le forum SAP Crystal Reports
    R�ponses: 2
    Dernier message: 09/06/2004, 18h10
  5. [D�butant] Utilisation de FOP - Register Fonts with FOP
    Par Johnbob dans le forum XML/XSL et SOAP
    R�ponses: 4
    Dernier message: 31/01/2004, 00h27

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