OVH Cloud OVH Cloud

Priorité et associativité des opérateurs

125 réponses
Avatar
Greydavayar
Bonjour a tous,

je lis partout le terme "d'associativit=E9" des op=E9rateurs ainsi que le
teme de "priorit=E9" des op=E9rateurs je pense avoir compris celui de la
priorit=E9 mais cette notion d'associativit=E9 reste tr=E8s (trop) floue
pour moi et je ne trouve rien qui l'explique clairement sur le net.

Bonne soir=E9e

10 réponses

Avatar
JKB
Le Wed, 08 Sep 2010 11:20:19 +0200,
Antoine Leca écrivait :
Alexandre Bacquart écrivit :
a - b - c



L'expression en tant que telle n'a rien à voir avec l'associativité, que
ce soit en maths ou en C. La seule règle à suivre est que ça s'applique
de gauche à droite.



Mmmm. Et le fait que lire de gauche à droite puisse donner le même
résultat que lire de droite à gauche, cela s'appelle comment, en maths ?

Autrement dit, parce que - n'est évidemment pas une opération
associative, tu as besoin d'une règle _conventionnelle_, en l'occurrence
qu'il faille lire de gauche à droite.


moindre petite subtilité, ni même une paire de parenthèses qui, soit dit
en passant, rajoutent une autre règle à suivre.



La position de JKB, c'est justement le rejet de la règle de la lecture
de gauche à droite, et son corrolaire, l'utilisation d'une _autre_
règle, celle des parenthèses : mais il ne s'agit pas d'une règle
supplémentaire, elle remplace.



Attention, on commence à toucher du doigt un consensus ;-)

ce qu'on appelle du code auto-documenté.



Pour moi, le « code auto-documenté » à base de constructions implicites
est une lubie qui cache beaucoup de paresse de la part des programmeurs
et induit beaucoup de perte de temps pour des questions existentielles
au moment de la phase débogage ; là où c'est drôle, c'est quand il se
trouve que la même personne est à la fois le programmeur auto-
documentant et celui qui se pose des questions au débogage ;-)



C'est justement ce que je trouve marrant. Ma position fait que je
débuggue (trop) souvent le code des autres qui ne se posent pas ces
questions existentielles. Et lorsque tu n'es pas celui qui a écrit
ces aberrations, tu te poses deux fois plus de questions
existentielles...

Par contre, je crois que des formulation comme (a-b)-c ou a-(b+c) sont
effectivement auto-documentées, rajoutant explicitement une information
C'est surtout vrai lorsque, comme dans le premier cas, elles sont
syntaxiquement inutiles, donc n'ont de portée sémantique qu'à
destination de celui qui lit, comme n'importe quel commentaire.



Je plussoie vigoureusement.

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Avatar
Wykaaa
Antoine Leca a écrit :
Wykaaa écrivit :
Exemples pour l'associativité :
- Associativité à gauche de l'opérateur + binaire :
a + b + c + d s'interprète comme : (((a + b) + c ) + d)
- Associativité à droite de l'opérateur d'affectation :
a = b = c = d s'interprète comme : (a = (b = (c = d)))



Oui

Il est conseillé de TOUJOURS mettre les parenthèses dans les expressions.



Mmmm, je ne suis pas complétement d'accord là. Cf. infra.


Priorité des opérateurs :
- La multiplication est prioritaire par rapport à l'addition. Ceci
signifie que : a + b * c s'interprète comme : a + (b * c)



Oui

- attention à certains cas :



OUI. Et c'est là que je vois l'intérêt de mettre des parenthèses, MÊME
si elles ne sont pas strictement nécessaires : en effet les cas d'erreur
potentielles sont nombreux en C.
Cela concerne les opérateurs sur les valeurs binaires (& | ^), les
opérateurs de décalages (<< >>) et les opérateurs de comparaison.
Que j'ai exprès mis dans le désordre.


l'opérateur & (opérateur ET bit à bit) est
plus prioritaire que les opérations arithmétiques



? On est bien sur fr.comp.lang.c ?



Je ne comprends pas ton interrogation. Oui c'est du C !

a + b & c s'interprète comme a + (b & c)



En mathématiques (où & est un succédané de multiplication) ou en Turbo
Pascal (avec & écrit and) d'accord, mais en C ?



Non & n'est pas un succédané de la multiplication en mathématique.
Oui et bien quoi en C ?

Un exemple d'utilisation :

while(MIDI_Byte1!=0x90){//Autolearn MIDI Channel



if(RCIF){

clear_usart_errors();

Rx_DATA=RCREG;

MIDI_Byte1 = Rx_DATA&0xF0;

MIDI_Chnl = Rx_DATA&0x0F;

}
}
C'est une utilisation courante du & lorsque l'on code des protocoles de
telecom et souvent on retrouve cet opérateur "mélangé" avec des
opérateurs arithmétiques pour appliquer un masque sur le résultat des
opérations.
Remarque préventive : le code n'est pas de moi ;-)



En général, ce que souhaite le programmeur, c'est plutôt faire :
(a + b) & c (appliquer un "masque" au résultat de l'addition).



Là, c'est la justification du choix de DMR...



Ben c'est l'utilisation la plus courante. Je ne vois pas ce qu'il y a de
surprenant à cela et, pour une fois, DMR a raison.

J'ai vu je ne sais combien de fois cette erreur en faisant des revues de
code (et pas seulement en C, C++ ou Java mais aussi en PL/1, par exemple).




Antoine
Avatar
espie
In article <i67ems$pk2$,
Antoine Leca wrote:
largement plus probable en l'instance) ; mais c'est aussi une chose qui
va surprendre la plupart des « utilisateurs », autrement dit cela
ressemble à de la mauvaise qualité...



<mauvaise langue>ca fait maintenant quelques annees que, de ce point de
vue, GCC fait de la mauvaise qualite</mauvaise langue>. Ils ont introduit
pas mal d'optimisations qui font gagner des SPECmarks, mais qui sont vraiment
tordues cote interpretation de la norme, et qui surprennent les utilisateurs.
Avatar
Wykaaa
Marc Espie a écrit :
In article <4c86b5c7$0$22645$,
Samuel DEVULDER wrote:
Le 07/09/2010 01:53, Marc Espie a écrit :

Justement, il n'y a rien de naturel ni de canonique dans tes surjections
(au sens theorie des categories),


Ca je ne connais pas. Il y a de vrais théorèmes utiles et pratiques la
dedans?


Un peu, oui. Toute la theorie du typage est basee dessus. Et toutes les
histoires de covariance/contravariance viennent aussi de la.


ah? Il faut bien baser les types sur une théorie, ca fait plus sérieux,
quitte à ce que la théorie soit celle du "grand tout et n'importe quoi" :)



Justement, le jeu est d'eviter que ca soit "grand tout et n'importe quoi".
Dans ce cadre precis, les maths modernes "classiques" (la theorie des
ensembles) s'effondre completement, parce que justement, on ne parle plus
d'objets qui sont des ensembles, et le paradoxe de Cantor n'est pas bien
loin.



C'est Bertrand Russell qui l'a appelé comme cela. Cantor n'a, lui,
jamais parlé de paradoxe. Aujourd'hui on dirait plutôt : la classe des
cardinaux n'est pas un ensemble.
Ce que ne pouvait dire Cantor, évidemment puisque la théorie axiomatique
des ensembles n'existait pas encore.
Par ailleurs, dire que "la théorie des ensembles s'effondre
complètement" vis-à-vis des types, c'est un peu abuser car le typage
fait appel à une logique du second ordre. Mais bon, on ne va pas entrer
dans les méandres des ZF-expressions, du lambda calcul typé polymorphe
du second ordre et tout le toutim...

Plus sérieusement, cela a l'air d'avoir rapport avec l'inférence de
types des compilo scala, camel et consors. C'est donc plus vraiment des
maths, mais du formalisme informatique trop puissant pour le commun des
programmeurs. En tout cas ca nous éloigne complètement du C et des
évaluations booléennes.



On va plutot dire, incomprehensible pour le programmeur java moyen, hein...



Pourquoi programmeur _Java_ moyen ?
Disons programmeur tout court ...

Ne te laisse pas emporter par ton aversion au langage Java ;-)

[couic] : plus compréhensible que "snip" ;-)

Cordialement Marc.
Avatar
Antoine Leca
Wykaaa écrivit :
Antoine Leca a écrit :
Wykaaa écrivit :
Priorité des opérateurs :






[couic]
l'opérateur & (opérateur ET bit à bit) est
plus prioritaire que les opérations arithmétiques



? On est bien sur fr.comp.lang.c ?



Je ne comprends pas ton interrogation. Oui c'est du C !



Jusqu'à maintenant, j'avais considéré que les opérations arithmétiques
(+ - * / %) étaient plus prioritaires que l'opérateur &.


a + b & c s'interprète comme a + (b & c)



En mathématiques (où & est un succédané de multiplication) ou en Turbo
Pascal (avec & écrit and) d'accord, mais en C ?



Oui et bien quoi en C ?



J'avais compris qu'en C, a + b & c s'interprétait comme (a+b) & c


Un exemple d'utilisation :


<couic> je ne vois pas de mélange entre opérateur arithmétique et & dans ton
exemple, sauf à considérer = comme un opérateur arithmétique.

(= est effectivement moins prioritaire que &, mais je n'avais
pas compris que la discussion portait là-dessus.)


En général, ce que souhaite le programmeur, c'est plutôt faire :
(a + b) & c (appliquer un "masque" au résultat de l'addition).



Là, c'est la justification du choix de DMR...



Ben c'est l'utilisation la plus courante.



Cela dépend complètement des gens : beaucoup de programmeurs C se
plaignent et préféreraient le contraire, que & (et aussi << et >>)
soient plus prioritaires qu'ils ne le sont en C. En particulier plus
prioritaires que les opérateurs de comparaison, comme dans
if (a&mask == b&mask) /* effet surprenant en C... */


Je ne vois pas ce qu'il y a de
surprenant à cela et, pour une fois, DMR a raison.



(J'aime bien le « pour une fois » :-) )
Le problème, c'est que lui-même n'en est pas sûr...


Antoine
Avatar
Antoine Leca
Wykaaa écrivit :
Notez que je ne fais qu'insister sur le contenu de mon précédent message
: si le code dépend de la première forme et ne passe pas avec la seconde
(ou vice-versa), il faut rajouter des commentaires pour éviter de se
poser des questions existentielles.



Un code limpide avec des noms de variables bien choisies, des
parenthèses dans les expressions, etc. n'a pas besoin de commentaires.



Si je te suis bien, il faudrait interdire les commentaires ?
Ou seulement les formulations qui nécessiteraient de mettre des
commentaires ?


Les commentaires sont souvent là pour exprimer de façon non formelle ce
qu'un mauvais programmeur n'a pas pu exprimer de façon clair en
formalisant dans sa programmation.



C'est effectivement une sorte de commentaires, qui d'ailleurs ne sont
pas toujours le fait du dit programmeur ; quant à savoir si c'est
souvent ou parfois...


Il ne faut pas, non plus, négliger la lourdeur de la tâche de
maintenance des commentaires quand le code change.



La même remarque vaut pour les algorithmes, les noms de variables etc.
les tâches de maintenance sont souvent sous-évaluées.

Par ailleurs, si est mauvais le programmeur qui obligeait à ce que le
mainteneur rajoutât un commentaire pour démêler l'effet d'un morceau de
code, doit-on qualifier de bon programmeur celui qui modifie le code
sans toucher au commentaire attenant ?
Ou le problème est-il seulement que la maintenance des commentaires est
une tâche de lourdeaux, pas assez noble pour les (vrais) programmeurs ?


Antoine
Avatar
espie
In article <i682vb$98r$,
Antoine Leca wrote:
Cela dépend complètement des gens : beaucoup de programmeurs C se
plaignent et préféreraient le contraire, que & (et aussi << et >>)
soient plus prioritaires qu'ils ne le sont en C. En particulier plus
prioritaires que les opérateurs de comparaison, comme dans
if (a&mask == b&mask) /* effet surprenant en C... */



Avec le niveau de sophistication de certains warnings, j'avoue que je ne
comprend pas pourquoi les compilos ne regardent pas les espaces dans une
expression...

l'air de rien, il est evident pour un etre humain que l'expression
ci-dessus a ete ecrite dans l'idee qu'elle va faire if ((a&mask) == (b&mask))
ca ne me parait pas hyper-complique de balancer un gros warning !

Il y a pas mal de cas ou ca pourrait etre utile. C'est pas tres dur non plus
de regarder les niveaux d'indentation et de detecter le ; intempestifs
et les } mal refermes...

Et c'est exactement le genre de choses qu'un compilo est le mieux place
pour faire, vu qu'il doit de toutes facons deja calculer enormement de
choses sur la semantique du programme, etre un peu plus precis sur l'analyse
de syntaxe ne me parait pas specialement aberrant !
Avatar
espie
In article <4c8745cd$0$10193$,
Wykaaa wrote:
Un code limpide avec des noms de variables bien choisies, des
parenthèses dans les expressions, etc. n'a pas besoin de commentaires.
Les commentaires sont souvent là pour exprimer de façon non formelle ce
qu'un mauvais programmeur n'a pas pu exprimer de façon clair en
formalisant dans sa programmation.
Il ne faut pas, non plus, négliger la lourdeur de la tâche de
maintenance des commentaires quand le code change.



ce que tu dis ne s'applique que si tu as des specs et une analyse independante
dont tu es sur qu'elles vont rester avec le code.

Par exemple, si tu fais du calcul numerique, tu fais comment pour ecrire
toute la preuve de ton calcul avec les marges d'erreurs directement dans
ton code ? tu mets des tonnes d'assert ? ca ne va pas suffire a expliquer
pourquoi telle valeur est < 1e-6, par exemple. Et si tu reprends un algo
classique, tu vas le nommer algo_from_numerical_recipes_1985edition_p253 ?

Il y a quand meme un point ou ca devient absurde et ou ecrire de vrais
commentaires va faire du sens...
Avatar
Antoine Leca
JKB écrivit :
Le Wed, 08 Sep 2010 11:20:19 +0200,
Antoine Leca écrivait :
La position de JKB, c'est [...]



Attention, on commence à toucher du doigt un consensus ;-)



Ehem... le fait que je reformule ta position, dans mon esprit, n'a pas
d'autre signification que d'essayer de faire comprendre _ta_ position à
Alexandre, qui me semble être passé à côté ; et tant l'entrée du
paragraphe --qu'il convient de ne pas oublier dans les citations-- comme
l'utilisation de la troisième personne ne doivent pas laisser à penser
qu'il s'agit de ma propre position.

Il est vrai que pour une fois, je n'ai pas utilisé le conditionnel.


/A contrario/, deux lignes plus bas...

ce qu'on appelle du code auto-documenté.



Pour moi, [...] je crois [...]





etc. :-)


Je plussoie vigoureusement.



Ah, là on peut peut-être essayer de construire un consensus !


Antoine
Avatar
Wykaaa
Antoine Leca a écrit :
Wykaaa écrivit :
Antoine Leca a écrit :
Wykaaa écrivit :
Priorité des opérateurs :






[couic]
l'opérateur & (opérateur ET bit à bit) est
plus prioritaire que les opérations arithmétiques


? On est bien sur fr.comp.lang.c ?


Je ne comprends pas ton interrogation. Oui c'est du C !



Jusqu'à maintenant, j'avais considéré que les opérations arithmétiques
(+ - * / %) étaient plus prioritaires que l'opérateur &.



Oooops. désolé. je me suis un peu mélangé dans les langages (j'en
connais trop !).
Mille excuses

[couic]