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 :

prioité entre les opérateurs "->" et "." ?


Sujet :

C

  1. #1
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2016
    Messages
    278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2016
    Messages : 278
    Par défaut prioité entre les opérateurs "->" et "." ?
    Bonjour,

    est-ce que vous auriez un exemple en C où la question de la priorité entre les opérateur "->" et "." se pose?

    Je connais les priorités respectives de ces opérateurs, mais je cherche s'il existe des cas où la question se pose en C.

    en vous remerciant

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Je vois pas comment la question pourrait se poser, ce sont 2 opérateurs de suffixe, y'a (quasi?) aucune chance qu'ils clashent.
    Les questions pourraient se poser quand tu as des syntaxes comme *toto->tati, (*toto)->tati ou (*toto).tati
    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
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    403
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 403
    Par défaut
    Opinion personnelle : on s'en fout de la priorité des opérateurs.

    On voit souvent des questions sur le sujet lors des tests techniques, parce que c'est des questions pas forcément simple. Mais est-ce qu'on veut dans nos codes des syntaxes dont la moitié des devs sont susceptibles de se tromper ? Même un dev qui connait les règles peut facilement se tromper.

    Donc ce sont des règles a exclure du code, il faut explicitement indiquer la priorité avec des parenthèses. C'est complètement idiot de faire l'économie de 2 caractères dans un code (et qui n'a aucun impact sur les binaires après compilation). C'est plus explicite et plus safe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // écrire
    (2 * 3) + 5
     
    (*toto)->tati
     
    *(++p)
     
    // plutôt que
    2 * 3 + 5
     
    *toto->tati
     
    *++p
    etc

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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 599
    Par défaut
    Citation Envoyé par mintho carmo Voir le message
    Opinion personnelle : on s'en fout de la priorité des opérateurs.

    On voit souvent des questions sur le sujet lors des tests techniques, parce que c'est des questions pas forcément simple. Mais est-ce qu'on veut dans nos codes des syntaxes dont la moitié des devs sont susceptibles de se tromper ? Même un dev qui connait les règles peut facilement se tromper.

    Donc ce sont des règles a exclure du code, il faut explicitement indiquer la priorité avec des parenthèses. C'est complètement idiot de faire l'économie de 2 caractères dans un code (et qui n'a aucun impact sur les binaires après compilation). C'est plus explicite et plus safe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // écrire
    (2 * 3) + 5
     
    (*toto)->tati
     
    *(++p)
     
    // plutôt que
    2 * 3 + 5
     
    *toto->tati
     
    *++p
    etc
    Mettre des parenthèses alors qu'elles ne sont pas nécessaires, n'est pas toujours plus clair. Quelques exemples:
    Au fait, l'équivalent de *toto->tati c'est *(toto->tati), ça n'est pas (*toto)->tati comme tu l'indiques. Ca n'est pas évident pour toi donc en effet tu devrais utiliser des parenthèses

    Mais si j'écris *ptr++, c'est en effet difficile à lire, mais si je l'écris identiquement avec des parenthèses *(ptr++), je penses que cela est plus perturbateur pour beaucoup de monde (on peut avoir l'impression que le ++ est fait avant *).
    Ecrire a.b.c() me paraît plus lisible que son équivalent avec des parenthèses ((a.b).c)().

    Pour revenir à . et ->, ils ne sont jamais en conflit, tous les deux sont interprétés immédiatement. Par exemple a.b.c->d.e n'est pas ambiguë, c'est forcément a.(b.(c->(d.e))).
    Par contre pour .* et ->*, là on a une expression potentiellement complexe a->*b.c est-il (a->*b).c ou a->*(b.c)? C'est le second qui s'applique.

    edit : du coup je me suis gourré, c'est (((a.b).c)->d).e pour a.b.c->d.e.

  5. #5
    Membre émérite
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Juillet 2020
    Messages
    352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Juillet 2020
    Messages : 352
    Par défaut
    Citation Envoyé par mintho carmo Voir le message
    Opinion personnelle : on s'en fout de la priorité des opérateurs.
    sauf quand on lit le code de quelqu'un d'autre … comme par exemple trouver l'erreur dans le code que tu donnes (en supposant que tu donnais les équivalences) :


    Citation Envoyé par mintho carmo Voir le message
    [...\
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // écrire
    (2 * 3) + 5
     
    (*toto)->tati
     
    *(++p)
     
    // plutôt que
    2 * 3 + 5
     
    *toto->tati
     
    *++p
    [...]
    *toto->tati se parenthèse en *(toto->tati) car les opérateurs d'accès à un membre (. ou ->) ont une précédence supérieure à l'opérateur de déréférencement (*).
    . et -> ont la même précédence, il suffit de les associer de gauche à droite comme l'indique la doc.

    Edit: grilled !

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    403
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 403
    Par défaut
    Citation Envoyé par dalfab Voir le message
    Ca n'est pas évident pour toi donc en effet tu devrais utiliser des parenthèses
    Erreur involontaire de ma part, mais je reconnais sans problème que :
    1. j'ai pas trop fait attention (ce qui arrive régulièrement dans les vrais projets)
    2. je suis très content d'avoir oublié, avec le temps, ce genre de choses inutiles

    Citation Envoyé par WhiteCrow Voir le message
    sauf quand on lit le code de quelqu'un d'autre … comme par exemple trouver l'erreur dans le code que tu donnes (en supposant que tu donnais les équivalences)
    La confusion ne peut arriver que dans un code sans parenthèse. Dans un code sans parenthèse, on ne peut pas savoir si c'est un choix volontaire de la part du dev ou s'il a fait une erreur sur les règles de priorité des opérateurs. Avec des parenthèses, il peut encore y avoir des erreurs, mais l'intention du dev est explicite.

    Je ne laisse passer aucun de ces codes en review sans parenthèse. Je demande au dev qu'il exprime explicitement avec des parenthèses ce qu'il veut faire, je n'essaie pas de deviner ses intentions (ou de savoir si un dev plus tard fera une erreur).

    Citation Envoyé par dalfab Voir le message
    edit : du coup je me suis gourré
    J'oserais dire que cette correction prouve que j'ai complètement raison d'interdire les codes sans parenthèse. Et je me permet : "Ca n'est pas évident pour toi donc en effet tu devrais utiliser des parenthèses"

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Je ne suis tellement pas d'accord

    Il y a des cas où mettre des parenthèses est effectivement un plus pour éviter les erreurs. Même si tu connais par cœur toutes les priorités des opérateurs et que tu peux écrire ton code avec certitude sans parenthèse, tu ne peux pas demander / garantir que les autres personnes de ton équipe seront dans le même cas. Ainsi, je vois clairement un intérêt à *ptr++ vs (*ptr)++ vs *(ptr++).

    Toutefois, il y a des cas tellement évidents et connus de toute le monde (et si ce n'est pas le cas, il faudrait peut-être réviser) et mettre des parenthèses est inutile, voire contre-productif. Quand on lit a + b * c / e - f, on sait qu'on applique les priorités des opérateurs. Quand on met des parenthèses et qu'on obtient quelque chose comme (je crois que c'est pareil) ((a + ((b * c) / e)) - (f)), le lecteur ou la lectrice se dira sans doute "ah ! des parenthèses, donc on fait qq chose de spécial...... hein quoi ?....... ah non en fait.....je vais quand même re-vérifier".

  8. #8
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    683
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 683
    Par défaut
    Citation Envoyé par Bktero Voir le message
    mettre des parenthèses est inutile, voire contre-productif. Quand on lit a + b * c / e - f, on sait qu'on applique les priorités des opérateurs.
    Là, par contre, des parenthèses pour montrer qu'on accorde la priorité à la multiplication ou la division c'est utile car suivant les cas le résultat de l'opération sera différent.

  9. #9
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 644
    Par défaut
    Bonjour kaitlyn,

    Citation Envoyé par kaitlyn Voir le message
    Là, par contre, des parenthèses pour montrer qu'on accorde la priorité à la multiplication ou la division c'est utile car suivant les cas le résultat de l'opération sera différent.
    Je suis d'accord avec toi d'autant que les compilateurs ne traitent pas nécessairement dans l'ordre les opérations. En cas d'optimisation vitesse agressive (le cas standard ? ), il va certainement traiter en parallèle a - f avec b*c/e avant d'en faire l'addition. S'il utilise la commutativité mathématique (b*c/e = b/e*c = c/e*b) pour anticiper l'opération lente de division (même si ici, je ne vois pas d'avantage à le faire) il pourrait opter pour une forme implicite (b/e)*c qui effectivement ne donnera pas les mêmes résultats ne serait-ce que parce que, contrairement aux mathématiques, l'informatique travaille avec une précision limitée.

    Il ne faut pas abuser des parenthèses qui ont participé à la mort de Prolog et Lisp (Lost In Stupid Parentheses disaient certains) mais il ne faut non plus les bouder là où elles peuvent lever le doute (y compris le doute du développeur même en l'absence d'ambiguïté) ou pour s'assurer du comportement du compilateur sur telle ou telle sous-expression.

    Salut

  10. #10
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    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 772
    Par défaut
    Il faudrait revenir à la NPI (notation polonaise inverse) : b c e a f * / + - <- ne donne pas (a + ((b * c) / e) - f)

    Édit 1: @Guesset a raison, on empile mais c'est l'idée

    Édit 2: en lisant la réponse de @Guesset, je me suis demandé comment fonctionne la division qui n'est pas commutative.
    Et apparemment avec la NPI, il y a 2 divisions (je ne sais pas si c'est normé , mais je pense que c'est dépend de la "machine"/ implémentation)
    • x y / -> x / y (division)
    • x y \ -> y / x (division inversée)

  11. #11
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 644
    Par défaut NPI : le retour de la revanche II
    Bonjour foetus,

    Citation Envoyé par foetus Voir le message
    Il faudrait revenir à la NPI (notation polonaise inverse) : b c e a f * / + -
    Tu es sûr que ce n'est pas plutôt a,b,c*e/+f- avec "," pour le Enter d'empilage. Il me semble que b c e a f * / + - provoquera b - (c + e/(a*f)). Même si c'est ancien, je crois, sans garantie, que le principe est : j'emplie jusqu'à ce que je trouve un opérateur qui remplace alors les deux dernières entrées par le résultat de l'opération.

    Même les HP récentes (Prime par exemple) proposent par défaut la notation algébrique, mais ouf ! on peut toujours se torturer en revenant à la NPI. Nostalgie d'une source d'erreurs ?

    Salut

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par kaitlyn Voir le message
    Là, par contre, des parenthèses pour montrer qu'on accorde la priorité à la multiplication ou la division c'est utile car suivant les cas le résultat de l'opération sera différent.
    Absolument pas. Les règles de priorités des opérateurs mathématiques ont justement été créées pour que le résultat d'un calcul soit toujours le même quel que soit l'ordre des opérateurs. 2+3*4 aura toujours le même résultat que 4*3+2. Parce que sinon ce serait un beau bordel dans le milieu scientifique (si une équation écrite dans un sens avait un résultat différent de la même équation écrite dans l'autre sens !!!)

    Et donc a + b * c / e - f aura exactement le même résultat dans tous les cas.

    Ceci dit je ne parle là que des opérateurs mathématiques dont les priorités sont censées être apprises au primaire et qui ne sont qu'au nombre de 2 (multiplications et divisions, puis additions et soustractions, et de la gauche vers la droite si on trouve plusieurs opérateurs mathématiques de même rang écrits à suivre). Je suis assez d'accord que pour les opérateurs du C (14 niveaux de priorité, avec parfois de la gauche vers la droite et parfois l'inverse), personne ne peut se vanter de tous les connaître par coeur et que les parenthèses peuvent alors aider. Sans toutefois en abuser comme certains l'ont montré.
    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]

  13. #13
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 644
    Par défaut Hors sujet ?
    Bonjour Foetus,

    Citation Envoyé par foetus Voir le message
    ...apparemment avec la NPI, il y a 2 divisions (je ne sais pas si c'est normé , mais je pense que c'est dépend de la "machine"/ implémentation)
    • x y / -> x / y (division)
    • x y \ -> y / x (division inversée)
    Je découvre cette possibilité. Mais il y a aussi l'inversion des deux derniers éléments de la pile (mais il n'y a plus de commande directe sur la prime).

    Salut

Discussions similaires

  1. Priorité entre les opérateurs mod et *
    Par King2net dans le forum Langage
    Réponses: 6
    Dernier message: 21/10/2010, 16h22
  2. [XML]/[DocBook] Les entités &quot; &lt; etc.
    Par ykerb2 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 08/05/2007, 20h25
  3. Sudo problème avec les simples quotes
    Par Tronche dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 23/03/2007, 12h02
  4. Les doubles quotes dans les fprintf
    Par Changedman dans le forum C
    Réponses: 30
    Dernier message: 22/02/2007, 12h07

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