OVH Cloud OVH Cloud

Priorité des opérateurs logiques

20 réponses
Avatar
David Côme
Bonjour à tous.
J'ai la norme sous les yeux et je n'arrive pas à trouver un paragraphe sur
la priorité des opérateurs logique, en particulier sur && et ||.
J'ai bien trouvé page 63 la note 53 disant "The precedence of operators is
not directly specified, but it can be derived from the syntax."
mais ca ne m'avance pas pour savoir lequel est prioritaire sur l'autre ou
si au contraire ils ont tout les deux la même priorité (ce que j'ai
toujours pensé).

Merci beaucoup pour vos réponses.
David Côme.

10 réponses

1 2
Avatar
James Kanze
On Aug 27, 6:49 pm, Wykaaa wrote:
David Côme a écrit :



> J'ai la norme sous les yeux et je n'arrive pas à trouver un
> paragraphe sur la priorité des opérateurs logique, en
> particulier sur && et ||. J'ai bien trouvé page 63 la note
> 53 disant "The precedence of operators is not directly
> specified, but it can be derived from the syntax." mais ca
> ne m'avance pas pour savoir lequel est prioritaire sur
> l'autre ou si au contraire ils ont tout les deux la même
> priorité (ce que j'ai toujours pensé).



Quand on veut faire des programmes de qualité, fiables,
lisibles,etc., pour toutes ces "choses" on met les parenthèses
qui vont bien sans se prendre la tête avec la norme qui est
tout sauf pédagogique (elle n'est pas faite pour cela).



Ça dépend : trop de parenthèses nuit aussi à la lisibil ité. Pour
des expressions logiques complexes, j'ai tendance à les découper
en fonctions, c-à-d :

bool
f()
{
return conditionA() || conditionB() || conditionC() ;
}

bool
conditionA()
{
return conditionA1() && conditionA2() && conditionA3() ;
}
// etc.

plutôt que :

bool
f()
{
return (conditionA1() && conditionA2() && conditionA3())
|| (conditionB1() && conditionB2() && conditionB3())
|| (conditionC1() && conditionC2() && conditionC3()) ;
}

Mais c'est loin d'être une règle absolue.

Quand j'utilise des expressions logiques complexes, je mets bien
les parenthèses, comme tu dis. Mais ça n'empėche que c'est u tile
de savoir la précédence, ou au moins de savoir la rétrouver, ne
serait-ce que pour lire le code des autres.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Wykaaa
James Kanze a écrit :
On Aug 27, 6:49 pm, Wykaaa wrote:
David Côme a écrit :



J'ai la norme sous les yeux et je n'arrive pas à trouver un
paragraphe sur la priorité des opérateurs logique, en
particulier sur && et ||. J'ai bien trouvé page 63 la note
53 disant "The precedence of operators is not directly
specified, but it can be derived from the syntax." mais ca
ne m'avance pas pour savoir lequel est prioritaire sur
l'autre ou si au contraire ils ont tout les deux la même
priorité (ce que j'ai toujours pensé).





Quand on veut faire des programmes de qualité, fiables,
lisibles,etc., pour toutes ces "choses" on met les parenthèses
qui vont bien sans se prendre la tête avec la norme qui est
tout sauf pédagogique (elle n'est pas faite pour cela).



Ça dépend : trop de parenthèses nuit aussi à la lisibilité. Pour
des expressions logiques complexes, j'ai tendance à les découper
en fonctions, c-à-d :

bool
f()
{
return conditionA() || conditionB() || conditionC() ;
}

bool
conditionA()
{
return conditionA1() && conditionA2() && conditionA3() ;
}
// etc.

plutôt que :

bool
f()
{
return (conditionA1() && conditionA2() && conditionA3())
|| (conditionB1() && conditionB2() && conditionB3())
|| (conditionC1() && conditionC2() && conditionC3()) ;
}

Mais c'est loin d'être une règle absolue.



Je suis d'accord avec ça. Cependant, je ne suis pas certain que les
appels en cascades soient réellement plus lisibles que les parenthèses
(même s'il y en a beaucoup).

Quand j'utilise des expressions logiques complexes, je mets bien
les parenthèses, comme tu dis. Mais ça n'empėche que c'est utile
de savoir la précédence, ou au moins de savoir la rétrouver, ne
serait-ce que pour lire le code des autres.



Dans un environnement professionnel, le code des autres ressemblera au
tien car il y aura un manuel des règles de programmation auquel il
faudra se conformer...
Personnellement, dans un manuel de règles de programmation (quel que
soit le langage), j'ai toujours vu la règle qui indique que les
expressions doivent être parenthésées et de ne pas faire confiance aux
règles du langage concernant la précédence des opérateurs.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
James Kanze
On Aug 31, 11:56 am, Wykaaa wrote:
James Kanze a écrit :
> On Aug 27, 6:49 pm, Wykaaa wrote:
>> David Côme a écrit :



>>> J'ai la norme sous les yeux et je n'arrive pas à trouver
>>> un paragraphe sur la priorité des opérateurs logique, en
>>> particulier sur && et ||. J'ai bien trouvé page 63 la
>>> note 53 disant "The precedence of operators is not
>>> directly specified, but it can be derived from the
>>> syntax." mais ca ne m'avance pas pour savoir lequel est
>>> prioritaire sur l'autre ou si au contraire ils ont tout
>>> les deux la même priorité (ce que j'ai toujours pensé) .



>> Quand on veut faire des programmes de qualité, fiables,
>> lisibles,etc., pour toutes ces "choses" on met les parenthèses
>> qui vont bien sans se prendre la tête avec la norme qui est
>> tout sauf pédagogique (elle n'est pas faite pour cela).



> Ça dépend : trop de parenthèses nuit aussi à la lis ibilité.
> Pour des expressions logiques complexes, j'ai tendance à les
> découper en fonctions, c-à-d :



> bool
> f()
> {
> return conditionA() || conditionB() || conditionC() ;
> }



> bool
> conditionA()
> {
> return conditionA1() && conditionA2() && conditionA3() ;
> }
> // etc.



> plutôt que :



> bool
> f()
> {
> return (conditionA1() && conditionA2() && conditionA3())
> || (conditionB1() && conditionB2() && conditionB3())
> || (conditionC1() && conditionC2() && conditionC3()) ;
> }



> Mais c'est loin d'être une règle absolue.



Je suis d'accord avec ça. Cependant, je ne suis pas certain
que les appels en cascades soient réellement plus lisibles que
les parenthèses (même s'il y en a beaucoup).



Si on arrive à trouver des bons noms pour les fonctions de bas
niveau, c'est clairement plus lisible. Sinon... c'est pourquoi
ce n'est pas une règle absolue :-).

> Quand j'utilise des expressions logiques complexes, je mets
> bien les parenthèses, comme tu dis. Mais ça n'empėche qu e
> c'est utile de savoir la précédence, ou au moins de savoir
> la rétrouver, ne serait-ce que pour lire le code des autres.



Dans un environnement professionnel, le code des autres
ressemblera au tien car il y aura un manuel des règles de
programmation auquel il faudra se conformer...



Dans des environnements professionnels où j'ai travaillé, il
nous arrive d'utiliser pas mal du code des tièrces, surtout open
source. Qui est plus ou moins bien écrit, et dans lequel il faut
plonger quand il ne marche pas.

Personnellement, dans un manuel de règles de programmation
(quel que soit le langage), j'ai toujours vu la règle qui
indique que les expressions doivent être parenthésées et d e ne
pas faire confiance aux règles du langage concernant la
précédence des opérateurs.



Jusqu'un certain point (qui dépend au moins en partie du domaine
d'application). Est-ce que tu écriras « x + *p », ou « x +
(*p) » ? Et si le domaine utilise les expressions mathématiques
plus ou moins compliquées :
discrim = b*b - 4*a*c ;
ou
discrim = (b * b) - ((4 * a) * c) ;
Dans ces cas-ci, la plupart des gens que je connais trouvent
l'expression sans parenthèses plus lisibles.

(Note que je suis d'accord avec toi en général. Mais je
reconnais qu'il y a des cas particuliers.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Wykaaa
James Kanze a écrit :
On Aug 31, 11:56 am, Wykaaa wrote:
James Kanze a écrit :
On Aug 27, 6:49 pm, Wykaaa wrote:
David Côme a écrit :







J'ai la norme sous les yeux et je n'arrive pas à trouver
un paragraphe sur la priorité des opérateurs logique, en
particulier sur && et ||. J'ai bien trouvé page 63 la
note 53 disant "The precedence of operators is not
directly specified, but it can be derived from the
syntax." mais ca ne m'avance pas pour savoir lequel est
prioritaire sur l'autre ou si au contraire ils ont tout
les deux la même priorité (ce que j'ai toujours pensé).









Quand on veut faire des programmes de qualité, fiables,
lisibles,etc., pour toutes ces "choses" on met les parenthèses
qui vont bien sans se prendre la tête avec la norme qui est
tout sauf pédagogique (elle n'est pas faite pour cela).







Ça dépend : trop de parenthèses nuit aussi à la lisibilité.
Pour des expressions logiques complexes, j'ai tendance à les
découper en fonctions, c-à-d :





bool
f()
{
return conditionA() || conditionB() || conditionC() ;
}





bool
conditionA()
{
return conditionA1() && conditionA2() && conditionA3() ;
}
// etc.





plutôt que :





bool
f()
{
return (conditionA1() && conditionA2() && conditionA3())
|| (conditionB1() && conditionB2() && conditionB3())
|| (conditionC1() && conditionC2() && conditionC3()) ;
}





Mais c'est loin d'être une règle absolue.





Je suis d'accord avec ça. Cependant, je ne suis pas certain
que les appels en cascades soient réellement plus lisibles que
les parenthèses (même s'il y en a beaucoup).



Si on arrive à trouver des bons noms pour les fonctions de bas
niveau, c'est clairement plus lisible. Sinon... c'est pourquoi
ce n'est pas une règle absolue :-).

Quand j'utilise des expressions logiques complexes, je mets
bien les parenthèses, comme tu dis. Mais ça n'empėche que
c'est utile de savoir la précédence, ou au moins de savoir
la rétrouver, ne serait-ce que pour lire le code des autres.





Dans un environnement professionnel, le code des autres
ressemblera au tien car il y aura un manuel des règles de
programmation auquel il faudra se conformer...



Dans des environnements professionnels où j'ai travaillé, il
nous arrive d'utiliser pas mal du code des tièrces, surtout open
source. Qui est plus ou moins bien écrit, et dans lequel il faut
plonger quand il ne marche pas.



Pour le code tierce, il faut utiliser, si possible, des outils comme
Logiscope pour vérifier les règles de programmation et "nettoyer", en
conséquence, le code qu'on reçoit.

Personnellement, dans un manuel de règles de programmation
(quel que soit le langage), j'ai toujours vu la règle qui
indique que les expressions doivent être parenthésées et de ne
pas faire confiance aux règles du langage concernant la
précédence des opérateurs.



Jusqu'un certain point (qui dépend au moins en partie du domaine
d'application). Est-ce que tu écriras « x + *p », ou « x +
(*p) » ?


Là ce n'est pas pareil car un programmeur se rappelle forcément que les
opérateurs unaires sont prioritaires sur les opérateurs binaires.
Et si le domaine utilise les expressions mathématiques
plus ou moins compliquées :
discrim = b*b - 4*a*c ;
ou
discrim = (b * b) - ((4 * a) * c) ;
Dans ces cas-ci, la plupart des gens que je connais trouvent
l'expression sans parenthèses plus lisibles.


Ici on peut se contenter de (b * b) - (4 * a * c) car la multiplication
est associative...

(Note que je suis d'accord avec toi en général. Mais je
reconnais qu'il y a des cas particuliers.)



Le problème c'est surtout le mélange des opérateurs logiques et
arithmétiques car on ne se rappelle jamais lesquels ont priorité sur qui.
Je me rappelle d'un bug, en C, lors d'un audit, dû à une expression du
genre :
a + x & 0x0000ffff
Ici on voit l'intention du programmeur qui veut "abattre" les bits de
fort poids de x et additionner le résultat à a. En clair,
il veut faire : a + (x & 0x0000ffff).
Sauf que, en C, + est prioritaire sur & et que, donc, l'expression est
interprétée comme (a + x) & 0x0000ffff !!
Cette expression était utilisée pour construire les trames d'un
protocole. Je ne te dis pas les dégâts !


--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
James Kanze
On Aug 31, 7:30 pm, Wykaaa wrote:
James Kanze a écrit :



[...]
>> Personnellement, dans un manuel de règles de programmation
>> (quel que soit le langage), j'ai toujours vu la règle qui
>> indique que les expressions doivent être parenthésées et de ne
>> pas faire confiance aux règles du langage concernant la
>> précédence des opérateurs.



> Jusqu'un certain point (qui dépend au moins en partie du
> domaine d'application). Est-ce que tu écriras « x + *p »,
> ou « x + (*p) » ?



Là ce n'est pas pareil car un programmeur se rappelle
forcément que les opérateurs unaires sont prioritaires sur les
opérateurs binaires.



Donc, il y a des exceptions:-).

Et si le domaine utilise les expressions mathématiques> plus
ou moins compliquées :
> discrim = b*b - 4*a*c ;
> ou
> discrim = (b * b) - ((4 * a) * c) ;
> Dans ces cas-ci, la plupart des gens que je connais trouvent
> l'expression sans parenthèses plus lisibles.



Ici on peut se contenter de (b * b) - (4 * a * c) car la
multiplication est associative...



Est-elle ? (L'addition des flottants ne l'est pas, mais je ne
suis pas sûr pour la multiplication.)

Plus généralement, tous les mathématiciens s'attendent que la
multiplication ait précédance sur l'addition, et c'est le cas
dans tous les langages qui ont de la précédence.

Mon point, c'est simplement qu'il faut s'adapter aux conventions
et aux connaissances du milieu où on se trouve. Il n'y a pas de
règle absolue où tirer la ligne.

> (Note que je suis d'accord avec toi en général. Mais je
> reconnais qu'il y a des cas particuliers.)



Le problème c'est surtout le mélange des opérateurs logiques
et arithmétiques car on ne se rappelle jamais lesquels ont
priorité sur qui.



Dès qu'on sort du « courant », je suis d'accord qu'il faut des
parenthèses. Donc, entre && and || (parce que les expressions
avec les deux ne sont pas « courantes », au moins je l'espère).

Je me rappelle d'un bug, en C, lors d'un audit, dû à une
expression du genre :
a + x & 0x0000ffff
Ici on voit l'intention du programmeur qui veut "abattre" les
bits de fort poids de x et additionner le résultat à a. En
clair,
il veut faire : a + (x & 0x0000ffff).
Sauf que, en C, + est prioritaire sur & et que, donc,
l'expression est interprétée comme (a + x) & 0x0000ffff !!
Cette expression était utilisée pour construire les trames
d'un protocole. Je ne te dis pas les dégâts !



Certes. Mais ici, il sort du « courant » ; l'utilisation de & et
de | doivent être assez rare qu'on ne doit pas s'attendre à ce
que leur précédences soient connues « instinctivement ».

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Avatar
Mickaël Wolff
Wykaaa a écrit :

Ici on peut se contenter de (b * b) - (4 * a * c) car la multiplication
est associative...



Ça dépend. Avec des object boost::quaternion et boost::octonion, ce
n'est pas vrai ;)


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Wykaaa
Mickaël Wolff a écrit :
Wykaaa a écrit :

Ici on peut se contenter de (b * b) - (4 * a * c) car la
multiplication est associative...



Ça dépend. Avec des object boost::quaternion et boost::octonion, ce
n'est pas vrai ;)




Ca dépend effectivement du type des opérandes, tu as parfaitement raison
+1
Avatar
Fabien LE LEZ
On Sun, 31 Aug 2008 22:31:12 +0200, Mickaël Wolff
:

Ici on peut se contenter de (b * b) - (4 * a * c) car la multiplication
est associative...



Ça dépend. Avec des object boost::quaternion et boost::octonion, ce
n'est pas vrai ;)



T'es sûr ? Je ne connais pas les octonions, mais il me semble que
l'ensemble des quaternions est un corps (non commutatif), ce qui
signifie que + et * sont associatifs, et que * est distributif par
rapport à +.
Bon, évidemment, il y a les problèmes d'arrondis sur flottants, mais
pas plus avec boost::quaternion qu'avec float.
Avatar
Mickaël Wolff
Fabien LE LEZ a écrit :
T'es sûr ? Je ne connais pas les octonions, mais il me semble que
l'ensemble des quaternions est un corps (non commutatif), ce qui
signifie que + et * sont associatifs, et que * est distributif par
rapport à +.



<http://www.boost.org/doc/libs/1_36_0/libs/math/doc/octonion/html/boost_octonions/octonions/overview.html>
« The main novelty this time is that the multiplication is not only
not commutative, is now not even associative »


Bon, évidemment, il y a les problèmes d'arrondis sur flottants, mais
pas plus avec boost::quaternion qu'avec float.



Pas sûr (il peuvent utiliser des outils de calculs à grandeur
arbitraire), mais je n'ai pas plus regardé boost::octonion et
boost::quaternion, je n'en ai pas l'utilité.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Avatar
Fabien LE LEZ
On Mon, 01 Sep 2008 04:47:26 +0200, Mickaël Wolff
:

Bon, évidemment, il y a les problèmes d'arrondis sur flottants, mais
pas plus avec boost::quaternion qu'avec float.



Pas sûr (il peuvent utiliser des outils de calculs à grandeur
arbitraire)



À vue de nez, boost::quaternion étant un template, il utilise les
nombres que l'utilisateur choisit.
1 2