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 :

problème d'affichage avec les pointeurs


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Février 2008
    Messages
    354
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Tunisie

    Informations forums :
    Inscription : Février 2008
    Messages : 354
    Points : 139
    Points
    139
    Par défaut problème d'affichage avec les pointeurs
    Bonjour,
    J'ai essayé de corriger cet exercice en c mais j'ai trouvé une différence entre l'exécution à la main et l'exécution en utilisant VS
    Le code
    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
     
    #include "stdafx.h"
    #include <stdio.h>
    int G1 = 1, G2 = 2, G3 = 3;
    int ptr1=&G1, ptr2=&G2, *ptr3=&G3;
    void f1(int a, int b) { a = b; }
    int  f2(int *b, int c)
    {
     *b = c;
     b = &G1;
     return *b;
    }
     
    int tmain(int argc, TCHAR* argv[])
    {
     int NoLig = 1;
     f1(G1, ptr2);
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     (*ptr1)++;(*ptr2)++;(*ptr3)++;
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     f2(ptr2, *ptr3);
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     (*ptr1)++;(*ptr2)++;(*ptr3)++;
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     return 0;
    }
    le problème est lorsqu'on applique la fonction f2, normalement ptr2 prend l'adresse de G1 mais lors de l'exécution avec VS elle a gardé la même adresse.
    L'exécution en utilisant VS
    No ligne : 1 G1 = 1 G2 = 2 G3 = 3
    No ligne : 2 G1 = 2 G2 = 3 G3 = 4
    No ligne : 3 G1 = 2 G2 = 4 G3 = 4
    No ligne : 4 G1 = 3 G2 = 5 G3 = 5
    L'exécution à la main
    No ligne : 1 G1 = 1 G2 = 2 G3 = 3
    No ligne : 2 G1 = 2 G2 = 3 G3 = 4
    No ligne : 3 G1 = 2 G2 = 4 G3 = 4
    No ligne : 4 G1 = 4 G2 = 4 G3 = 5

  2. #2
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir,
    Citation Envoyé par moooona Voir le message
    Bonjour,
    J'ai essayé de corriger cet exercice en c mais j'ai trouvé une différence entre l'exécution à la main et l'exécution en utilisant VS
    Le code
    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
    #include "stdafx.h"
    #include <stdio.h>
    int G1 = 1, G2 = 2, G3 = 3;
    (1)int ptr1=&G1, ptr2=&G2, *ptr3=&G3;
    (2)void f1(int a, int b) { a = b; }
    (3)int  f2(int *b, int c)
    {
     *b = c;
     b = &G1;
     return *b;
    }
    
    int tmain(int argc, TCHAR* argv[])
    {
     int NoLig = 1;
     (4)f1(G1, ptr2);
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     (*ptr1)++;(*ptr2)++;(*ptr3)++;
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     f2(ptr2, *ptr3);
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     (*ptr1)++;(*ptr2)++;(*ptr3)++;
     printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3);
     return 0;
    }
    le problème est lorsqu'on applique la fonction f2, normalement ptr2 prend l'adresse de G1 mais lors de l'exécution avec VS elle a gardé la même adresse.
    L'exécution en utilisant VS

    L'exécution à la main
    Il n'y a pas mal d’erreurs; plus une confusion ou une incompréhension des pointeurs.
    Pour commencer, un pointeur (dit « variable pointeur ») est une variable de type adresse plus précisément, un pointeur est une adresse associée à un type de donnée. Exemple: Si l’on déclare un pointeur de type caractère ou entier. Le type pointé ( « int ou char ») permet alors de connaître la taille et la façon dont il faut interpréter les bits qui la composent.
    Mais l’on comprend également qu'aucune donnée n’est stockée dans la variable pointeur, elle contient juste l’adresse mémoire où se trouve la donnée de type type (On dit alors que le variable pointeur pointe vers une donnée du type type).
    La manipulation des pointeurs se fait de la façon suivante:
    • L’opérateur ‘&' permet d’obtenir l’adresse d’une variable de type type exemple: int *p = &x. L’opérateur ‘&' ne peut être appliqué qu’a des variables donc, des objets qui se trouvent uniquement dans la mémoire interne et ne peut pas être utilisés à des variables déclarées avec les mots-clés « register » ou des expressions.
    • L’opérateur ‘*’ permet d’accéder à la valeur de l’objet pointé en clair au contenu de l’adresse. Ce procédé est appelé déréférencement de pointeur Exemple: int x = 10;, int *p = &x;, *p = 19; // change la valeur de x.


    Toutefois il faut faire attention, un pointeur est une variable comme toutes les autres donc un pointeur doit être (dans mon cas toujours et forcement) initialisé a « NULL » en attente de données a pointé car, si vous ne le faites pas elle contiendra une valeur aléatoire (sauf cas de static) donc vers une donnée en mémoire quelconque que vous n’avez pas le droit d’accès. Et pourquoi « NULL » parce que cette constante est en réalité un pointeur invalide de référence c’est-à-dire qu’il correspond à l’adresse mémoire ‘0x0’ (zéro) considérer le plus souvent comme étant une adresse erronée et utile pour détecter des erreurs d’adressage en clair si un pointeur pointe sur nulle cela veux dire qu'il pointe sur rien et peut-être considéré comme étant une erreur mais tout dépend de l’implémentation et de l’interprétation de chacun.

    Il existe également d'autres pointeurs du type void*p dits types génériques, c'est-à-dire sans type associé. Ces pointeurs sont donc généralement utilisés dans les cas où l’on ne connaît pas encore le type de l’objet. Le pointeur génériques sont converties implicitement vers un autre type de pointeur avant d'être l’utiliser.

    Bref revenons à votre problème (il se fait tard donc j'abrège.)
    • (1)Vous ne pouvez pas assigner à une variable une adresse. Pour que cela marche il faut déclarée les variables « Ptr1 & Ptr2 » comme étant des variables pointeurs et par la suite attribué les différentes adresses de vos variables du type entier
    • (2)« void f1(int a, int b) { a = b; } » la fonction ne modifie rien du tout elle manipule que des copies pour modifier la variable il faut utiliser les pointeurs et faire un déréférencement. En utilisant la fonction dans votre code (cas 4) vous générer une erreur qui est une forme du cas 1.
    • (5)« (*Ptr1)++;(*Ptr2)++;(*Ptr3)++; arrivé ici c’est un peut du n’importe quoi sans vouloir vous vexer et êtes vous sur que le programme compile ?

    voici un exemple simple mais il faut également revoir votre cours ou chapitre sur les pointeurs.
    Attention le code source peut comporté des erreurs.
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int main( void ){
     
        int x = 10;
        int y = 20;
        int z = y + x;
     
        int *p = NULL;
     
        p = &x;   // p contient l(adresse de x = 10;;
        fprintf( stdout, "addr %p = %d\n", p, *p );
     
        *p = 20;  // p change la valeur de x à 20;
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&x, x );
     
        p = &y;  // p pointe sur y = 20 et x est egale a 20 toujour;
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&x, x ); // 20
        fprintf( stdout, "addr %p = %d\n", (void*)&y, y ); // 30
     
        *p = 30;  // p change la valeur de y à 30;
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&y, y ); // 30
     
        p = &z;  //p pointe sur Z = 10 + 20 du dépard
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&x, x );
        fprintf( stdout, "addr %p = %d\n", (void*)&y, y );
        fprintf( stdout, "addr %p = %d\n", (void*)&z, z );
     
        *p = 40; // p change la valeur Z;
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&y, y );
     
        z = 41;
        fprintf( stdout, "addr %p = %d\n", p, *p );  // P = 41 car il pointe sur z
        x = 100;
        y = 200;
        *p = x+y;
        fprintf( stdout, "addr %p = %d\n", p, *p );
        fprintf( stdout, "addr %p = %d\n", (void*)&z, z ); //Z = 300
        return EXIT_SUCCESS;
    }
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  3. #3
    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 519
    Points
    41 519
    Par défaut
    Bonjour,
    Je vais refaire l'exécution à la main de ton code.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    void f1(int a, int b) { a = b; }
    Cette fonction ne fait rien d'autre que modifier une variable locale, qui est ensuite détruite quand la fonction se termine. Je vais donc la supprimer ainsi que son appel, vu qu'elle n'a pas d'effet de bord.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int  f2(int *b, int c)
    {
    	*b = c;
    	b = &G1;
    	return *b;
    }
    b étant une variable locale, cette fonction peut se résumer à ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int  f2(int *b, int c)
    {
    	*b = c;
    	return G1;
    }
    Et en fait, on peut même supprimer le return vu que la valeur retournée n'est jamais lue.

    Ton code simplifié doit maintenant ressembler à ceci, et les commentaires correspondent à mon exécution à la main:
    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
    17
    18
    19
    20
    21
     
    #include "stdafx.h"
    #include <stdio.h>
    int G1 = 1, G2 = 2, G3 = 3;
    int *ptr1=&G1, *ptr2=&G2, *ptr3=&G3;
     
    void f2(int *b, int c) { *b = c; }
     
    int _tmain(int argc, TCHAR* argv[])
    {
    	int NoLig = 1;
     
    	printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3); //Affiche 1 et 1, 2, 3
    	(*ptr1)++;(*ptr2)++;(*ptr3)++;                                          //Incrémente à 2, 3, 4
    	printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3); //Affiche 2 et 2, 3, 4
    	f2(ptr2, *ptr3);                                                        //Équivaut à G2 = G3 -> 2, 4, 4
    	printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3); //Affiche 3 et 2, 4, 4
    	(*ptr1)++;(*ptr2)++;(*ptr3)++;                                          //Incrémente à 3, 5, 5
    	printf("No ligne : %d G1 = %d G2 = %d G3 = %d\n", NoLig++, G1, G2, G3); //Affiche 4 et 3, 5, 5
    	return 0;
    }
    Cela correspond parfaitement au résultat de VS, c'est donc ton calcul à la main qui était erroné.
    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.

Discussions similaires

  1. Problème d'affichage avec les float
    Par Poseidon62 dans le forum Ada
    Réponses: 9
    Dernier message: 04/05/2007, 14h03
  2. Réponses: 17
    Dernier message: 22/01/2007, 13h34
  3. Problème d'affichage avec les lumières
    Par Glosialabolas dans le forum OpenGL
    Réponses: 3
    Dernier message: 02/11/2006, 18h46
  4. [PHP-JS] Problème d'affichage avec les ', ê, é,è
    Par cyberdevelopment dans le forum Langage
    Réponses: 4
    Dernier message: 28/07/2006, 13h49
  5. Réponses: 6
    Dernier message: 19/05/2005, 11h06

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