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 :

decryptage d'une expression structure pointeur


Sujet :

C

  1. #1
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 73
    Localisation : Antarctique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2019
    Messages : 3
    Points : 2
    Points
    2
    Par défaut decryptage d'une expression structure pointeur
    Bonjour,

    Le code ci-dessous est extrait d'un code parfaitement fonctionnel que j'ai un peu de mal à décrypter (je suis débutant en C). Il s'agit de l'initialisation d'un buffer circulaire pour une liaison serie.
    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
    char  TX_buf[32];
    char  RX_buf[32];
     
    struct {	
    		unsigned char  *ringBuf_start;
    		unsigned char  *ringBuf_end;
    		unsigned char  *ringBuf_in;
    		unsigned char  *ringBuf_out;
    	 } TX;
     
    struct {
    		unsigned char  *ringBuf_start;
    		unsigned char  *ringBuf_end;
    		unsigned char  *ringBuf_in;
    		unsigned char  *ringBuf_out;
    	 } RX;
     
    void init_serial_buffer(void)
    {
           ((&TX) -> ringBuf_in = (&TX) -> ringBuf_out = (&TX) -> ringBuf_start = TX_buf,	(&TX) -> ringBuf_end = &(&TX) -> ringBuf_start[32-1]);
           ((&RX) -> ringBuf_in = (&RX) -> ringBuf_out = (&RX) -> ringBuf_start = RX_buf,	(&RX) -> ringBuf_end = &(&RX) -> ringBuf_start[32-1]);
    }
    Je me demande ce que signifie "&(&TX) ->" dans :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    (&TX) -> ringBuf_end = &(&TX) -> ringBuf_start[32-1]);
    Et plus généralement, connaissez-vous des sites, des livres, videos...etc où je pourrai m'entrainer à la lecture et/ou à la production d'expressions complexes de pointeurs/structures. Sachant à moyen terme je doit devenir capable de produire du code optimisé pour systèmes embarqués.

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    &x : pointeur sur x
    y->z utiliser le membre z du pointeur y

    Écrire (&X)->Y est un peu stupide, il est plus simple d'écrire X.Y.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    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 : 60
    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,

    Peut-être que celui qui écrit ce code a lu un livre expliquant comment écrire des expressions illisibles. Une explication de choses simples me parait préférable.

    Tu as arrêté ta lecture avant la fin de l'expression. Pour le moment je ne vais que déplacer les espaces & (&TX)->ringBuf_start[32-1] (les espaces ne jouent pas de rôle dans l'interprétation d'une expression.)
    Maintenant j'écris la même ligne telle que je l'aurais écrite : TX.ringBuf_start+(32-1) n'est-elle pas plus simple? On peut aussi l'écrire & TX.ringBuf_start[32-1] c'est encore équivalent.
    Cette expression retourne l'adresse du dernier octet qui est dans le buffer désigné par ringBuf_start.

    Des explications :
    (& qqch) -> toto est totalement équivalent à qqch.toto sauf que c'est très tordu.
    En effet, en prenant l'adresse de qqch on obtient un pointeur, et un pointeur s'utilise avec -> pour accéder à un champ.

    Le & au tout début de l'expression & (&TX)->ringBuf_start[32-1] ne doit être interprété qu'en dernier, il va chercher l'adresse de (&TX)->ringBuf_start[32-1]. Tous les opérateurs unaires à droite (ce sont ++ -- accès-tableau appel-fonction accès-à-un-champ accès-pointeur-à-un-champ) ont une action immédiate, les autres opérateurs ne sont traités qu'après.
    Exemples :
    *tb[2] correspond à : le 3ième élément du tableau est déréférencé.
    &fct(int) correspond à : j'ai une fonction dont je veux prendre l'adresse
    &pt->tb[1] correspond à : accéder 2nd élément du tableau désigné par pt->tb, et en trouver son adresse
    pt->tb + 1 correspond à la même chose : la seule chose à connaître est l'équivalence ptrOuTab[x] <==> *(ptrOuTab + x) ou bien &ptrOuTab[x] <==> ptrOuTab + x.
    *pt++ est peut-être le plus dur à interpréter. On incrémentera après le pointeur vu, et on déréférence le pointeur(avant son incrémentation)
    (*pt)++ on incrémente ce qui est pointé (le pointeur de change pas.) la parenthèse est importante

    edit : grilled mais j'ai un peu plus détaillé

  4. #4
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 73
    Localisation : Antarctique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2019
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    donc &(&TX) -> ringBuf_start[32-1] signifie : utiliser le membre ringBuf_start[32-1] du pointer sur pointer sur TX et ça veut dire ... ?

  5. #5
    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 : 60
    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
    En tout cas ta phrase ne veut rien dire. Quant à ta réponse je l'ai déjà donnée

  6. #6
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Août 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 73
    Localisation : Antarctique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2019
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Dalbaf ton explication éclaircit bien les choses.

    A la base j'ai obtenu ce code en utilisant le pre-processeur sur le code ci-dessous pour faire sauter les macros et obtenir un qqch de plus clair ...

    le code originel est le suivant
    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
    #define MAX_BUFLEN 32
     
    #define RB_CREATE(ringBuf, type)	\
    	struct {			\
    		type *ringBuf_start;	\
    		type *ringBuf_end;	\
    		type *ringBuf_in;       \
    		type *ringBuf_out;	\
    		} ringBuf
     
    #define RB_INIT(ringBuf, start, number)								        \
    	((ringBuf) -> ringBuf_in = (ringBuf) -> ringBuf_out = (ringBuf) -> ringBuf_start = start,	\
    	(ringBuf) -> ringBuf_end = &(ringBuf) -> ringBuf_start[number])
     
    char TX_buf[MAX_BUFLEN];
    char RX_buf[MAX_BUFLEN];
     
    RB_CREATE (TX, unsigned char);
    RB_CREATE (RX, unsigned char);
     
    void init_serial_buffer(void)
    {
             RB_INIT(&TX, TX_buf, MAX_BUFLEN-1);
    	 RB_INIT(&RX, RX_buf, MAX_BUFLEN-1);
    }

    En tout cas vous m'avez permis d'approfondir un peu les expressions à pointeur
    Un grand MERCI à tous !

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

Discussions similaires

  1. [JNA] - Pointeur de structure dans une autre structure
    Par John.BE dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 24/02/2012, 15h02
  2. Structure dans une Structure : Pointeur ou Objet?
    Par TNT89 dans le forum Langage
    Réponses: 11
    Dernier message: 13/07/2009, 19h53
  3. [String] rendre une expression reguliere insensible à la case
    Par chimical dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 07/05/2004, 11h38
  4. "Différence de type dans une expression" Tquery
    Par Hakim dans le forum Bases de données
    Réponses: 3
    Dernier message: 20/04/2004, 00h22
  5. [langage] surement une expression régulière...
    Par armada dans le forum Langage
    Réponses: 5
    Dernier message: 30/05/2003, 17h06

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