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 :

pointeur sur un pointeur


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 62
    Points : 43
    Points
    43
    Par défaut pointeur sur un pointeur
    bonjour , j'essaie de manipuler les pointeurs sur les pointeurs sans objectif precis , j ai ecris un 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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int foo(int *tab[]){
     
     printf("%p\n",tab);
     return 1 ;
    }
     
    int main(){
    int a[5];
    int **b;
    b=&(*a);
    foo(b);
    return 1 ;
    }

    le pb c est que j ai un warning que j arrive pas a enlever :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    C:\Users\alexa\Documents\tp_PDC_theme_4\essai1.c:14:2: warning: assignment from incompatible pointer type
     b=&(*a);
      ^

    pourriez vous m 'aider ?

  2. #2
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Bonjour,
    l'opérateur unaire & sert à prendre l'adresse d'un objet. L'expression *a n'est pas un objet mais une valeur indéterminée de type int → ça n'a aucun sens de vouloir en prendre la valeur.
    Si tu veux l'adresse du premier élément de a il te suffit d'écrire a, et si (comme je le suppose) tu veux l'adresse du tableau a alors &a est l'expression que tu devrais utiliser. Attention pointeur et tableau sont deux objets différents en C avec des comportement qui se ressemblent mais qui sont différents.

  3. #3
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 62
    Points : 43
    Points
    43
    Par défaut reponse
    j avais fait une faute dans le code oui :

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int foo(int *tab[]){
     
     printf("%p\n",tab);
     return 1 ;
    }
     
    int main(){
    int a[5];
    int **b;
    b=&a;
    foo(b);
    return 1 ;
    }

    mais j ai toujours un warning :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C:\Users\alexa\Documents\tp_PDC_theme_4\essai1.c|14|warning: assignment from incompatible pointer type|

    &a me donne vraiment l'adressse de l adresse du tableau ?moi c est ce que je cherche en fait ma syntaxe a l'air bonne maintenant. mais apparemment j ai toujours un warning et si je fais b[0] apres ça me donne un entier ou plutot un adresse ?comme c est un pointeur sur pointeur

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Sans être méchant vas apprendre les pointeurs et ensuite les tableaux


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void foo(int* tab) {
       printf("%p\n", tab);
    }
     
     
    int main(int /*argc*/, char** /*argv*/) {
       int a[5];
     
       foo(a);
     
       return 1;
    }

  5. #5
    Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Février 2013
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2013
    Messages : 62
    Points : 43
    Points
    43
    Par défaut reponse
    ça marche pas l adresse n est pas la même j ai demandé un pointeur sur un pointeur !et je voudrais savoir ce qu il arrive si je fais b[5] ou b[0] est ce que ce sera un int ou une adresse?

    là c est pas ce que je veux , c'est pas du tout ce que j ai demandé

  6. #6
    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 : 61
    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 648
    Points
    7 648
    Par défaut
    Bonjour,

    Un pointeur sur T, c'est une variable qui pointe sur une donnée qui a le type T.
    Un pointeur de pointeur sur T, c'est une variable qui pointe sur une variable qui pointe sur une donnée de type T. Il y a donc au moins 3 données (le pointeur de pointeur, le pointeur et la donnée pointée)
    Un tableau de T, c'est une séquence de données du type T. Un nom de tableau devient pointeur quand il est passé en paramètre.

    Si on a un pointeur, on peut pointer dessus par un pointeur de pointeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int a[5];            // a est un tableau  et  a <=> &a[0]  et  &a n'a pas de sens il est vu comme équivalent à a
    int **b;             // b doit pointer sur un pointeur
    b = &a;              // FAUX on s'attend à recevoir l'adresse d'un pointeur, or &a est un pointeur
    int *c = a;          // ok c pointe sur le début de a
    b = &c;              // ok b pointe sur c qui pointe sur le début de a
    foo( b );            // ok, foo() attend un pointeur de pointeur, il reçoit l'adresse de c
     
    void foo( int *tab[] ) {
     printf("%p\n", tab );      // tab est bien l'adresse de c
     printf("%p\n", *tab );     // *tab est le contenu de c, c'est un pointeur correspondant à a
     printf("%d\n",(*tab)[0]);  // (*tab)[0] est le 1er pointé par c, donc a[0]
     printf("%d\n", **tab );    // est aussi a[0]
    }

  7. #7
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Citation Envoyé par alex5956 Voir le message
    ça marche pas l adresse n est pas la même j ai demandé un pointeur sur un pointeur !et je voudrais savoir ce qu il arrive si je fais b[5] ou b[0] est ce que ce sera un int ou une adresse?

    là c est pas ce que je veux , c'est pas du tout ce que j ai demandé
    C'est super simple, si b est une expression de type «tableau d'objets de type O» ou de type «pointeur sur un objet de type O» alors le type d'une expression b[n] est de type O.
    Si b est un objet de type T, alors &b est une expression de type «pointeur sur un objet de type T».

    Dans ton code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a[5];
    int **b;
    b=&a;
    a est de type «tableau de 5 int», b est de type «pointeur sur pointeur sur un entier» et &a est une expression «pointeur sur tableau de 5 int». b et &a n'ont pas le même type → d'où le warning.
    Tableaux et pointeurs sont deux choses bien différentes.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Citation Envoyé par alex5956 Voir le message
    ça marche pas l adresse n est pas la même j ai demandé un pointeur sur un pointeur !et je voudrais savoir ce qu il arrive si je fais b[5] ou b[0] est ce que ce sera un int ou une adresse?
    là c est pas ce que je veux , c'est pas du tout ce que j ai demandé
    C'est-à-dire que tes posts ne sont pas vraiment clairs, tu en conviendras.

    Pour le reste, tu mets effectivement le doigt sur une particularité assez récurrente du langage C.

    • Un tableau, en C, est une suite d'éléments de même type et même taille consécutifs en mémoire, sans aucune autre méta information additionnelle stockée à côté. Tout ce qu'il y a à retenir l'est à la compilation uniquement, et disparaît de l'exécutable final. Ainsi un tableau tel que int tab[10]; sur une machine utilisant des entiers sur 32 bits, donc 4 octets, occupera exactement quarante octets en mémoire, pas un de plus, pas un de moins ;
    • Une expression de type « pointeur sur un élément », c'est-à-dire l'adresse en mémoire d'un objet de type identifié, quelle qu'elle soit, peut être indexée en ajoutant une paire de crochets pour accéder à l'élément pointé ou au nième élément qui le suit ;
    • Invoquer le nom d'un tableau seul renvoie l'emplacement en mémoire de ce tableau, et donc celle du premier élément. Ainsi, dans le cas du tableau ci-dessus, écrire tab renvoie donc l'adresse du tableau et est donc une expression de type int *, qui peut être indexée ;
    • Via l'arithmétique des pointeurs (qui tient compte de la taille du type pointé lorsqu'on incrémente ceux-ci), on peut affirmer que p[n] est équivalent à *(p+n), c'est-à-dire le déplacement du pointeur de n éléments, puis le déréférencement de l'adresse ainsi obtenue ;
    • Tout ceci permet donc d'exploiter un tableau comme un pointeur et réciproquement.


    Maintenant, les deux différences (à connaître) entre un tableau et un pointeur sont :

    1. La résolution de leur identifiant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        int tab[10];
        int *ptr;
     
        printf ("tab: %p\n",tab);
        printf ("&tab: %p\n",&tab);
     
        printf ("ptr: %p\n",ptr);
        printf ("&ptr: %p\n",&ptr);
    Dans le premier cas, tab et &tab sont équivalents et renvoient la même valeur. La première renvoie « le tableau lui-même », donc son emplacement en mémoire, et la seconde renvoie… « l'adresse du tableau en mémoire », donc son emplacement en mémoire.

    Dans le second cas, en revanche, la première expression renvoie le contenu du pointeur, donc sa valeur, soit l'adresse mémoire de ce qu'il pointe, alors que la seconde expression renvoie l'emplacement du pointeur lui-même, qui lui est une variable propre, que l'on peut éventuellement remplir.

    2. L'estimation de leur taille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        int tab[10];
        int *ptr;
     
        printf ("taille de tab: %p\n",sizeof tab);
        printf ("taille de ptr: %p\n",sizeof ptr);
    Dans le premier cas, le compilateur sait qu'il s'agit d'un tableau et va donc te renvoyer la place qu'il occupe en mémoire : 40.
    Dans le second cas, le compilateur va te renvoyer la taille du pointeur lui-même, donc la largeur d'une adresse mémoire, quelle que soit l'envergure de ce qu'il pointe. Donc : 4 (ou 8 sur une machine 64 bits).

    En outre, si tu écris « int **p », tu déclares bien « un pointeur sur un pointeur sur un entier ». Par conséquent, si tu déréférences p, tu obtiens donc « un pointeur sur un entier », et pas un « entier ».

    Comme l'adresse d'un tableau est « un pointeur sur un entier : int * », il faut bien déclarer « un pointeur sur un entier : int *b » pour la recevoir, et pas « un pointeur sur un pointeur sur un entier : int **b »


    Tu peux également lire ces discussions :

    https://www.developpez.net/forums/d1...ion-pointeurs/
    https://www.developpez.net/forums/d1...-3-dimensions/

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

Discussions similaires

  1. Probleme de pointeur sur une fonction
    Par nicky78 dans le forum C
    Réponses: 2
    Dernier message: 23/05/2004, 20h26
  2. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17
  3. [allegro]passage de pointeur sur image
    Par Gonath dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 13/12/2003, 18h47
  4. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50
  5. Declaration de fonction retournant un pointeur sur fonction
    Par pseudokifaitladifférence dans le forum C
    Réponses: 5
    Dernier message: 11/08/2003, 19h37

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