Les expressions du langage
Comme beaucoup d'autres langages, Java manipule bien sûr des expressions, et donc des opérateurs (de différentes natures). Nous allons donc, au travers de ce chapitre, étudier l'ensemble des opérateurs du langages ainsi que les différentes natures d'expressions du langage.
Les expressions numériques
Les opérateurs que je nomme numériques, calculent tous un résultat numérique. Cependant, il faut bien noter qu'il y a plusieurs opérateurs qui ont le même nom (par exemple les opérateurs nommés +) mais qui s'appliquent sur des types différents : l'exemple qui suit vous fixera mieux les idées.
int i = 4 + 3; |
Dans ce cas, l'opérateur + prend deux entiers (chacun sur 32 bits) et rend un entier, lui aussi représenté sur 32 bits. |
double d = 3.2 + 1.84; |
Ici, l'opérateur d'addition, prend deux opérandes de types décimaux (représenté chacun sur 64 bits) et retourne un flottant du
même type. |
En règle générale, il y a autant d'opérateurs + que de types numériques. Mais la question est alors de savoir ce qui doit se passer si l'on tente d'ajouter un entier avec un décimal. Il est clair que le résultat doit aussi être décimal. En conséquence, c'est le deuxième cas donné en exemple qui s'applique, avec une phase implicite de conversion de la valeur entière en valeur décimale. Cette phase de conversion est plus connue sous le nom de casting. Toujours en règle générale, un cast est implicitement effectué s'il est nécessaire, et s'il n'y a pas de perte de précision sur la valeur numérique. Il est donc clair qu'un cast implicite d'un décimal en un entier ne serra jamais possible. Il faut alors explicitement demander le cast. L'exemple qui suit vous donne la syntaxe à utiliser : il suffit de préfixer la valeur par le type, mit entre parenthèses.
int i = 4 + (int)3.8; |
Dans ce cas, l'opérateur + prend deux entiers (chacun sur 32 bits) et rend un entier, lui aussi représenté sur 32 bits. Le résultat est 7 car 3.8 donne 3 après le
cast. |
Une fois cela assimilé il faut comprendre encore deux ou trois petites choses. Un opérateur, par définition, prend un certain nombre d'expressions (ou opérandes) pour calculer une valeur qui pourra à son tour être utilisée par un autre opérateur. En d'autres termes, une expression est constituée d'opérateurs et de sous expressions, comme le montre l'exemple suivant.
Finalement, la variable i de type entier sur 32 bits, contiendra la valeur 36. En effet, des règles de priorité sur les opérateurs, impliques qu'un opérateur va primer sur un autre selon les cas de figure. Donc en reprenant l'exemple suivant, la valeur est calculée en faisant la somme du produit de 3 par 6 et de 2 par 9 (soit 18 + 18). Se reporter à la table de précédence des opérateurs pour plus d'informations.
Nous trouvons notamment, comme opérateurs numériques, la somme (+), la soustraction (-), la multiplication (*), la division (/). Ils s'appliquent tous sur des opérandes numériques quelconques (entières ou flottantes). On en trouve aussi qui s'applique uniquement à des opérandes entières : le reste de la division entière (%), le et bit à bit (&), le ou inclusif bit à bit (|) ou encore le ou exclusif bit à bit (^), le décalage à gauche, bit à bit, (<< équivalent à un multiplication par 2) et le décalage à droite (>> équivalent à une division entière par 2).
Nous trouvons aussi deux opérateurs permettant d'incrémenter (++) ou de décrémenter (--) d'une unité une variable numérique (entière ou flottante). Il faut noter que ces deux opérateurs sont unaires et surtout que l'on peut les utiliser en préfixe ou en postfixe d'une variable. Dans ce cas l'action sémantique n'est pas la même. Pour comprendre cela, regardons l'exemple qui suit.
Fichier "Essai.java"
public class essai {
static public void main(String arg[]){
int a = 10;
System.out.println("a = "+a+";\t(++a*2) = "+(++a*2)+";\ta = "+a+";");
a = 10;
System.out.println("a = "+a+";\t(a++*2) = "+(a++*2)+";\ta = "+a+";");
}
}
Résultats
a = 10; (++a*2) = 22; a = 11;
a = 10; (a++*2) = 20; a = 11;
Bon si vous avez toujours pas fuit votre écran devant ces quelques lignes indéchiffrables, je vais pouvoir tenter de vous expliquer ce qu'elles font, et pourquoi elles le font. Donc, comme dans le cas de votre première application Java, le programme commence par la définition d'une classe (ici nommée essai). Ensuite, on y spécifie notre seule méthode, qui doit servir de point de départ à l'application : on la nomme donc main (nous reviendrons sur la nécessité du static plutard, sachez seulement qu'il est obligatoire pour la méthode main, idem pour le public). La ligne qui suit sert à créer une variable nommée a à laquelle on affecte la valeur 10. Ensuite, tout se complique, mais
ça reste du domaine du compréhensible. System est un objet prédéfinit en Java qui permet d'avoir accès au système (comme son nom l'indique). Cet objet contient dans ces attributs un autre objet nommé
out qui lui donne accès au flot de données de sortie de l'application, et on applique la méthode
println qui y place un message (passé en paramètre) ainsi qu'un retour chariot. Toute la difficulté réside dans le fait de comprendre le message. Ce dernier commence par une chaîne de caractères suivit d'un opérateur +. Il est bien clair, qu'il ne s'agit donc pas de l'opérateur dont on a déjà parlé : celui-ci réalise la concaténation de deux chaînes de caractères (nous en reparlerons). Je vous sens alors choqué : ce qui suit n'est pas une chaîne de caractères. Mais par contre, en Java, tous peut s'exprimer en ce type. Comme il n'y a pas, à priori, de perte de données, le casting d'un nombre en une chaîne de caractères est donc accepté, et le tour est joué. A force de pratiquer, ces petites astuces vous deviendrons familières. Ce n'est pas finit, on trouve ensuite une autre chaîne de caractères contenant les deux caractères "\t" : ils servent à placer une tabulation dans la chaîne. Ensuite on trouve notre fameux opérateur ++ (et oui, vous l'aviez déjà oublié, mais il est toujours le sujet principal de notre débat) : lors de sa première apparition, il est utilisé en préfixe, tandis qu'il l'est en postfixe dans sa seconde apparition. Si vous regardez les résultats (ceux affichés par les
System.out.println, vous vous apercevrez que la valeur calculée n'est pas la même, bien que l'incrémentation de la variable a soit faites. La raison en est trés simple : dans le premier cas, on incrémente la variable, et on finit le calcul. Dans le second cas, on effectue le calcul, puis ensuite, on n'oublie surtout pas d'incrémenter la variable. Faites les calculs à la main et vous verrez que vous trouverez alors les mêmes valeurs. Est-ce maintenant plus clair ? Si oui, sachez que l'opérateur -- fonctionne de même (bien qu'il effectue une décrémentation). Si au contraire ce n'est pas le cas, faites une pause, prenez un café, et reprenez ce paragraphe.
Les expressions booléennes
De même qu'il existe des expressions qui calculent des résultats numériques, il en existe qui calculent des résultats booléens (c'est à dire un résultat pouvant être interprété soit comme vrai, soit comme faux). Il existe donc des opérateurs booléens nécessaires à la construction des ces expressions. Nous y trouvons notamment des prédicats (autre façon de nommer ces opérateurs) de comparaison numérique (==, il en existe autant que de types numériques et des conversions peuvent exister), de différenciation (!=), d'infériorité (strictes (<) ou non (<="))," de supériorité (>et >=). Nous trouvons aussi le ou logique (||) et le et logique (&&) qui prennent tous deux des opérandes booléennes. Il existe encore l'opérateur unaire (qui prend uniquement une seule opérande) de négation (!).
boolean egal=(3==4);
int a=3,b=4;
boolean diff=((a<b)||(a>b)); |
La variable egal vaut donc à cet instant
false. lavariable diff sera elle vraie soit si a est plus petiteque b, soit si elle est plus grande (donc différente).Sinon diff sera faux. |
boolean bool1=(3==4);
boolean bool2=(3.0==4.0); |
Il est bien clair que dans ces deux cas, les opérateursde comparaisons ne sont les mêmes. Un prend deuxopérandes entières, l'autres deux
opérandesdécimales. |
Les expressions retournant des chaînes de caractères
Comme nous l'avons dit précédemment, un opérateur agissant sur des chaînes de caractères, permet des constituer des expressions de type chaîne de caractères. L'opérateur + permet donc de concaténer deux chaînes pour en former une nouvelle (nous avons déjà vu un exemple d'utilisation il y a quelques paragraphes).
Fichier "Essai.java"
public class Essai {
static public void main(String arg[]){
String a="Le debut et ...", b=" la fin !!!", c=a+b;
System.out.println(c);
}
}
Résultat :
Le debut et ... la fin !!!
Une chose utile à se rappeler est que toute valeur en Java (pas forcément numérique) peut s'afficher sous forme de chaîne de caractères. L'expression ("a "+1) aura donc pour valeur "a 1".
Les affectations et les opérateurs associés
Une affectation est aussi une expression qui calcule une valeur et l'affecte à une variable. La valeur d'une telle expression est celle calculée dans la partie droite de l'affectation (les opérateurs d'affectation étant binaires infixes). L'opérateur permettant de définir une affectation sera noté =.
Fichier "Essai.java"
public class essai {
static public void main(String arg[]){
int a,b;
System.out.println("b = "+(a=10)*2+";\ta = "+a+";");
}
}
Résultat :
b = 20; a = 10;
A partir de là, et dans un souci de convivialité, d'autres opérateurs d'affectation sont définis. Le principe reste quasiment le même, à la différence que la valeur qui va être affectée à la variable, est calculé en fonction de l'état de cette variable. Pour mieux se fixer les idées regardons le tableau suivant qui fixe les équivalences entre ces nouveaux opérateurs et l'opérateur d'affectation classique.
a += b; |
a = a + b; |
a -= b; |
a = a - b; |
a *= b; |
a = a * b; |
a /= b; |
a = a / b; |
a %= b; |
a = a % b; |
a &= b; |
a = a & b; |
a |= b; |
a = a | b; |
a ^= b; |
a = a ^ b; |
a >>= b; |
a = a >> b; |
a <<= b; |
a = a <<b; |
Les autres opérateurs du langage
Il existe encore d'autres opérateurs dont une petite description sera donnée dans le tableau suivant. Nous seront, par la suite amenés à en reparler.
new |
Opérateur d'allocation mémoire
int tableau[]=new int[10]; |
Il sera étudier plus en détail dans le chapitre consacré à la
programmation orientée objet. [] Accès aux éléments d'un tableau
b = tableau[indice];
Attention, les indices d'un tableau commencent toujours à partir de zéro. Si un tableau contient dix éléments, les indices varirons donc entre 0 et 9. . Opérateur de traversé, utilisé pour accéder aux champs (attributs et méthodes) des objets.
int value = objet.champQuelconque;
?: L'opérateur conditionnel : c'est le seul opérateur ternaire (qui prend trois opérandes) du langage. Il permet de calculer une expression plutôt qu'une autre selon la valeur booléenne d'une autre expression. L'expression qui sert à choisir quelle autre expression calculer se place devant le point
d'interrogation. Celle qui sera calculée si le test est vrai doit être mise entre le point
d'interrogation et les deux points, la dernière, après les deux points.
boolean b = true;
// plein de code Java
int value = b ? 3*a+z : 3*a-k;
, Cet opérateur permet de constituer une expression à partir de deux sous-expressions. Ceci est utile dans les constructions du langage qui n'accepte qu'une unique expression à un endroit particulier (nous en verrons). L'exemple qui suit sera expliqué en détail dans le capitre suivant.
while((step=f(x),a-=step)>0) g(a);
Précédence des opérateurs
Comme vous l'avez certainement déjà remarqué, il est possible de se servir de parenthèses pour fixer l'ordre d'évaluation des sous-expressions formant une expression Java. Ainsi, les expression 3*2+4 et 3*(2+4) n'auront pas les mêmes valeurs (10 et 18). Mais attention tout de même : l'utilisation abusive des parenthèses rend très rapidement un code illisible. Dans le but de ne pas arriver dans de telles situations, sachez que des règles de priorités ont étaient définies sur les opérateurs. Le tableau suivant fixe cet ordre : du plus prioritaire à l'opérateur de séquencement (,) qui est le moins prioritaire. Dorénavant, utilisez donc bien les parenthèses.
[ ] |
! ++ -- |
* / % |
+ - |
<<>> |
== != <<=>>= |
& |
^ |
| |
&& |
|| |
?: |
= += -= *= /= %= <<=>>= &= ^= |= |
, |
Nous venons donc de survoler l'ensemble des opérateurs, ainsi que quelques expressions du langage. Ils nous seront fort utile pour calculer des valeurs (numériques ou autres) dans nos programmes. Mais cela ne fait pas tout, il nous faut aussi pouvoir définir le comportement général du programme. Dans ce but, nous allons nous attacher, dans le chapitre suivant, à étudier les instructions du langage.
|