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 :

Petits problèmes de pointeurs


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut Petits problèmes de pointeurs
    Salut,

    Alors voilà, j'ai des instructions sur les pointeurs que je ne comprend pas bien.
    Je les ai écris :
    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
    #include <stdio.h>
     
    int main(){
      int a[] = {12,23,34,45,56,67,78,89,90,100};
      int *p, (*q)[2];
      p=a;
      q = (int (*)[2])&a;
     
      printf("%p %p %p\n",a,&p,&q);
     
      printf("%d\n", *p+2);  //14
      printf("%d\n", *(p+2)); //34
      printf("%p\n", &p+1);
      printf("%p\n",&a[4]);
      printf("%p\n",&a[4]-3);
      printf("%p\n",a+3);
      printf("%d\n",&a[7]-p);
      printf("%p\n",p+(*p-10));
      printf("%d\n",*(p+*(p+8)-a[7])); //23
      printf("%d\n",(*q)[3]);
      printf("%p\n",q+2);
      printf("%d\n",(*(q+3))[1]);
      return 0;
    }
    Dans un premier temps j'ai hésiter à me sucider en me coupant les veines avec la feuille d'exam (c'était bien dans un exam de c) ... et dans un second temps aussi ... Mais bon j'ai quand même réussi à comprendre certaines instruction (3 avec les "//" et qqunes avec les adresses). J'ai alors plusieurs questions :
    - que fait l'instruction qui affecte q ?
    - que se passe t-il quand on ajoute 3 a une adresse ? Genre &a[4]-3 ou a+3 , comment expliqueriez vous ce résultat ?
    - que font les 3 dernières instructions exactement ?

    Après avoir regardé qq cours sur les pointeurs, je ne trouve toujours pas réponses à ces questions ... Si qqun pourrait m'éclairer je serai très reconnaissant.

    Merci d'avance.

    Edit : j'ai oublié de vous donner les résultats de ce prog :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    0xbfdb8d60 0xbfdb8d8c 0xbfdb8d88
    14
    34
    0xbfdb8d90
    0xbfdb8d70
    0xbfdb8d64
    0xbfdb8d6c
    7
    0xbfdb8d68
    23
    45
    0xbfdb8d70
    89

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Tu avais toutes ces instructions et devais dire ce que chacune fait (ou affiche) ?

    - que se passe t-il quand on ajoute 3 a une adresse ? Genre &a[4]-3 ou a+3 , comment expliqueriez vous ce résultat ?
    C'est la base de l'arithmétique des pointeurs. Quand tu incrémentes un pointeur, tu te décales de façon à pointer sur l'emplacement mémoire suivant, en considérant la mémoire comme une suite d'emplacement du type pointé.
    Exemple : soit pa pointeur sur int, alors pa+1 pointe sur l'entier suivant après *pa.

    - que fait l'instruction qui affecte q ?
    &a est n'est pas du même type que q, il faut donc caster la valeur pour obtenir des types concordants, sinon, tu auras un warning à la compilation :
    d:\...\test.c|76|warning: assignment from incompatible pointer type|
    - que font les 3 dernières instructions exactement ?
    Quelque d'assez obscur pour moi, il faut encore que je réfléchisse là-dessus

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    En espérant ne pas m'être trompé

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <stdio.h>
     
    int main(void){
      int a[] = {12,23,34,45,56,67,78,89,90,100};
      int *p, (*q)[2];
      p=a;
      q = (int (*)[2])&a;
     
      printf("a = %p \t&p = %p \t&q = %p\n",a,&p,&q);
     
      printf("%d\n", *p+2);  //14
      printf("%d\n", *(p+2)); //34
      printf("%p\n", &p+1); // adresse de p + taille d'un pointeur (4 octets)
      printf("%p\n",&a[4]); // adresse du 5e element (a +16 octets)
      printf("%p\n",&a[4]-3); // adresse du 2e element (a + 4 octets)
      printf("%p\n",a+3);   // adresse du <s>3e</s> 4e elements (a + 12 octets)
      printf("%d\n",&a[7]-p); // a + 7 - a = 7
      printf("%p\n",p+(*p-10)); //p+12-10 = p+2 = a+2
      printf("%d\n",*(p+*(p+8)-a[7])); //23
     
     
        puts("\nLe coquinou de 'q'...");
        /* q est un pointeur sur un tableau de 2 ints
        Voir http://www.developpez.net/forums/d1177939/c-cpp/c/tableaux-string/#post6467166 */
     
        printf("q vaut  %p qui est bien l'adresse du debut du tableau 'a'\n" , q);
     
        printf("1=%d  2=%d\n",(*q)[0], (*q)[1] ); //
        printf("%d\n",(*q)[3]); // logique avec la ligne du dessus
     
        printf("sizeof(*q) = %d\n", sizeof(*q));
        printf("%p\n",q+2);   // q decale de 2 fois ce qu'il pointe.
                            // il pointe un tableau de 2 ints donc 4*2 octets
                            // on se decale 2 fois donc 16 octets au total
     
        printf("%d\n",(*(q+3))[1]); // en combinant les precedentes explications
                                    // on obtient bien le 8e element de a, soit a[7]
        printf("Pour verifier, a[7] = %d\n\n", a[7]);
      return 0;
    }

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2007
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 178
    Points : 451
    Points
    451
    Par défaut
    Citation Envoyé par Raikyn Voir le message
    - que font les 3 dernières instructions exactement ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d\n",(*q)[3]);
    Là a priori c'est relativement simple "q" étant initialisé comme l'adresse de "a", la 4ème valeur du tableau s'affiche

    Là ça commence à être un peu plus tordu, on obtiend l'adresse "a" ("q") décalée deux fois mais comme "q" est déclaré non pas comme un entier mais comme un tableau de deux entier ça donne q + 2 * 2 * (taille en octet d'un entier (en général 4))

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d\n",(*(q+3))[1]);
    Là c'est vachement tordu mais si on a en tête le truc de dessus c'est assez logique : on décale 3 fois, chaque décalage faisant 2 entiers on arrive au 7éme élément du tableau, du coup à la position "[1]" on tombe sur le 8ème élément soit 89

    Edit : ah, grillé par Bktero, bon visiblement on est assez d'accord c'est plutôt bon signe, mais c'est clair que c'etait pas trivial comme question

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    On a effectivement l'air d'accord

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Merci pour vos réponses, mais j'ai encore qq soucis ^^

    Citation Envoyé par Bktero Voir le message
    C'est la base de l'arithmétique des pointeurs. Quand tu incrémentes un pointeur, tu te décales de façon à pointer sur l'emplacement mémoire suivant, en considérant la mémoire comme une suite d'emplacement du type pointé.
    Exemple : soit pa pointeur sur int, alors pa+1 pointe sur l'entier suivant après *pa.
    Ok, si on affiche avec %p on obtient donc l'adresse du prochain élément.

    Ensuite : &a[7]-p , je n'ai pas très bien compris le a + 7 - a. Normalement quand on fait a[7] on obtient pas l'élément en 7ème position ? Donc &a[7] ça devrait être l'adresse de cet élément non ?

    Aussi, à propos de l'affectation de q, si j'ai bien compris c'est un tableau de 2 int dont le début est le début de a ? Donc si on veut faire par exemple
    Ca affichera a[3] ? Même si c'est hors limite de q ?

    Les dernières instructions ont encore un peu du mal à être acceptées par ma cervelle, je reviendrais là dessus sans doutes x)

    Encore merci.

    PS : J'ai eu la liste des printf dans l'exam, il fallait juste dire ce que ça affichait. Je ne vous cacherais pas que cet exam ne ma pas trop inspiré :v

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ensuite : &a[7]-p , je n'ai pas très bien compris le a + 7 - a. Normalement quand on fait a[7] on obtient pas l'élément en 7ème position ? Donc &a[7] ça devrait être l'adresse de cet élément non ?
    Oui c'est ça

    Il faut savoir que a est le nom du tableau, mais que si tu utilises a dans le code (seul, sans crochet derrière), il est automatiquement converti en &a[0]. Il faut aussi savoir que a[1] est égal à *(a+1).

    p étant égal à a (p contient l'adresse du premier élément du tableau, il contient &a[0]), on a : &a[7] - p = &*(a+7) - a = a +7 - a = 7.


    Aussi, à propos de l'affectation de q, si j'ai bien compris c'est un tableau de 2 int dont le début est le début de a ?
    Non, q est un pointeur vers un tableau de 2 entiers. Regarde le lien que j'ai donné en commentaire dans le code précédent.

    Comme q est un pointeur sur un tableau (de 2 entiers), il faut bien l'initialiser avec &a et non a (je te passe le transtypage dont j'ai déjà parlé).

    *q est égal à a, en toute logique et par conséquent.

    Ca affichera a[3] ?
    Tu essayeras

    Même si c'est hors limite de q ?
    Les limites c'est toujours une chose floue en C. q n'a pas de limite, c'est un pointeur vers un endroit donné de la mémoire. Tu peux le faire pointer où tu as envie, mais à cet endroit :
    • il se pourrait que tu lises n'importe quoi
    • il se pourrait qu'écrire provoque un crash (segmentation fault) ou un comportement tout à fait improbable

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Bonjour à tous.

    Je lis avec intérêt ce thread et ne comprends pas un point.

    Normalement lorsque l'ont fait :
    pour obtenir l'adresse du 8e élément, on ne rajoute pas réellement 7 à l'adresse maisnon ?

    Donc pourquoi lorsque l'ont fait
    obtient-on 7 et non pas
    ?

    Edit : En fait ma question c'est : pourquoi le compilateur s'occupe-t-il lui même de ce calcul ?

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Quand tu as un pointeur, tu peux faire :
    - p++ pour pointer sur l'élément suivant
    - p-- pour pointer sur l'élément précédant
    - p += x pour pointer sur le x ième élément suivant
    - p -= x pour pointer sur le x ième élément précédant
    - pointeur début - pointeur fin : nombre d'élément.

    C'est beaucoup plus pratique que de devoir à chaque fois écrire sizeof tu ne trouves pas?
    De plus ceci évite certaines erreurs (comme pointer sur un int puis pointer un octet plus loin).

    L'autre raison, c'est qu'il n'y a aucun intérêt à incrémenter/décrémenter un pointeur d'un octet quelque soit le type.
    Or pointer x éléments après ou avant est très utile dans les parcours de tableaux etc...

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2012
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2012
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse.

    Oui c'est beaucoup plus pratique en effet.

    Ce qui me dérange c'est que lorsque que j'utilise le format d'affichage %d, je m'attend à un calcul mathématique sur des entiers et non une interprétation automatique par mon compilateur d'un soustraction d'adresse.
    J'aurais aimé obtenir 7 lorsque j'utilise %p et 28 lorsque j'utilise %d. Cela me paraîtrait plus logique. Mais peut-être me trompe-je.

  11. #11
    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
    int *p, (*q)[2] : p est un pointeur sur int, q est un pointeur sur un tableau de 2 int
    
    p=a        :   p contient l'adresse du premier élément du tableau a
    
    q = (int (*)[2])&a : q contient l'adresse d'un tableau de 2 éléments (int), cette adresse étant celle du tableau a (de 10 int, d'où le cast). 
                         (But probable : présenter a comme un tableau à 2 dimensions q[5][2])
    
    ...a,&p,&q : affichage de l'adresse du premier élément (n°0) de a, de l'adresse du pointeur p et de celle du pointeur q
    
    ...*p+2    : Equivalent à p[0]+2 : affichage de l'entier à l'adresse p auquel on a ajouté 2.(p==a)-> a[0]+2 -> 14 
    
    ...*(p+2)  : Equivalent à p[2] : affichage de l'entier n°2 du tableau débutant à l'adresse p. (p==a) a[2]-> 34.
    
    ...&p+1    : Adresse de p augmentée de 1. 
                 Comme p est du type int *, la position mémoire de p sera augmentée de sizeof(int*) 
    
    ...&a[4]   : Equivalent à &*(a+4) == a+4 . 
                 L'adresse correspond à celle de l'élément n°4 de a 
                (position mémoire : celle de a augmentée de 4*sizeof(int))
    
    ...&a[4]-3 : Equivalent à &*(a+4)-3 == a+4-3 == a+1 . 
                 L'adresse correspond à celle de l'élément n°1 de a 
                (position mémoire : celle de a augmentée de sizeof(int))
    
    ...a+3     : L'adresse correspond à celle de l'élément n°3 de a 
                (position mémoire : celle de a augmentée de 3*sizeof(int))
    
    ...&a[7]-p : Equivalent à &*(a+7)-p == a+7-p ; avec p==a -> 7
    
    ...p+(*p-10) : *p ==*a == a[0] == 12. Donc égal à p+(12-10) == p+2. 
                   L'adresse correspond à celle de l'élément n°2 de p (ou de a) 
                  (position mémoire : celle de a augmentée de 2*sizeof(int))
    
    ...*(p+*(p+8)-a[7]): Equivalent à *(p+p[8]-a[7]) == p[p[8]-a[7]]. 
                         (p==a) -> a[a[8]-a[7]] == a[1] == 23
    
    ...(*q)[3]  :  Equivalent à q[0][3]. Comme q[0] == a  -> a[3]  == 45
    
    ...q+2      : adresse de l'élément n°2 de q. Les éléments de q sont des tableaux de 2 int, 
                  (position mémoire : celle de q (ou a) augmentée de 2*sizeof(int[2]) ==  4*sizeof(int)) 
    
    ...(*(q+3))[1] : Equivalent à q[3][1] ; 
                     q[3] : Ce tableau (de 2 int) correspond à la position de l'élément n°6 (=3*2) de a 
                     (q[0]==a); q[3][1] est l'élément n°7 de a (a[7]) -> 89
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par stroke Voir le message
    Normalement lorsque l'ont fait :
    pour obtenir l'adresse du 8e élément, on ne rajoute pas réellement 7 à l'adresse maisnon ?

    Donc pourquoi lorsque l'ont fait
    obtient-on 7 et non pas
    ?
    Ecrire a+7 est implicitement transformé par le compilateur en a + (7 * sizeof(int)), et même plus probablement en a + (7 * sizeof(*a)). Pour l'opération inverse, je pense que c'est surtout pour une question de cohérence. Posons que int *b = a + 7. Il serait logique que le test b - a == 7 soit vrai. De même, il serait cohérent qu'il fasse le calcul implicitement dans les 2 sens. Pour le programmeur, ce qui importe n'est pas tant le décalage réel en mémoire mais le décalage en terme d'objets, comme l'a dit Neckara.



    Je regarde la correction de diogene, j'ai fait une faute (pour *(a+3))... Je m'en sors bien ^^

  13. #13
    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
    Aussi, à propos de l'affectation de q, si j'ai bien compris c'est un tableau de 2 int dont le début est le début de a ? Donc si on veut faire par exemple
    Ca affichera a[3] ? Même si c'est hors limite de q ?
    * Non.
    La raison est que *(q+3) == q[3] est du type "tableau de 2 int". Dans ce contexte, q[3] est donc l'adresse du premier élément du tableau q[3]. Ce n'est pas un int (mais un int*). La position mémoire est celle de q (ou de a) augmentée de 3*sizeof(int[2]) == 6* sizeof(int) (et le format devrait être %p)

    * A noter que q[3] est bien dans les limites du tableau (q correspond à un tableau int [5][2])

    * A retenir absolument pour tout comprendre des tableaux et de leur rapport avec les adresses :
    Si A est une expression désignant un tableau d'éléments de type T, alors A est l'adresse du premier élément de A, (donc de type T*)
    excepté dans deux cas seulement:
      - A est l'opérande de sizeof
      - A est l'opérande de l'opérateur unaire & (adresse de)
      Dans ces deux cas A est effectivement le tableau (et est de type T[])
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Merci à tous pour les réponses j'y vois nettement plus clair.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Bonjour,

    J'ai quelques questions sur les pointeurs (encore :p ), j'ai préféré continuer ce post que d'en créer un autre.

    Alors j'ai des tableaux :
    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
    typedef int (*ptr_tab10int)[10];
    ptr_tab10int t1;
    void init(int (*)[10]); // prototype de init avec type incomplet pour le paramètre
    int t2[4][10]; 
     
    void init(int (*t)[10]) { 
       int i;
       for(i = 0; i < 10; i++)
         (*t)[i] = i + 1;
    } 
     
    int main ( ) {
       int i;
       t1 = malloc(10 * sizeof(int)); 
       init(t1); 
       for(i = 0; i < 10; i++)
          printf("%d ", (*t1)[i]); 
     
        return 0;
    }
    Je ne comprend pas très bien la notation (*t1)[i], avez-vous un équivalent à me proposer ? Je fais qq recherche il s'agit peut-être de "type incomplet" mais je ne vois pas à quoi ça sert.

    Merci d'avance.

  16. #16
    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
    (*t1)[i] : cette notation est utilisée lorsque t1 est l'adresse d'un tableau.
    (*t1) est ce tableau
    et
    (*t1)[i] est un élément de ce tableau

    A noter des incohérences :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef int (*ptr_tab10int)[10];
    ptr_tab10int t1;
    ....
    t1 = malloc(10 * sizeof(int));
    On s'attend à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t1 = malloc(sizeof *t1);
    pour allouer 1 élément, cet élément étant lui-même un tableau de 10 int (même si le code est équivalent, il devient obscur avec la première formulation).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    D'accord, et on peut dire que c'est la même chose que même si c'est mal formulé.

    Aussi si j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef int (*ptr_tab10int)[10];
    ptr_tab10int t1;
    t1 = malloc(sizeof *t1);
     
    int t2[4][10];
    Que fait :

  18. #18
    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
    D'accord, et on peut dire que sizeof *t1 c'est la même chose que sizeof((*)[10]) même si c'est mal formulé.
    Non. Si on reprend la definition de t1, par le typedef, c'est équivalent à la définition int (*t1)[10];. Alors *t1 a le type int[10]et sizeof *t1 est équivalent à sizeof(int[10]) (ou 10*sizeof(int))

    Il faut faire très attention à la formulation : si on fait une formulation approchée, c'est souvent en fait parce que le problème est mal assimilé et que ça cache une lacune dans la compréhension des choses.

    Que fait : t1 = t2 +1.
    t2 est un tableau de 4 tableaux de 10 int.
    Dans le contexte de l'expression t2+1 (cf message #13 de la discussion), t2 est l'adresse du premier élément du tableau t2. Il est donc de type "adresse d'un tableau de 10 int" : int (*)[10] (ce qui correspond bien au type de t1).
    Sa valeur est égale à &t2[0](voir remarque).

    D'après l'arithmétique des adresses, en faisant t2+1, on augmente l'adresse t2 pour obtenir celle de l'élément suivant celui désigné par t2. Donc t2+1 est l'adresse du second tableau de 10 int de t2 (type int (*)[10]). Sa valeur est égale à &t2[1].
    Cette adresse correspond au 11-ième entier figurant dans le tableau t2.

    Remarque : t2[0] est un tableau (de 10 int) et donc dans l'expression &t2[0], t2[0] désigne bien le tableau et &t2[0] est "l'adresse d'un tableau de 10 int", de type int (*)[10](cf message #13 de la discussion).
    Publication : Concepts en C

    Mon avatar : Glenn Gould

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

  19. #19
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Pour les messages de diogene, on devrait avoir un bouton qui lui ferait gagner 10 points d'un coup !

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 152
    Points : 64
    Points
    64
    Par défaut
    Il est vrai qu'il rend tout les problèmes plus clairs ^^

    Merci et à bientôt (certainement sur ce topic )

Discussions similaires

  1. Réponses: 22
    Dernier message: 14/04/2014, 00h02
  2. Petit problème de pointeur
    Par Bebuck dans le forum Débuter
    Réponses: 9
    Dernier message: 12/02/2012, 05h19
  3. Petit problème sur pointeurs de structures
    Par benjaminb dans le forum C
    Réponses: 5
    Dernier message: 05/01/2008, 20h08
  4. Réponses: 4
    Dernier message: 15/10/2006, 18h05
  5. petit problème avec pointeurs
    Par Kerod dans le forum C
    Réponses: 12
    Dernier message: 09/12/2005, 15h48

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