Le b.a.-ba de la syntaxe JAVA

Merci à Mirabelle Nebut, rédactrice principale de ce document, ainsi qu’à Jean-Christophe Routier.

Sommaire

1.Les types primitifs

Deux types spéciaux:

  • type null (référence non initialisée)
  • type void

Les types classiques : le type booléen, le type caractère et …

  • les booléens en Java boolean, contient les valeurs {true, false};
  • les caractères : le type Java char utilise le codage Unicode sur 16 bits ;
    ex : 'a'

… les types numériques : types entier et réel.

Les entiers

Les entiers signés sont représentés en complément à deux :

  • les octets type Java byte sur 8 bits, intervalle $[-2^7,2^7-1]$ avec $2^7 = 128$, ex : 15
  • les entiers courts type Java short sur 16 bits, intervalle $[-2^{15},2^{15}-1]$ avec $2^{15} = 32768$, ex : 32189
  • les entiers type Java int sur 32 bits, avec $2^{31} \sim 2.10^9$, ex : 1235234567
  • les entiers longs type Java long sur 64 bits, avec $2^{63} \sim 9.10^{18}$, suffixés par L, ex: 2147483648L

Les réels

Pour les réels ou flottants Java adopte le codage en virgule flottante de la norme IEEE754 en simple et double précision. Virgule flottante signifie qu’on représente un réel sous la forme $\mathtt{+/- m * b}$ ^ $\mathtt{e}$ où $\mathtt{+/-}$ est le signe, $\mathtt{m}$ la mantisse (entière), $\mathtt{b}$ la base et $\mathtt{e$} l’exposant (qui fait “flotter” la virgule). La norme IEEE754 impose la représentation plus précise :

  • $\mathtt{(-1)^s * (1+M) * 2^{E-127}}$ sur 32 bits (simple précision)
  • $\mathtt{(-1)^s * (1+M) * 2^{E-1023}}$ sur 64 bits (double précision) où $\mathtt{s}$ est le bit de signe (sur 1 bit donc), l’exposant $\mathtt{E}$ est codé sur 8 bits ou 11 bits, et la mantisse $\mathtt{M}$ est codée sur 23 bits ou 52 bits. Dans la syntaxe Java :
  • simple précision type Java float, littéraux suffixés par F, intervalle $[-10^{-38},-10^{38}] \cup [10^{-38},10^{38}]$, ex : 112.2e-45F, -34E-555F, 3.14F;
  • double précision type Java double, littéraux suffixés optionnellement par D, intervalle
    $[-10^{-308},-10^{308}] \cup [10^{-308},10^{308}]$, ex: 1.34e56D, 3.14

2.Les opérateurs et prédicats de base

Opérateurs numériques :

  • addition +, soustraction -;
  • multiplication *, division entière ou réelle /;
  • moins unaire -;
  • modulo %: x%y = x-(x/y)*y, surtout utilisé pour les entiers.

On a aussi les « raccourcis » des post/pré incrément/décrément:

  • x++: post-incrément, délivre la valeur de x puis ajoute 1 à x;
  • --x: pre-décrément, soustrait 1 à x puis délivre la valeur de x;
  • symétriquement ++x et x--.

NB: l’opérateur de puissance n’est pas un opérateur de base. On utilisera pow de la classe java.Math.

Opérateurs booléens:

  • et logique &&, ou logique ||: ces opérateurs sont paresseux;
  • et logique &, ou logique |: ces opérateurs sont stricts (non paresseux);
  • ou exclusif ^ (strict);
  • négation logique !.

Prédicats de comparaison de base:

  • les classiques < <= > >=;
  • l’égalité ==;
  • la différence !=.

3.Les commentaires

// toute la ligne est en commentaire
/* commentaire entre balises */

4.La déclaration de variables

Dans la mesure du possible commenter et donner des noms parlants. De la forme :

$\langle$type$\rangle$ $\langle$nom_var$\rangle$ $[$= $\langle$valeur_init$\rangle$ $]$ ;

où $\langle$type$\rangle$ est à remplacer par un type comme int ou boolean, $\langle$nom_var$\rangle$ par un nom de variable, $\langle$valeur_init$\rangle$ par une valeur initiale, etc. Les $[$ $]$ délimitent les parties optionnelles.

ex:

int nbJoueurs = 3; // nombre de joueurs
int y; //  ordonnée
boolean fini = false; // le jeu n'est pas fini

On peut faire des déclarations en cascade, à éviter.
Syntaxe des identificateurs Java: $($lettre | _ $)($lettre | _ | chiffre$)*$

NB: Java différencie les majuscules des minuscules (sensible à la casse).

5.Les instructions

Ne pas oublier les ; de fin d’instruction.

L’affectation

De la forme: $\langle$nom_var$\rangle$ = $\langle$expression$\rangle$ ;

ex:

y = x+3;
fini = ! fini;

Attention: ne pas confondre l’opérateur d’affection = et l’opérateur de comparaison == !!

Les structures de contrôle

La séquence

Ou comment exprimer ensuite…. Deux instructions séparées par ; sont exécutées en séquence.

Le bloc d’instructions

Un bloc est délimité par { et }. Toute variable déclarée dans un bloc a une portée (ou visibilité) limitée à ce bloc (n’est connue que dans ce bloc). Toute séquence d’instructions doit être incluse dans un bloc.

{ int i = 5; } i = 6; // erreur

Structures conditionnelles

Le si… alors… s’écrit:

if ($\langle$condition$\rangle$)
    $\langle$code_vrai$\rangle$

ce qui peut donner:

if (x == y) 
  z = 0;
if (x == y) {
   z = 0;
}

Le si… alors… sinon… s’écrit:

if ($\langle$condition$\rangle$)
     $\langle$code_vrai$\rangle$
else
    $\langle$code_faux$\rangle$

ce qui peut donner:

if (x%2 == 0) 
  x = x / 2;
else
  x = x + 1;
if (x == y) {
  fini = true; x = 0;
} else fini = false;

Les structures itératives

Ou comment exprimer la répétition en boucle.

La boucle tant que

while ($\langle$condition$\rangle$)
    $\langle$corps$\rangle$

1. si la condition est fausse, 
     la boucle termine
   sinon 2. exécuter le corps
         3. retour en 1.

ex:

{
int x = 2;
boolean fini = x < 0; // fin de boucle
int nb = 0; // nb tours de boucle
while ( ! fini ) {
   x = x-1;
   nb = nb + 1;
   fini = x < 0;
}}

invariant de boucle: x + nb = 2
sortie de boucle x = -1 $\Longrightarrow$ nb = 3

{
int x = 3;
int nb = 0; // nb tours de boucle
while ( x > 0 ) {
   x = x-1;
   nb = nb + 1;
}}

invariant de boucle: x + nb = 3
sortie de boucle x = 0 $\Longrightarrow$ nb = 3

La boucle for

for ($\langle$initialisation$\rangle$;$\langle$condition$\rangle$;$\langle$expr_progression$\rangle$)
     $\langle$corps$\rangle$

1. effectuer l'initialisation
2. si la condition est fausse le for termine
   sinon 3. effectuer le corps 
         4. évaluer l'expression
         5. retour en 2. 

ex:

for (i=0, j=0; i<3; i=i+1) 
   j = j+2;
i = 0; j = 0;
while (i<3) {
   j = j+2;
   i = i+1;
}

invariant j = i*2
sortie de boucle i = 3 $\Longrightarrow$ j=6

Possibilité de déclarer localement les « variables de boucles » lors de l’initialisation:

int j = 2;
for (int i=0; i<3; i=i+1) 
   j = j+2; 
Boucle faire … jusqu’à

do
    $\langle$corps$\rangle$
while ($\langle$condition$\rangle$)

équivalent à

$\langle$corps$\rangle$
while ($\langle$condition$\rangle$)
    $\langle$corps$\rangle$

donc idem boucle tant-que mais en testant la condition à la fin. Le corps de la boucle est nécessairement exécuté au moins une fois.

6.Les tableaux

Les tableaux permettent de stocker un nombre prédéfini d’objets d’un même type. On aura par exemple un tableau de 10 entiers, un tableau de 2 booléens … Pour utiliser un tableau il faut le déclarer puis le créer.

Déclaration d’un tableau

Pour déclarer un tableau on précise le type de ses éléments, pas son nombre de cases (le nombre d’éléments qu’il contient):

$\langle$type_elt$\rangle$ [] $\langle$nom_tab$\rangle$ ;

ex:

int[] tab1;
boolean[] tab2;

Création d’un tableau de taille fixée

La création d’un tableau $\langle$nom_tab$\rangle$ déjà déclaré se fait en utilisant new et en précisant sa taille (son nombre de cases):

$\langle$nom_tab$\rangle$ = new $\langle$type_elt$\rangle$ [ $\langle$expr_nb$\rangle$ ];

La taille n’est pas nécessairement connue statiquement (c.-à-d. qu’elle peut n’être connue qu’à l’exécution du programme).
ex:

tab1 = new int[10];
tab2 = new boolean[x+3];

Alors tab1 contient 10 cases numérotées de 0 à 9. tab2 contient x+3 cases.

Taille

La taille d’un tableau fait partie des propriétés fournies par Java: si $\langle$nom_tab$\rangle$ est un tableau déjà créé, alors

$\langle$nom_tab$\rangle$.length
est son nombre d'éléments.

ex: tab1.length vaut 10.

Initialisation à la déclaration

On peut initialiser un tableau lors de sa déclaration par une liste de valeurs séparées par des ,, entourée d’accolades. Dans ce cas il n’y pas besoin de créer explicitement le tableau par new.

ex:

int[] tab = {1,2,3,4,12};

On a ici tab.length = 5.

Accès indexé

Les éléments d’un tableaux sont numérotés (on dit indexés ou indicés) à partir de 0. Si $\langle$nom_tab$\rangle$ est un tableau déjà créé, alors on accède à son ième élément par:

$\langle$nom_tab$\rangle$[$\langle$expr_indice$\rangle$]

ex: tab1[0], … ,tab1[9] sont des expressions correctes, mais tab1[10] est une expression incorrecte. On écrira par exemple:

tab1[O] = 1;
tab1[1] = 2;
int x = 5;
tab1[x-3] = 3;
tab1[x-2] = 4;
....
tab1[9] = 10;

Attention: l’indice doit être compris entre 0 inclus et tab.length exclu. On écrira donc typiquement:

 for (int i=0; i<tab.length; i++) {
     tab[i] = i+1;
 }

Itération sur les élements d’un tableau

Lorsque l’on souhaire parcourir un tableau et réaliser une manipulation sur chacun de ses éléments on peut utiliser la syntaxe (dite « à la for-each ») suivante:

float[] tab = ... ;
float somme  = 0;
for (float element : tab) { 
   // element prend successivement toutes les valeurs
   somme = somme + element;
}

qui équivaut à

float[] tab = ... ;
float somme  = 0;
for (int i=0; i<tab.length; i++) {
   somme = somme + tab[i];
}