précédent|suivant| table des matières

expressions
Une expression est constituée d'une séquence d'opérateurs, d'opérandes et de parenthèses qui spécifient un calcul.
Les opérateurs ont quatre caractéristiques : arité, associativité, priorité, sémantique.
L'ordre d'évaluation des sous expressions n'est pas défini par le langage !

opérateur : arité

La plupart des opérateurs sont soit unaire soit binaire, et certains sont à la fois binaire et unaire.

opérateurs unaires :
 
&
adresse, ou référencement
*
indirection ou de déréférencement
+
plus unaire
-
moins unaire
~
complément bit à bit
!
négation logique
++
pré ou post incrément
--
pré ou post décrément
sizeof
taille de l'opérande (qui peut être un type) en octets
(type)
transtypage de l'opérande
new, delete
gestion mémoire C++

opérateurs binaires ou plus :
 
+, -, *,/, %
opérateurs arithmétiques % est le modulo
<<, >>
décalage à gauche, à droite
&, ^, |
et, ou exclusif, ou inclusif bit à bit
&&, ||
et, ou logique
=,*=,/*,%=, +=, -=, <<=, >>=, &=, ^=, |=
affectation

a op=bÛ a=a op b

<, >, <=, >=, ==, !=
opérateurs relationnels
. ->
sélecteur de composant direct et indirect
::
résolution de portée C++
a ? b : c
si a alors b sinon c
,
opérateur virgule : a,b,c évalue a, puis b puis c et a pour valeur la valeur de c. le résultat est une l-value
[ ]
a[b] Û *(a+b) a ou b doit être un pointeur , l'autre étant entier
( )
opérateur d'appel de fonction
.* ->*
déréférence un pointeur sur un membre de classe C++

 

opérateurs : associativité

Les opérateur sont associatifs à gauche ou associatifs à droite. Ssoient a, b, c trois opérandes et op un opérateur :

Les opérateurs unaires et les opérateurs d'affectation sont associatifs à droite, tous les autres opérateurs sont associatifs à gauche.

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).

exercices.

opérateurs : priorité

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 :
18
::
 
17
. []
()
++   -- 
dynamic_cast static_cast reinterpret_cast const_cast

appel de fonction
post
16
sizeof 
++   -- 
~ ! + - * & new delete
() 
unaires
pré

transtypage

15
->* .*
 
14
*, /, %
 
13
+ -
 
12
<< >>
 
11
< <= > >=
 
10
== !=
 
9
&
 
8
^
 
7
|
 
6
&&
 
5
||
 
4
?:
 
3
= *= /= %= += -= <<= >>= &= |= ^=
 
2
throw
 
1
,
 

opérateur : sémantique

opérateurs arithmétiques

Les opérateurs arithmétiques ont le sens habituel. Il faut cependant faire quelques remarques :

L'opérateur % entre deux opérandes entiers a pour valeur le reste de la division des deux entiers.

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 :

En revanche en C++, l’opérateur d’affectation a une évaluation non définie par le langage : le compilateur a le choix de l’évaluation de l’opérande gauche d’abord, ou de l’opérande droit d’abord.

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) :

Bien que se ressemblant fortement, ces deux opérateurs post et pré n’ont pas le même comportement : Donc ++++a est légal

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 :
 
a
b
!a
a&&b
a||b
1
1
0
1
1
1
0
0
0
1
0
1
1
0
1
0
0
1
0
0

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 :

1. a est évalué.
2. si a vaut 1 la valeur de l'expression est la valeur de b
3. sinon c'est la valeur de c.
opérateur sizeof

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 : 'Ã '


précédent|suivant| table des matières