La plupart des opérateurs sont soit unaire soit binaire, et certains sont à la fois binaire et unaire.
opérateurs unaires :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opérateurs binaires ou plus :
|
|
|
|
|
|
|
|
|
a op=bÛ a=a op b |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Les opérateur sont associatifs à gauche ou associatifs à droite. Ssoient a, b, c trois opérandes et op un opérateur :
exemple :
a = b = c Û a =( b
= c)
a + b + c Û (a +
b) + c
opérateurs : ordre d’évaluation
L’ordre d’évaluation des sous-expressions est indéfini dans le langage. Evidemment chaque compilateur fera un choix, habituellemnt de gauche à droite … mais pas toujours !
int a=0, b ;
(a=1)=(b=a) ;
Dans la deuxième ligne … l’évaluation de gauche à droite donne a=1 et b=1, alors que l’évaluation de droite à gauche donne a=0 et b=0 !
int i=1 ;
v[i]=++i ; a également un résultat
qui dépend de l’ordre d’évaluation des opérandes de
l’affectation !
Seuls les opérateurs , (opérateur virgule) && et || assurent que l’opérande de gauche est évalué avant l’opérande de droite. ( ne pas confondre l’opérateur , avec la virgule qui sépare les paramètres d’une fonction, pour laquelle l’ordre d’évaluation est indéfini).
La stratégie d'évaluation des opérandes dépend des compilateurs... elle peut être gauche-droite (gcc) ou dépendre de l'associativité des opérateurs : droite-gauche pour les opérateurs d'affectation et gauche-droite pour les autres opérateurs ( Borland C++ builder3).
Si on essaie d'évaluer l'expression 1 + 2 * 3, la seule règle d'associativité à gauche donne comme résultat 9 alors que l'habitude donne 7. Ceci est du à des règles implicites de priorité.
Les priorités sont données par la table suivante :
|
|
|
|
() ++ -- dynamic_cast static_cast reinterpret_cast const_cast |
appel de fonction |
|
++ -- ~ ! + - * & new delete () |
pré transtypage |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opérateurs arithmétiques
Les opérateurs arithmétiques ont le sens habituel. Il faut cependant faire quelques remarques :
opérateurs d'affectation
En général, dans les langages de programmation, l’opérateur d’affectation = défini de la façon suivante :
Les instructions suivantes sont légales, mais vraisemblablement à éviter :
b=1+(a=2);
//
b vaut 3
(b=1)=(b=3)
//
b vaut 3
b=0;
(b+=1)=(b+=1)
//
b vaut 2
a
= 5; b = 10;
(a
= b) = (b = a) // le résultat dépend de l’ordre d’évaluation
// a=10 et b=10 pour une évaluation Gauche-Droite
// a=5 et b=5 pour une évaluation Droite-Gauche
Les opérateurs op= permettent une écriture condensée, et une optimisation du code généré par le compilateur : x op = y Û x = x op y
L’opérande de gauchede l’affectation doit être une G-Valeur c’est à dire une référence à un espace mémoire où on peut ranger la valeur de l’opérande de droite.
opérateurs d'incrémentation
Les opérateurs unaires ++ et -- peuvent se trouver devant ou derrière l'opérande : on parle de pré ou post incrémentation (ou décrémentation) :
En revanche ++a++ est illégal alors que (++a)++ l’est ! Il faut également noter que l’opérateur post est aussi en général plus coûteux en temps de calcul que l’opérateur pré.
opérateurs de bits
Les opérateurs de bits ont des opérandes entiers.
~ x a pour valeur un entier de même type
que x, tous les bits de x sont inversés.
&, ^, et | sont des opérateurs binaires et,
ou exclusif et ou.
Les opérateurs << et >> sont les opérateurs
de décalage à gauche et à droite des bits de l'opérande
de gauche ; l'opérande de droite indique de combien de positions
sont décalés les bits. Les bits insérés sont
égaux à 0 et les bits qui dépassent sont perdus.
opérateurs d'égalité, et de relation
==, !=, <, <=, >, >= renvoient vrai (1) si les opérandes
satisfont la relation et faux (0) sinon.
opérateurs logiques
Les opérateurs logiques && et || représentent
les opérateurs etpuis et oualors : le premier opérande
est évalué, et le second n'est évalué que si
le résultat demeure indéterminé après l'évaluation
du premier opérande. Les opérateurs logiques sont définis
par la table suivante :
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
opérateur virgule
Une suite d'expressions séparées par des virgules est évaluée en évaluant toutes les expressions de gauche à droite. La valeur de l'expression est la valeur de l'expression la plus à droite.
opérateur ?:
C'est l'opérateur conditionnel : a?b:c a une valeur qui est évaluée de la façon suivante :
L'opérateur sizeof retourne la taille en octets d'une expression, ou d'un spécificateur de type :
sizeof (int) a pour
valeur 4. (les parenthèses autour du nom du type sont obligatoires)
sizeof 65000 a pour
valeur 4
sizeof 3.1415 a pour
valeur 8 (implanté en double)
opérateurs de transtypage
Le transtypage peut être explicite ou implicite et dans ce cas on parle de coercition ou de promotion :
Le transtypage explicite peut s'écrire de deux façons : type (expression) ou (type) expression.
exemple :
int
i, a; float x;
i=
int(3.1415); // transtypage explicite
i=3.14
//
coercition de réel en entier
// 3.14 est contraint en 3
x=a;
// promotion de entier en réel
Quelques écritures à éviter bien que licites :
int
a, b;
char
c;
int
t[5]={1,2,3,4,5};
a=1;
b=3+a++; // b vaut 4
cout<<a++;
//
affiche 2 puis a vaut 3
a=2;
a=t[a++]; // a vaut 4
b=(a=3)+++a
//
b vaut 7
cout<<(b=(a=3)+(++a));
//affiche
7
c='a'+'b';
//
c a pour valeur le caractère dont le code est égal au
// code de a plus le code de b : 'Ã
'