Précédence des opérateurs en C
Le tableau suivant liste la précédence et l'associativité des opérateurs C. Les opérateurs sont listés de haut en bas, par précédence décroissante.
| Précédence | Opérateur | Description | Associativité |
|---|---|---|---|
| 1 | ++ --
|
Incrémentation et décrémentation suffixe/postfixe | De gauche à droite |
()
|
Appel de fonction | ||
[]
|
Indiçage de tableau | ||
.
|
Accès aux membres de structure et d'union | ||
->
|
Accès aux membres de structure et d'union via pointeur | ||
(type){list}
|
Littéral composé(C99) | ||
| 2 | ++ --
|
Incrémentation et décrémentation préfixe[1] | De droite à gauche |
+ -
|
Plus et moins unaires | ||
! ~
|
NON logique et NON bit à bit | ||
(type)
|
Transtypage | ||
*
|
Indirection (déréférencement) | ||
&
|
Adresse de | ||
sizeof
|
Taille de[2] | ||
_Alignof
|
Exigence d'alignement(C11) | ||
| 3 | * / %
|
Multiplication, division et reste | De gauche à droite |
| 4 | + -
|
Addition et soustraction | |
| 5 | << >>
|
Décalage binaire gauche et droite | |
| 6 | < <=
|
Pour les opérateurs relationnels < et ≤ respectivement | |
> >=
|
Pour les opérateurs relationnels > et ≥ respectivement | ||
| 7 | == !=
|
Pour les opérateurs relationnels = et ≠ respectivement | |
| 8 | &
|
ET bit à bit | |
| 9 | ^
|
OU exclusif bit à bit (XOR) | |
| 10 | |
|
OU inclusif bit à bit (OR) | |
| 11 | &&
|
ET logique | |
| 12 | ||
|
OU logique | |
| 13 | ?:
|
Conditionnel ternaire[3] | De droite à gauche |
| 14[4] | =
|
Affectation simple | |
+= -=
|
Affectation par somme et différence | ||
*= /= %=
|
Affectation par produit, quotient et reste | ||
<<= >>=
|
Affectation par décalage binaire gauche et droite | ||
&= ^= |=
|
Affectation par ET, OU exclusif et OU binaires | ||
| 15 | ,
|
Virgule | De gauche à droite |
- ↑ L'opérande de
++et--préfixes ne peut pas être un transtypage. Cette règle interdit grammaticalement certaines expressions qui seraient de toute façon sémantiquement invalides. Certains compilateurs ignorent cette règle et détectent l'invalidité sémantiquement. - ↑ L'opérande de
sizeofne peut pas être un transtypage : l'expressionsizeof (int) * pest interprétée sans ambiguïté comme(sizeof(int)) * p, mais passizeof((int)*p). - ↑ L'expression au milieu de l'opérateur conditionnel (entre
?et:) est analysée comme si elle était entre parenthèses : sa précédence par rapport à?:est ignorée. - ↑ Les opérandes gauches des opérateurs d'affectation doivent être des expressions unaires (niveau 2, sans transtypage). Cette règle interdit grammaticalement certaines expressions qui seraient de toute façon sémantiquement invalides. De nombreux compilateurs ignorent cette règle et détectent l'invalidité sémantiquement. Par exemple,
e = a < d ? a++ : a = dest une expression qui ne peut pas être analysée à cause de cette règle. Cependant, de nombreux compilateurs ignorent cette règle et l'analysent commee = ( ((a < d) ? (a++) : a) = d ), puis donnent une erreur car elle est sémantiquement invalide.
Lors de l'analyse d'une expression, un opérateur qui figure sur une ligne sera lié plus étroitement (comme par des parenthèses) à ses arguments que tout opérateur figurant sur une ligne plus bas. Par exemple, l'expression *p++ est analysée comme *(p++), et non comme (*p)++.
Les opérateurs qui se trouvent dans la même cellule (plusieurs lignes d'opérateurs peuvent être listées dans une cellule) sont évalués avec la même précédence, dans la direction donnée. Par exemple, l'expression a = b = c est analysée comme a = (b = c), et non comme (a = b) = c en raison de l'associativité de droite à gauche.
Notes
La précédence et l'associativité sont indépendantes de l'ordre d'évaluation.
La norme elle-même ne spécifie pas les niveaux de précédence. Ils sont dérivés de la grammaire.
En C++, l'opérateur conditionnel a la même précédence que les opérateurs d'affectation, et les opérateurs préfixes ++ et -- ainsi que les opérateurs d'affectation n'ont pas de restrictions sur leurs opérandes.
La spécification de l'associativité est redondante pour les opérateurs unaires et n'est montrée que pour être complète : les opérateurs préfixes unaires s'associent toujours de droite à gauche (sizeof ++*p est sizeof(++(*p))) et les opérateurs postfixes unaires s'associent toujours de gauche à droite (a[1][2]++ est ((a[1])[2])++). Notez que l'associativité est significative pour les opérateurs d'accès aux membres, même s'ils sont regroupés avec les opérateurs postfixes unaires : a.b++ est analysé (a.b)++ et non a.(b++).
Références
- Norme C23 (ISO/IEC 9899:2024) :
- A.3.1 Expressions
- Norme C17 (ISO/IEC 9899:2018) :
- A.2.1 Expressions
- Norme C11 (ISO/IEC 9899:2011) :
- A.2.1 Expressions
- Norme C99 (ISO/IEC 9899:1999) :
- A.2.1 Expressions
- Norme C89/C90 (ISO/IEC 9899:1990) :
- A.1.2.1 Expressions
Voir aussi
Ordre d'évaluation des arguments d'un opérateur à l'exécution.
| Opérateurs courants | ||||||
|---|---|---|---|---|---|---|
| affectation | incrémentation décrémentation |
arithmétique | logique | comparaison | membre accès |
autre |
|
|
|
|
|
|
|
|
Documentation C++ pour Précédence des opérateurs en C++
|