C Operator Precedence
Le tableau suivant répertorie la précédence et l'associativité des opérateurs en C. Les opérateurs sont listés de haut en bas, par ordre de précédence décroissante.
| Priorité | Opérateur | Description | Associativité |
|---|---|---|---|
| 1 |
++
--
|
Incrémentation et décrémentation suffixe/postfixe | Gauche à droite |
()
|
Appel de fonction | ||
[]
|
Indice 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 [note 1] | Droite à gauche |
+
-
|
Plus et moins unaires | ||
!
~
|
NON logique et NON bit à bit | ||
(
type
)
|
Conversion de type | ||
*
|
Indirection (déréférencement) | ||
&
|
Adresse de | ||
sizeof
|
Taille de [note 2] | ||
_Alignof
|
Exigence d'alignement (C11) | ||
| 3 |
*
/
%
|
Multiplication, division et reste | Gauche à droite |
| 4 |
+
-
|
Addition et soustraction | |
| 5 |
<<
>>
|
Décalage bit à bit vers la gauche et vers la droite | |
| 6 |
<
<=
|
Pour les opérateurs relationnels < et ≤ respectivement | |
>
>=
|
Pour les opérateurs relationnels > et ≥ respectivement | ||
| 7 |
==
!=
|
Pour les relations = et ≠ respectivement | |
| 8 |
&
|
ET bit à bit | |
| 9 |
^
|
OU exclusif bit à bit | |
| 10 |
|
|
OU inclusif bit à bit | |
| 11 |
&&
|
ET logique | |
| 12 |
||
|
OU logique | |
| 13 |
?:
|
Condition ternaire [note 3] | Droite à gauche |
| 14 [note 4] |
=
|
Affectation simple | |
+=
-=
|
Affectation par somme et différence | ||
*=
/=
%=
|
Affectation par produit, quotient et reste | ||
<<=
>>=
|
Affectation par décalage bit à bit vers la gauche et vers la droite | ||
&=
^=
|=
|
Affectation par ET, OU exclusif et OU inclusif bit à bit | ||
| 15 |
,
|
Virgule | Gauche à droite |
-
↑
L'opérande du préfixe
++et--ne peut pas être un cast de type. 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 cast de type : l'expression sizeof ( int ) * p est interprétée sans ambiguïté comme ( sizeof ( int ) ) * p , mais pas comme sizeof ( ( 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 relative à?:est ignorée. - ↑ Les opérandes de gauche des opérateurs d'affectation doivent être des expressions unaires (niveau 2 non-cast). 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 = d est 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 comme e = ( ( ( a < d ) ? ( a ++ ) : a ) = d ) , puis génèrent une erreur car elle est sémantiquement invalide.
Lors de l'analyse d'une expression, un opérateur listé sur une ligne donnée sera lié plus étroitement (comme s'il était entre parenthèses) à ses arguments que tout opérateur listé sur une ligne située en dessous. 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 (il peut y avoir plusieurs rangées d'opérateurs listés 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 concernant leurs opérandes.
La spécification de l'associativité est redondante pour les opérateurs unaires et n'est montrée qu'à titre d'exhaustivité : les opérateurs unaires préfixés s'associent toujours de droite à gauche ( sizeof ++* p est sizeof ( ++ ( * p ) ) ) et les opérateurs unaires postfixés 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 unaires postfixés : a. b ++ est analysé comme ( a. b ) ++ et non comme a. ( b ++ ) .
Références
- Norme C17 (ISO/CEI 9899:2018) :
-
- A.2.1 Expressions
- Norme C11 (ISO/IEC 9899:2011) :
-
- A.2.1 Expressions
- Norme C99 (ISO/CEI 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 des opérateurs lors de l'exécution.
| Opérateurs courants | ||||||
|---|---|---|---|---|---|---|
| affectation |
incrémentation
décrémentation |
arithmétique | logique | comparaison | accès membre | autres |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
Documentation C++
pour
la précédence des opérateurs C++
|