Priorité et associativité
On a vu à la section précédente qu'on pouvait construire des expressions complexes impliquant plusieurs opérateurs et opérandes. On peut dès lors se demander comment la valeur d'expression très compliquée comme celle montrée ci-dessous est calculée; il s'agit du sujet de cette section.
Priorité
Les opérateurs Java sont classés selon un ordre de priorité. Toutes les expressions sont évaluées en suivant la règle de priorité des opérateurs. Pourquoi établir une telle règle ? Prenons un exemple pour comprendre. Soit l'expression suivante :
Quelle est la valeur de cette expression : 27 ou 13 ? Autrement dit, doit-on d'abord effectuer l'addition ou la multiplication ? En Java, tout comme en mathématique d'ailleurs, cette expression vaut 13 car il faut d'abord effectuer la multiplication avant l'addition. On dit que l'opérateur de multiplication a priorité sur l'opérateur d'addition. Voici comment le calcul est effectué, étape après étape :
7 + 2 * 3 = 7 + 6 = 13
On peut également représenter une expression par un arbre de l'expression. La figure 13 montre la représentation correspondant à l'exemple précédent. Pour évaluer l'expression, il faut partir du bas et effectuer les calculs en remontant.
Parenthèse
Si on veut forcer une certaine partie d'une expression à être évaluée en premier, il faut utiliser des parenthèses. En effet, toute expression mise entre parenthèses sera évaluée en premier. Ainsi, pour que l'expression précédente vaille 27, il faut écrire :
(7 + 2) * 3 = (7 + 2) * 3 = 9 * 3 = 27
Si une expression contient plusieurs sous-expressions entre parenthèses, elles seront évaluées de gauche à droite, de la plus intérieure à la plus extérieure. Prenons un exemple :
(3 + 2) * (6 / (4 - 2)) = (3 + 2) * (6 / (4 - 2)) = (3 + 2) * (6 / 2) = 5 * (6 / 2) = 5 * 3 = 15
La figure 14 montre l'arbre correspondant à cette expression. Pour l'évaluer, on part donc du bas vers le haut et de la gauche vers la droite.
Liste des opérateurs par priorité
La figure 15 liste les opérateurs Java selon leur priorité. Les opérateurs de niveau 1 sont les plus prioritaires et seront donc évalués en premier, tandis que ceux de niveau 15 sont les moins prioritaires et seront donc évalués en dernier.
Rappelez-vous bien qu'il est toujours possible de forcer une sous-expression à être évaluée en premier en la mettant entre parenthèses. Remarquez également que certains niveaux de priorité ne sont pas présents dans le tableau; en effet, nous n'avons pas encore vu tous les opérateurs de Java.
Niveau | Opérateur | Description | Exemple |
---|---|---|---|
1 | ++ |
incrémentation postfixe | x++ |
-- |
décrémentation postfixe | x-- |
|
2 | ++ |
incrémentation préfixe | ++x |
-- |
décrémentation préfixe | --x |
|
- |
changement de signe | -x |
|
+ |
signe + | +x |
|
! |
NON logique | ! x |
|
4 | * |
multiplication | x * y |
/ |
division | x / y |
|
% |
modulo | x % y |
|
5 | + |
addition | x + y |
- |
soustraction | x - y |
|
7 | < |
plus petit que | x < y |
<= |
plus petit ou égal à | x <= y |
|
> |
plus grand que | x > y |
|
>= |
plus grand ou égal à | x >= y |
|
8 | == |
égal | x == y |
!= |
différent | x != y |
|
10 | ^ |
OU logique exclusif | x ^ y |
12 | && |
ET logique | x && y |
13 | || |
OU logique inclusif | x || y |
14 | ? : |
opérateur conditionnel | x ? y : z |
15 | = |
affectation | x = y |
+= , -= , *= , /= , %= |
affectations composées | x += y |
Associativité
Intéressons-nous maintenant aux expressions complexes qui ne contiennent que des opérateurs ayant la même priorité. Prenons par exemple l'expression suivante :
La valeur de cette expression est-elle -4 ou 2 ? Doit-on évaluer l'expression de gauche à droite et commencer par 1 - 2
ou de droite à gauche et commencer par 2 - 3
? C'est la règle d'associativité qui dicte cela. Cette règle définit comment des expressions dont tous les opérateurs ont le même niveau de priorité sont évaluées.
L'opérateur de soustraction est associatif de gauche à droite, c'est-à-dire qu'il faut évaluer l'expression de l'exemple précédent de la première manière; sa valeur est donc -4.
1 - 2 - 3 = -1 - 3 = -4
La plupart des opérateurs sont associatifs de gauche à droite, sauf ceux des niveaux de priorité 2, 3, 14 et 15 qui sont associatifs de droite à gauche. En effet, pour l'affectation et les affectations combinées, on avait déjà vu que l'opérande de droite était évalué avant l'affectation. On pouvait par exemple écrire :
x = y = 2 + 3 = x = y = 5 = x = 5 = 5
La figure 16 montre l'arbre correspondant à cette dernière expression. On y voit bien qu'il faut évaluer l'expression en partant de l'addition qui se trouve tout à droite et on revient ensuite vers la gauche.
Expression complètement parenthésée
Pourquoi avoir défini une règle de priorité et une règle d'associativité ? C'est pour pouvoir écrire les expressions complexes de manière plus simple, plus lisible. En effet, on peut très bien se passer de ces règles et utiliser systématiquement des parenthèses pour bien rendre compte de l'ordre dans lequel les opérations doivent être effectuées.
En fait, il est toujours possible d'obtenir, à partir d'une expression, l'expression complètement parenthésée correspondante; c'est-à-dire que toutes les parenthèses sont explicitement présentes. Cette notation est par ailleurs tout à fait équivalente à la représentation en arbre. La figure 17 montre quelques expressions et leur forme complètement parenthésée correspondante.
Expression normale | Expression complètement parenthésée |
---|---|
7 + 2 * 3 |
(7 + (2 * 3)) |
1 - 2 - 3 |
((1 - 2) - 3) |
1 + 2 * 3 / 4 |
(1 + ((2 * 3) / 4)) |
3 * 5 - 2 + 1 - 8 / 2 * 3 |
((((3 * 5) - 2) + 1) - ((8 / 2) * 3)) |
-9 >= 6 && true || 7 * 3 < 2 |
((((-9) >= 6) && true) || ((7 * 3) < 2)) |