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 :

mon_booleen ne fonctionne pas


Sujet :

C

  1. #21
    Invité
    Invité(e)
    Par défaut
    est-ce que le code que j'ai proposé le post avant est valable tout de même (même si...) ?

  2. #22
    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
    Tu veux dire le code du message #18? Ben non, il ne marche pas: Les a et b de Echanger() sont des paramètres, des variables locales, donc des copies des a et b de main().

    Seules les copies sont échangées, donc les a et b de main() conservent leurs valeurs respectives.
    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. #23
    Invité
    Invité(e)
    Par défaut
    pourtant j'aurais juré qu'avec des variables normales ça marcherait

    jamais je n'aurais pensé que ça faisait une sorte de copie si vous n'étiez pas là

    ça me perturbe vachement cette histoire : je n'ai pas compris lors du passage des paramètres : quand vous dites "copie" ça veut dire quoi au juste ?

  4. #24
    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
    Ça veut dire que:
    • Avant l'appel, tu as une variable n'importe où en mémoire: Cela peut être une variable globale, une variable allouée quelque part dans le tas (malloc() etc.), ou une variable locale.
    • Lors de l'appel, la variable est copiée quelque part d'autre, dépendant de l'implémentation: Sur un processeur x86, c'est sur la pile: On décale le pointeur de pile avec la taille de la variable, et on écrit à cet endroit, tous les octets de la variable (dans des langages comme C++, c'est un poil plus compliqué).
    • La fonction appelée travaille sur cette copie comme si c'était une de ses variables locales.
    • Lorsque la fonction retourne, la copie est détruite. Elle n'est pas recopiée dans l'autre sens vers l'original, elle est simplement oubliée.


    Un exemple pour montrer que c'est une copie, c'est que les deux variables possèdent des addresses différentes:
    Code C : 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
    #include <stdio.h>
     
    void UneFonction(int param)
    {
    	int* pParam = &param;
    	printf("Adresse de param: %p\n", (void*)pParam);
    }
     
    int main(void)
    {
    	int varLocale;
    	int *pVarLocale = &varLocale;
    	printf("Adresse de varLocale: %p\n", (void*)pVarLocale);
    	UneFonction(varLocale);
    	return 0;
    }
    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.

  5. #25
    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 fait, sur une machine x86, tu peux considérer la mémoire comme un tableau, et les pointeurs comme des indexes dans ce tableau. Voici un équivalent simple:
    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
    #include <stdio.h>
    #include <stddef.h>
     
    int g_memoire[10];
     
    void Echange(size_t iGauche, size_t iDroite)
    {
    	/*Note que le temporaire lui-même n'est pas un pointeur.
    	  C'est un int, vu qu'on échange les int pointés.*/
    	int temporaire = g_memoire[iGauche];
    	g_memoire[iGauche] = g_memoire[iDroite];
    	g_memoire[iDroite] = temporaire;
    }
     
    int main(void)
    {
    	size_t ia, ib;
     
    	g_memoire[0] = 1;
    	g_memoire[1] = 42;
    	ia = 0;
    	ib = 1;
     
    	printf("Avant : a=%d, b=%d, ia=%ld, ib=%ld\n", g_memoire[0], g_memoire[1], (long)ia, (long)ib);
    	Echange(ia, ib);
    	printf("Apres : a=%d, b=%d, ia=%ld, ib=%ld\n", g_memoire[0], g_memoire[1], (long)ia, (long)ib);
    	return 0;
    }
    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. #26
    Invité
    Invité(e)
    Par défaut
    bon déjà j'ai compris qu'un pointeur est une variable vide lorsqu'elle est déclarée et qui pointe sur une autre variable lors qu'on l'initialise

    en vérité on assigne jamais un nombre à un point mais on lui indique une autre variable de même nature (ex ici un int)

    ex : on n'écrit pas mais alors qu'avec une variable normale on peut écrire : c'est ça en gros non ?

  7. #27
    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
    Oui, à cela près qu'une variable n'est jamais "vide".
    Par contre, elle peut être non-initialisée (la lire entraine un comportement indéfini) ou nulle.

    Un pointeur nul est un pointeur initialisé à zéro. En C, on utilise la macro NULL, qui est traditionnellement définie en tant que ((void*)0) (mais ça peut être, à la place, un truc plus spécifique au compilateur).

    Donc, typiquement, à part quand on fait de la programmation à très bas niveau (pour de l'Embarqué par exemple), on ne met que 4 choses différentes dans un pointeur:
    • NULL pour dire qu'il ne pointe sur rien du tout.
    • L'adresse d'une variable existante, ou d'un champ de structure, ou même d'une fonction.
    • La valeur retournée par une fonction qui retourne un pointeur (peut être une fonction à toi, ou une fonction comme malloc()).
    • Le résultat d'un calcul sur des pointeurs: si p pointe sur le premier élément d'un tableau, alors p+1 pointe sur le second élément.

    Il est important de ne jamais laisser un pointeur non-initialisé! S'il ne pointe sur rien du tout, l'initialiser à NULL. Pourquoi? Parce que le code peut tester si un pointeur est nul, alors qu'on ne peut pas tester si un pointeur est initialisé ou non.
    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.

  8. #28
    Invité
    Invité(e)
    Par défaut
    ayé je pense avoir compris le truc (je pense) dites-moi si je me trompe

    après avoir lu le tuto de cgi sur les pointeurs je pense avoir compris que :

    => un pointeur pointe vers 1 seule et unique adresse mémoire lorsqu'on l'initialise
    avec &x

    => de ce pointeur on peut en tirer la valeur pointée à l'adresse mémoire
    correspondante avec *px

    => pour reprendre l'exemple que vous m'avez donné avec la fonction
    echange() : comme vous m'avez dit lors du passage des paramètres ça fait
    une copie : ça copie la valeur à une autre adresse mémoire : n'importe
    laquelle : on se retrouve avec la meme valeur mais à une autre adresse mémoire

    => la valeur copiée n'est active qu'à l'intérieur de la fonction et meurt à la fin

    => alors que les pointeurs ils disent tu vas à cette unique adresse mémoire
    et c'est pour ça que ça marche

    en fait je ne m'y connais pas en progra mais ça a l'air d'être un truc super puissant

  9. #29
    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
    C'est exactement ça!
    C'est en effet très puissant et indispensable à bas niveau.

    Dans un processeur x86, plusieurs registres sont tout le temps des pointeurs!
    • IP - Instruction Pointer (EIP en 32 bits): Pointeur d'instruction: Il dit quelle partie du programme le processeur exécute
    • SP - Stack Pointer (ESP en 32 bits): Pointeur de pile: Il indique le sommet de la pile; il est utilisé et modifié à chaque fois qu'on empile ou dépile un truc (comme justement, un paramètre de fonction).
    • BP - Base Pointer (EBP en 32 bits): pointe à dans la pile, à l'endroit des variables locales et des paramètres: En fait, quand tu accèdes à une variable locale, vu du proc elle se trouve à EBP+(quelque chose).
    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.

  10. #30
    Invité
    Invité(e)
    Par défaut
    Bonjour tout le monde,

    Je sais que je dis merci 10 ans après mais merci :

    => pour vos précisions apportées sur les pointeurs qui m'ont permis de mieux comprendre à quoi ils servent.

    => pour la mise à disposition des tutos qui m'ont été utiles également

    Tout cela me sera d'ailleurs utiles par la suite aussi.

    Merci d'avoir pris un peu de votre temps pour m'expliquer tout cela.
    Non vraiment.

    A bientôt.

    Cordialement,
    Gizmo.

  11. #31
    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
    De rien!

    Bon courage pour la suite.
    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. #32
    Invité
    Invité(e)
    Par défaut
    Bonsoir à toutes et à tous,

    Je reviens avec une question concernant le code de Medinoc sur les pointeurs :
    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
    #include <stdio.h>
     
    void Echange(int *pGauche, int *pDroite)
    {
    	/*Note que le temporaire lui-même n'est pas un pointeur.
    	  C'est un int, vu qu'on échange les int pointés.*/
    	int temporaire = *pGauche;
    	*pGauche = *pDroite;
    	*pDroite = temporaire;
    }
     
    int main(void)
    {
    	int a = 1;
    	int b = 42;
    	int *pa;
    	int *pb;
     
    	pa = &a; /*On initialise pa avec l'adresse de a.
    	           pa pointe maintenant sur a.*/
    	pb = &b; /*On initialise pb avec l'adresse de b.
    	           pb pointe maintenant sur b.*/
     
    	/*Note: la norme exige de caster un pointeur en void* avant de le passer à printf.
    	  C'est à cause de certaines machines où les pointeurs n'ont pas tous la même taille.*/
    	printf("Avant : a=%d, b=%d, pa=%p, pb=%p\n", a, b, (void*)pa, (void*)pb);
    	Echange(pa, pb);
    	printf("Après : a=%d, b=%d, pa=%p, pb=%p\n", a, b, (void*)pa, (void*)pb);
    	return 0;
    }
    C'est la fonction Echange qui m'interpelle ici : au moment de l'appel de la fonction dans la partie main : il est marqué Comme les pointeurs sont initialisés aux adresses de a et b, je ne comprend pas la chose suivante : lors de la déclaration de la fonction Echange, les paramètres sont des valeurs pointées.
    Par quel miracle des adresses de variable sont-elles transformées en entier ?
    Lors de l'appel de la fonction dans le main, pourquoi ne met-on pas : ?
    Car enfin ce sont les entiers a et b à échanger qui nous intéresse, et non pas d'échanger les adresses des variables ?

    Voyez-vous ce que je veux dire, où je veux en venir ?

  13. #33
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Comme les pointeurs sont initialisés aux adresses de a et b, je ne comprend pas la chose suivante : lors de la déclaration de la fonction Echange, les paramètres sont des valeurs pointées.
    Non, les paramètres sont des pointeurs.

    Par quel miracle des adresses de variable sont-elles transformées en entier ?
    Elles ne sont pas transformées en entier. A partir des adresses pGauche ou pDroite, la fonction retrouve la valeur des entiers situés à ces adresses : *pGauche et *pDroite


    Si on veut échanger le contenu de deux variables, il faut savoir elles sont. Connaitre leur valeur de suffit pas.
    Si on écrit :
    on donne en argument la valeur des variables a et b. Comment la fonction va t-elle faire pour prendre par exemple la valeur de a (pas de problème, elle la connait puisque c'est le premier argument) pour la mettre DANS la variable b (mais elle ne sait pas où est b) ?
    C'est pourquoi on passe les adresses. La fonction peut prendre la valeur de l'une (elle peut le faire puisqu'elle sait où elle est) pour la mettre dans l'autre variable (elle peut le faire puisqu'elle sait où elle est).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  14. #34
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    J'ai compris le système des pointeurs.
    Mon problème vient de cet exemple en particulier.
    Ce qui me "taquine" c'est que lors de sa déclaration, la fonction Echange attend des paramètres entiers int avec pour variable des pointeurs *pgauche,...
    Donc quand on lui passe les paramètres on devrait mettre les étoiles pour dire que c'est bien les valeurs qu'on veut échanger et pas les adresses... Mais si on le fait alors on n'a pas résolu le problème car on fait une copie et l'on revient à l'exemple avec de simples variables et ça ne marche pas.

    Grosso modo je n'ai pas saisi ce qui se passe au moment de l'appel de la fonction après l'avoir déclarée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void Echange(int *pGauche, int *pDroite)
    {
    	/*Note que le temporaire lui-même n'est pas un pointeur.
    	  C'est un int, vu qu'on échange les int pointés.*/
    	int temporaire = *pGauche;
    	*pGauche = *pDroite;
    	*pDroite = temporaire;
    }
    et lors de l'appel :avec pa et pb initialisée respectivement à &a et &b les adresses de a et b.
    Donc on lui fait passer en paramètres : ce que je ne comprend pas en regardant la fonction déclarée c'est : comment la fonction traite-t-elle les adresses pour qu'elle deviennent des pointeurs ?

    Pour moi pa est différent de *pGauche : l'un est une adresse mémoire et l'autre est un pointeur : je n'arrive pas à faire le lien entre les deux.

    Autrement dit quand on passe à la fonction l'adresse &a, pour moi *pGauche vaut &a... Vous saisissez ?

    Ca n'est pas facile de trouver les mots pour bien faire comprendre mon problème, aussi n'hésitez pas à dire si vous ne me comprenez pas.

    Merci à vous.

    Cordialement,
    Gizmo.
    Dernière modification par Invité ; 07/09/2010 à 03h12.

  15. #35
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gizmo27 Voir le message
    Donc on lui fait passer en paramètres : ce que je ne comprend pas en regardant la fonction déclarée c'est : comment la fonction traite-t-elle les adresses pour qu'elle deviennent des pointeurs ?
    Parce qu'une adresse, c'est un pointeur

    Démonstration
    int toto=123;

    La variable "toto" se trouve à l'adresse (par exemple) 0x0010 => &toto=0x0010

    Peut-on stocker 0x0010 dans une variable "i" ? Réponse oui
    int i=0x0010

    Est-ce que cela nous aide pour trouver 123 ?
    Réponse non. On pourrait demander "*i" mais le compilo, s'il connait "i", ne connait pas "*i". Il ne sait pas ce qu'il faut récupérer à la zone mémoire d'adresse 0x010 (faut-il récupérer 1, 2, 4, 8 cases ???)

    Donc bien qu'on puisse écrire i=0x0010, on peut pas aller plus loin et on est bloqué.

    Pour s'en sortir, il faut indiquer non seulement le type qui reçoit 0x0010, mais aussi le type de l'élément situé à l'adresse 0x0010. Or à cet endroit là, il y a un int.
    Donc on écrit int *pt=0x0010 ce qui signifie
    - pt est de type "int étoile" ou "pointeur sur int"
    - *pt est de type "int"
    - pt (et non "étoile pt" !!!) reçoit la valeur 0x0010
    Comme 0x0010=&toto, on peut écrire plus simplement int *pt=&toto

    Ensuite, si on va taper dans "*pt"; le compilo connaissant son type "int" saura récupérer les 4 octets qui s'y trouvent (0x0010; 0x0011; 0x012 et 0x0013) et le transformer en nombre => 123
    Idem si on écrit dans "*pt". Le compilo ira écrire dans les cases 0x0010...0x0013

    Donc 0x0010 est une adresse. C'est l'adresse de toto. Mais quel est donc son type ???
    Ben on peut faire l'analogue suivante
    toto est de type "int" et vaut 123
    *(&toto) (ce qu'il y a à l'adresse &toto ou 0x0010) est toujours de type int et vaut 123
    &toto est de type int... étoile (l'étoile qui a disparu du coté gauche est alors passée du coté droit car elle n'a pas le droit de disparaitre de la phrase)

    Donc &toto est bien un pointeur sur int !!!

    Citation Envoyé par gizmo27 Voir le message
    Pour moi pa est différent de *pGauche : l'un est une adresse mémoire et l'autre est un pointeur : je n'arrive pas à faire le lien entre les deux.
    pa vaut &a. On peut imaginer qu'il vaut 0x0010.
    Ensuite on passe pa (0x0010) en paramète à la fonction. Cette valeur 0x0010 sera stockée dans "pGauche" (et non "étoile pGauche" !!! C'est là qu'il faut faire la distinction !!!).
    Donc pGauche contiendra 0x0010. En allant taper dans "*pGauche" (qui est de type "int"), ça ira taper dans "ce qu'il y a à l'adresse 0x0010" et les 3 suivantes ; soit la zone mémoire connue aussi sous le nom de "a".
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #36
    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
    Ce qui me "taquine" c'est que lors de sa déclaration, la fonction Echange attend des paramètres entiers int
    No, elle attend des paramètres pointeurs sur entier de type int*.
    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.

  17. #37
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Mais si on le fait alors on n'a pas résolu le problème car on fait une copie
    C'est juste. En C, les arguments sont toujours passés par copie.
    Pour rappel, le processus est le suivant :
    Lors de l'appel à une fonction :
    - les expressions utilisées en argument de l'appel sont évaluées (dans un ordre non spécifié). Donc, ici, pa et pb sont évalués, et les valeurs obtenues sont les adresses de a (&a) et de b (&b).
    - les variables déclarées en paramètres sont créées et initialisées avec la valeur obtenue pour les arguments. Donc ici, pGauche et pDroite sont créés et initialisés respectivement avec les valeurs &a et &b.
    ce qui est bien la conclusion à laquelle tu arrives.

    Donc on lui fait passer en paramètres : ce que je ne comprend pas en regardant la fonction déclarée c'est : comment la fonction traite-t-elle les adresses pour qu'elle deviennent des pointeurs ?
    Un pointeur est un objet (une variable) dont le type de la valeur est une adresse. Autrement dit, c'est le type d'objet adapté pour stocker une adresse. Les adresses ne deviennent pas des pointeurs, elles sont stockées dans des pointeurs.

    Pour moi pa est différent de *pGauche :
    Pour moi aussi
    l'un est une adresse mémoire et l'autre est un pointeur
    Non. pa est un pointeur (qui contient l'adresse de a, &a). pGauche est un pointeur (qui contient la valeur de pa soit aussi l'adresse de a). *pGauche est l'objet situé à l'adresse contenue dans pGauche, c'est à dire l'objet entier a.


    Je me demande si ton problème ne vient pas de la confusion entre la syntaxe de déclaration d'un pointeur et celle pour l'utiliser.
    Je résume le point de vue du C :
    - Si A est une adresse, alors l'opérateur unaire * permet d'obtenir l'objet à cette adresse. Symboliquement :
    Si A == &Objet alors *A == Objet.
    Donc *&Objet == Objet. La combinaison des opérateurs *& est neutre.

    - Pour déclarer un pointeur p sur un objet de type T, on va écrire qu'à l'adresse contenue dans p, on a un objet de type T. L'objet à cette adresse est (*p) et on écrira T (*p) (de la même façon que pour déclarer un objet i de type int, on écrit int i). Les parenthèses sont inutiles ici et on simplifie en T *p.
    L'étoile dans cette déclaration est une notation, ce n'est plus l'opérateur unaire *. Toutefois, le choix de cette notation n'est pas innocent et est donc directement lié au rôle de l'opérateur unaire *.
    En associant l'étoile à p (et en l'assimilant à l'opérateur *), T *p , on a dit : A l'adresse contenue dans p est un T.
    Mais on lit la déclaration T * p en associant l'étoile à T, T* p, et on dit : le type de p est T* .

    Le type de l'objet est écrit de la même façon que le type de la valeur qu'il stocke (par exemple, int, float,..., pointeurs; mais exception notable : les tableaux). Le type de p est T*. Il stocke une adresse sur T. Le type "adresse de T" s'écrira aussi T*.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  18. #38
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Merci pour vos réponses elle m'ont je pense éclairé.

    Je pense avoir compris mais je ne suis pas sûr : dites-moi si je me trompe :
    En reprenant l'exemple de la fonction Echange : lorsqu'on déclare un pointeur, on le fait comme ceci , :
    : cela veut dire grosso modo : "Réserves un pointeur pGauche en adresse mémoire"
    Tout pointeur doit être initialisé ? Alors on lui dit : pa étant initialisé à &a (l'emplacement mémoire de a)
    Mais en fait cela se fait de manière implicite lors de l'appel de la fonction par passage de paramètres.

    Voilà : en fait j'avais bien compris l'explication du tuto sous une forme simple mais n'avais pas compris du tout avec la fonction.

    Encore merci car vous m'avez appris une autre chose : je ne savais pas qu'une adresse mémoire exprimée en base hexadécimale (0x00000001) différente des entiers exprimés en base 10, pouvait être un entier aussi et surtout qu'il n'y avait pas de conversion à faire.

    Je voulais vous demander une dernière chose : est-ce que les références sont beaucoup utilisées dans la progra c++ ?

    Cordialement,
    Gizmo.

  19. #39
    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
    Oui, les références sont très utilisées en C++. La règle pour choisir entre pointeur et référence, c'est "si c'est possible avec une référence, alors on utilise une référence" : On réserve les pointeurs aux circonstances qui en ont besoin (comme la possibilité d'être nul).
    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.

  20. #40
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gizmo27 Voir le message
    Encore merci car vous m'avez appris une autre chose : je ne savais pas qu'une adresse mémoire exprimée en base hexadécimale (0x00000001) différente des entiers exprimés en base 10, pouvait être un entier aussi
    Ben une adresse c'est l'endroit où il y a la valeur. Cet endroit est identifié par un nombre donc forcément entier !!! Tu devrais essayer d'afficher tes adresses de temps en temps....

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int tab[10];
    int i;
     
    for (i=0; i < 10; i++)
    {
        printf("&tab[%d]=%d\n", i, &tab[i]);
        printf("tab + %d=%d\n", i, tab + i);
    }

    Citation Envoyé par gizmo27 Voir le message
    et surtout qu'il n'y avait pas de conversion à faire.
    Ben non. Le compilo reconnait la notation utilisée et c'est lui qui fait la conversion (il traduit de toute façon tout en binaire !!!!)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/01/2004, 12h14
  2. [FP]Writeln ne fonctionne pas !
    Par néo333 dans le forum Turbo Pascal
    Réponses: 4
    Dernier message: 02/11/2003, 00h47
  3. UNION qui ne fonctionne pas
    Par r-zo dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/07/2003, 11h04
  4. Un Hint sur un PopupMenu ne fonctionne pas !!??
    Par momox dans le forum C++Builder
    Réponses: 6
    Dernier message: 26/05/2003, 17h48
  5. ca ne fonctionne pas (generateur auto-incrémentant)
    Par tripper.dim dans le forum SQL
    Réponses: 7
    Dernier message: 26/11/2002, 01h10

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