3. Les expressions et les
opérateurs
3.1 Type de
résultat, transtypage.
Tous
les opérateurs calculent un résultat. Quand les opérandes dans un operateur
sont de
même type, le type du
résultat coïncide avec le type
des opérandes (exception:le type du
résultat intégral moins de 4 bytes - par
exemple byte, short est toujours converti vers type int)
Si les
opérandes n'ont pas le même
type, avant
l'exécution on fait une conversion de type automatique d'un des
opérandes vers
le type de l'autre (si c'est possible). Si cette conversion n'est pas
possible
une faute de compilation est générée. Cette
conversion de type porte le nom transtypage implicite
(ou automatique).
Le transtypage automatique peut s'appliquer quand il n'y a pas de
risque de perte d’information.
Les six
flèches noires dans la figure 3.1 indiquent les conversions sans
perte
d'information. Le trois flèches pointillées indiquent
celles pouvant
souffrir d'une perte de précision.

Fig. 3.1. Transtypage
automatique autorisé en Java
public class Oper {
public static void main(String arg[]){
int k,i1=4, i2 = 5;
double f1 =5.0,f2=5.0;
f1= i1/i2 +i1/f2;
}
}
• L'expression i1/i2 se fait sans transtypage
est le résultat est 0
• Dans l'expression i1/f2, i1 est convertis en
double est le résultat est 0.8
• Le résultat final est de type double
transtypage explicite (caste)
int i = (int)56.4;
byte sh = (byte)456;
public class Oper {
public static void main(String arg[]){
int in;
long ln=123L;
double db = 34.5;
in = ln;
//type mismatch
in = db;
//type mismatch
in = (int)ln;
//ok
in = (int)db;
//ok
}
}
public class Oper {
public static void main(String arg[]){
byte b1,b2=2,b3=3;
b1 = 5;
//ok!
b1 = b2+b3;
// type mismatch
b1 =
(byte)(b2+b3); //ok!
b1=130;
//type mismatch
b1=(byte)130;
//ok!
}
}
3.2 La
priorité et l'associativité des opérateurs
|
Opérateurs
|
Associativité
|
|
() [] .
++(postfixé) --(postfixé)
|
––>
|
|
+(unaire) -(unaire) ++(préfixé) --(préfixé)
~ ! cast
new
|
<––
|
|
* / %
|
––>
|
|
+ -
|
––>
|
|
<< >> >>>
|
––>
|
|
< <= >
>=
instanceof
|
––>
|
|
== !=
|
––>
|
|
&
|
––>
|
|
^
|
––>
|
|
|
|
––>
|
|
&&
|
––>
|
|
||
|
––>
|
|
?:
|
––>
|
|
= += -= *= /= %= <<= >>= >>>= &= |= ^=
|
<––
|
Tab. 3.1. Les opérateurs de Java et leurs priorités
3.3 Les
opérateurs arithmétiques
• + addition;
• - soustraction,
• * multiplication,
• / division.
De plus, il existe un opérateur de modulo noté % qui peut
porter sur des entiers ou sur des flottants. Avec des entiers, il
fournit le reste de la division entière de son premier
opérande par son second. Avec des flottants il fonction de la
même manière mais les résultats sont approximatifs.
public class Oper {
public static void main(String arg[]){
System.out.println("11%4:\t"+11%4);
System.out.println("23%6:\t"+23%6);
System.out.println("-11%3:\t "+
-11%3);
System.out.println("12.5%3.5:\t
"+12.5%3.5);
System.out.println("-15.2%7.5:\t
"+-15.2%7.5);
}
}
public class Oper {
public static void main(String arg[]){
int i= 20000000;
System.out.println
("overloading: "+i*i); //dépassement de capacité
float x = 1e30f ;
float y ;
y = x*x ;
System.out.println (x + " a
pour carre : " + y) ;
float zero = 0.f ; //
division flottante par zero
y=4.5f;
float z = y/zero ;
System.out.println (y + "
divise par 0 = " + z) ;
System.out.println("l'oppose
de " + y + " = "+ -y);
float z1 = z/y ;
System.out.println (z + "/"
+ y + " = " + z1) ;
System.out.println
("0./0.:"+zero/zero);
}
}
·
Dans le cas des
entiers,
le dépassement de capacité n’est jamais
détecté. On se contente de
conserver les bits les moins significatifs du résultat.
·
Dans le cas des
entiers, la
division par zéro (par / ou par %) conduit à une erreur
d’exécution.
·
En Java, aucune
opération sur les
flottants ne conduit à un arrêt de
l’exécution (pas même une division par zéro
!). En effet, les flottants sont codés en respectant les
conventions IEEE 754.
Celles-ci imposent qu’il existe une valeur particulière
pour représenter
l’infini positif, l’infini négatif et non
calculable (NaN- not a number).
opérateurs
d’incrémentation (++ et --)
public class Oper {
public static void main(String arg[]){
int k, m=3;
k = m++; //m
vaut 4, k vaut 3 - valeur ancienne
m=3;
k = ++m; //m
vaut 4, k vaut 4 - valeur novelle
m=3;
k = m--; //m
vaut 2, k vaut 3 - valeur ancienne
m=3;
k = --m; //m
vaut 2, k vaut 2 - valeur novelle
k= (m++)++;
//erreur! m++ n'est pas constante
}
}
L’opérateur
d’affectation (=)
public class Oper {
public static void main(String arg[]){
int k, m=3,z=4,p;
p = k =(m = 2) *(z =
4);
//m vaut 2
//z vaut 4
//k vaut 8
//p vaut 8
p = k = 2;
//k vaut 2, p vaut 2
p = (k = 2);
//la
même chose
(p = k) = 2;
//erreur
– l'opérande de gauche (p=k) est constante
}
}
3.4 Les
opérateurs de comparaisons logique
• == Rend true si les deux
opérandes sont égaux.
• != Rend true si les deux
opérandes sont différents.
• < Rend true si
l'opérande de gauche est strictement inférieur à
l'opérande de droite.
• <= Rend true si
l'opérande de gauche est inférieur ou égal
à l'opérande de droite.
• > Rend true si
l'opérande de gauche est strictement supérieur à
l'opérande de droite.
• >= Rend true si
l'opérande de gauche est supérieur ou égal
à l'opérande de droite.
public class Oper {
public static void main(String arg[]){
System.out.println("25>11:"+(25>11)+ "\t17<=8: "+(17<=8));
}
}
3.5
Opérateurs logiques sur des booléens
• && Opérateur
ET (AND). Le résultat est true, si les deux opérandes ont
la valeur true.
• || Opérateur OU (OR).
Le résultat est true, si l'un des deux opérandes a la
valeur true.
• ! Opérateur NON
(NOT). Le résultat est true si le seul opérande a la
valeur false.
public class Oper {
public static void main(String arg[]){
boolean
b1=true,b2=true,b3=false,b4=false;
System.out.println("true
&& true: "+(b1&&b2)+ "\t true && false:
"+(b1&&b3));
System.out.println("true ||
false: "+(b1||b3)+ "\t false || false: "+(b3&&b4));
System.out.println("!true:
"+!b1+"\t !false: "+!b3);
}
}
3.6
Opérateurs logiques bit à bit
• & Opérateur ET
(AND).
• | Opérateur OU (OR).
• ~ Opérateur NON (NOT).
• >> Décalage
arithmétique à droite.
• >>> Décalage
logique à droite. Le signe de l'opérande de gauche n'est
pas gardé. On introduit toujours un zéro à gauche.
• << Décalage
à gauche. C'est une multiplication par 2
public class Oper {
public static void main(String arg[]){
System.out.println("7&8:
"+(7&8)+"\t7|8: "+(7|8));
System.out.println("~7: "+ (~7));
System.out.println("7 << 2:
"+(7 << 2));
System.out.println("-7 >>
2: "+(-7 >> 2)+"\t -7 >>> 2: "+(-7 >>>
2));
}
}
3.7
Opérateur ternaire
public class Oper {
public static void main(String arg[]){
int res,a=4, b=9;
res = a>b?a:b;
}
}