1.2. Java 2 , les instructions



Plan de ce chapitre:   ...........retour au plan général

1. instructions-bloc

1.1 Instruction
1.2 Instruction complète
1.3 Bloc-instruction
1.4 Visibilté dans un bloc-instruction


2. L'affectation

    2.1 Affectation simple
    2.2 Raccourcis et opérateurs d'affectation


3. Les conditions

    3.1 les instructions conditionnelles
    3.2 l'opérateur conditionnel


4. Les itérations

    4.1 Itération while
    4.2 Itération do...while
    4.3 Itération for


5.Break et continue

5.1 Interruption break
5.2 Rebouclage continue
 
6. Switch...case
 

7.try...catch
 


1. instructions-bloc

Une large partie de la norme ANSI du langage C est reprise dans Java.
 


Dans ce sous-chapitre nous expliquons les instructions Java en les comparant à pascal-delphi. Voici la syntaxe d'une instruction en Java :

1.1 instruction :

 

1.2 instruction complète :

Toutes les instructions se terminent donc en Java par un point-virgule " ; "
 
 

1.3 bloc - instruction composée :
L'élément syntaxique

est aussi dénommé bloc ou instruction composée au sens de la visibilité des variables Java.
 
 

1.4 visibilité dans un bloc - instruction  :

Exemple de déclarations licites et de visibilité dans 3 blocs instruction imbriqués :
int a, b = 12;
   { int x , y = 8 ;
     { int z =12;
            x = z ;
            a = x + 1 ;
        { int u = 1 ;
            y = u - b ;
         }
     }
   }

schéma d'imbrication des 3 blocs

Nous examinons ci-dessous l'ensemble des instructions simples de Java.
 

2. L'affectation

Java est un langage de la famille des langages hybrides, il possède la notion d'instruction d'affectation.
Le symbole d'affectation en Java est  " = ", soit par exemple :
 
x = y ; 
// x doit obligatoirement être un identificateur de variable.

 

2.1 Affectation simple

L'affectation peut être utilisée dans une expression :

soient les instruction suivantes  :
 

int a , b = 56 ;
a = (b = 12)+8 ;  // b prend une nouvelle valeur dans l'expression
a = b = c = d =8 ; // affectation multiple


simulation d'exécution Java :
 instruction  valeur de a   valeur de b
  int a , b = 56 ;   a = ???   b = 56
   a = (b = 12)+8 ;   a = 20   b = 12

2.2 Raccourcis et opérateurs d'affectation

Soit op un opérateur  appartenant à l'ensemble des opérateurs suivant  { +, - , * , / , % , << , >> , >>> , & , | , ^ }, il est possible d'utiliser sur une seule variable le nouvel opérateur op= construit avec l'opérateur op. Il s'agit plus d'un raccourci syntaxique que d'un opérateur nouveau (seule sa traduction en bytecode diffère : la traduction de a op= b devrait être plus courte en instructions p-code que a = a op b, bien que les optimiseurs soient capables de fournir le même code optimisé).
 
x op= y ;     signifie en fait  :   x = x op y

soient les instruction suivantes  :
 

int a , b = 56 ;
a = -8 ;
a += b ;  // équivalent à : a = a + b
b *= 3 ;  // équivalent à : b = b * 3


simulation d'exécution Java :
 instruction  valeur de a   valeur de b
  int a , b = 56 ;   a = ???   b = 56
  a = -8 ;   a = -8   b = 56
  a += b ;   a = 48   b = 56
  b *= 3 ;   a = 48   b = 168

Remarque :


 

3. Les conditions
 

3.1 les instructions conditionnelles

Syntaxe :

Schématiquement les conditions sont de deux sortes :


La définition de l'instruction conditionnelle de java est classiquement celle des langages algorithmiques; comme en pascal  l'expression doit être de type booléen (différent du C), la notion d'instruction a été définie plus haut.

Exemple d'utilisation du if..else (comparaison avec pascal)
Pascal-Delphi Java
var a , b , c : integer ;
....
if  b=0 then c := 1
else begin
c := a / b;
writeln("c = ",c);
end;
c := a*b ;
if c <>0 then c:= c+b
else c := a
int a , b , c ;
....
if ( b = = 0 ) c =1 ;
else {
c = a / b;
System.out.println("c = " + c);
}
if ((c = a*b) != 0) c += b;
else c = a;

Remarques :

 
L'instruction ambigüe :
if ( Expr1 ) if ( Expr2 ) InstrA ; else InstrB  ;
 
Le compilateur résout l'ambigüité ainsi :

if ( Expr1 ) if ( Expr2 ) InstrA ; else InstrB  ;


Exemple de parenthésage du else pendant
Pascal-Delphi Java
if  Expr1  then
begin 
  if  Expr2  then InstrA 
end
else InstrB 
if ( Expr1 ) {
     if ( Expr2 ) InstrA ; 
}
else InstrB 

 
 

3.2 l'opérateur conditionnel

Il s'agit ici comme dans le cas des opérateurs d'affectation d'une sorte de raccourci entre l'opérateur conditionnel if...else et l'affectation. Le but étant encore d'optimiser le bytecode engendré.

Syntaxe :

expression renvoie une valeur booléenne (le test), les deux termes valeur sont des expressions générales (variable, expression numérique, boolénne etc...) renvoyant une valeur de type quelconque.

Sémantique :
Exemple :

int a,b,c ;
c =   a = = 0  ?  b  a+1 ;
Si l'expression est true l'opérateur renvoie la première valeur, (dans l'exemple c vaut la valeur de b)
Si l'expression est false l'opérateur renvoie la seconde valeur (dans l'exemple c vaut la valeur de a+1).


Sémantique de l'exemple avec un if..else :

if (a = = 0) c = b;
else c = a+1;


question :

utiliser l'opérateur conditionnel pour calculer le plus grand de deux entiers. réponse : int a , b , c ; ....
c = a>b ? a : b ;
question : que fait ce morceau le programme ci-après ? int a , b , c ; ....
c = a>b ? (b=a) : (a=b) ;
réponse : a,b,c contiennent après exécution le plus grand des deux entiers contenus au départ dans a et b.
 

4. Les itérations

4.1.Itération while

Syntaxe :

Où expression est une expression renvoyant une valeur booléenne (le test de l'itération).

Sémantique :
Identique à celle du pascal (instruction algorithmique tantque .. faire .. ftant) avec le même défaut de fermeture de la boucle.
 

Exemple de boucle while
Pascal-Delphi Java
while  Expr  do Instr while ( Expr ) Instr ;
while  Expr  do
begin 
   InstrA ;
   InstrB ; ...
end
while ( Expr )
{
    InstrA ;
    InstrB ; ...
}

 

4.2.Itération do...while

Syntaxe :

Où expression est une expression renvoyant une valeur booléenne (le test de l'itération).

Sémantique :
"do Instr while ( Expr )" fonctionne comme l'instruction algorithmique répéter  Instr  jusquà non Expr.

Sa sémantique peut aussi être expliquée à l'aide d'une autre instruction Java while :
do Instr while ( Expr ) º  Instr ; while ( Expr ) Instr

Exemple de boucle do...while
Pascal-Delphi Java
repeat
   InstrA ;
   InstrB ; ...
until not Expr
do
{
    InstrA ;
    InstrB ; ...
} while ( Expr )

 

4.3.Itération for

Syntaxe :

Sémantique :
Une boucle for contient 3 expressions for (Expr1 ; Expr2 ; Expr3 ) Instr, d'une manière générale chacune de ces expressions joue un rôle différent dans l'instruction for. Une instruction for en Java (comme en C) est plus puissante et plus riche qu'une boucle for dans d'autres langages algorithmiques. Nous donnons ci-après une sémantique minimale :
 


"for (Expr1 ; Expr2 ; Expr3 ) Instr" fonctionne au minimum comme l'instruction algorithmique pour... fpour.

Sa sémantique peut aussi être approximativement(*) expliquée à l'aide d'une autre instruction Java while :
for (Expr1 ; Expr2 ; Expr3 ) Instr º Expr1
while ( Expr2
{ Instr ;
   Expr3
}
(*)Nous verrons au paragraphe consacré à l'instruction continue que si l'instruction for contient un continue cette définition sémantique n'est pas valide.
 

Exemples montrant la puissance du for
Pascal-Delphi Java
for i:=1 to 10 do
begin
   InstrA ;
   InstrB ; ...
end
for ( i = 1; i<=10; i++ )
{
    InstrA ;
    InstrB ; ...
i := 10; k := i;
while (i>-450) do
begin
  InstrA ;
  InstrB ; ...
  k := k+i;
  i := i-15;
end
for ( i = 10, k = i ;i>-450 ; k += i ,  i -= 15)
{
    InstrA ;
    InstrB ; ...
i := n;
while i<>1 do
  if i mod 2 = 0 then i := i div 2
  else i := i+1
for ( i = n ;i !=1 ; i % 2 == 0 ? i /=2 : i++);
 // pas de corps de boucle !


Montrons  exemple de boucle for dite boucle infinie :
for ( ; ; );   est équivalente à  while (true);

Voici une boucle ne possédant pas de variable de contrôle(f(x) est une fonction déjà déclarée) :
for (int n=0 ; Math.abs(x-y) < eps ; x = f(x) );

Terminons par une boucle for possédant deux variables de contrôle :
//inverse d'une suite de caractère dans un tableau par permutation des deux extrêmes
char [ ] Tablecar ={'a','b','c','d','e','f'} ;
for ( i = 0 , j = 5 ;  i<j ; i++ , j-- )
{ char car ;
   car = Tablecar[i];
   Tablecar[i ]= Tablecar[j];
   Tablecar[j] = car;
  }
dans cette dernière boucle ce sont les variations de i et de j qui contrôlent la boucle.
 
 

Remarques récapitulatives sur la boucle for en Java :


 

5. Break et continue
 

5.1.Interruption break

Syntaxe  :

Sémantique :
Une instruction break ne peut se situer qu'à l'intérieur du corps d'instruction d'un bloc switch (le switch est traité au paragraphe suivant), ou de l'une des trois itérations while, do..while, for.

Lorsque break est présente dans l'une des trois itérations while, do..while, for :
 


Exemple d'utilisation du break dans un for :
(recherche séquentielle dans un tableau)
   int [ ] table= {12,-5,7,8,-6,6,4,78,2};
   int elt = 4;
   for ( i = 0 ; i<8 ; i++ )
     if (elt= =table[i]) break ;
   if (i = = 8)System.out.println("valeur : "+elt+" pas trouvée.");
   else System.out.println("valeur : "+elt+" trouvée au rang :"+i);

 
Explications
Si la valeur de la variable elt est présente dans le tableau table if (elt= =table[i]) est true et break est exécutée (arrêt de la boucle et exécutionde if (i = = 8)... ). Donc, lorsque l'instruction  if (i = = 8)... est exécutée, soit la boucle s'est exécutée complètement (recherche infructueuse), soit le break l'a arrêtée prématurément (elt trouvé dans le tableau).
 
 

5.2.Rebouclage continue

Syntaxe  :

Sémantique :
Une instruction continue ne peut se situer qu'à l'intérieur du corps d'instruction de l'une des trois itérations while, do..while, for.

Lorsque continue est présente dans l'une des trois itérations while, do..while, for :
 


Exemple d'utilisation du continue dans un for :
Rappelons qu'un for s'écrit généralement  : 
for (Expr1 ; Expr2 ; Expr3 ) Instr
L'instruction continue présente dans une telle boucle for s'effectue ainsi :
  • exécution immédiate de Expr3
  • ensuite, exécution de Expr2
  • réexécution du corps de boucle.
int [ ] ta = {12,-5,7,8,-6,6,4,78,2}, tb = new int[8];
for ( i = 0, n = 0 ; i<8i++ , k = 2*n )
{ if ( ta[i] = = 0 ) continue ;
  tb[n] = ta[i];
  n++;
}

 
Explications
Si l'expression ( ta[i] = = 0 ) est true, la suite du corps des instructions de la boucle (tb[n] = ta[i];  n++;) n'est pas exécutée et il y a rebouclage du for .

Le déroulement est alors le suivant :


et la boucle se poursuit en fonction de la valeur de la condition de rebouclage.

Cette boucle recopie dans le tableau d'entiers tb les valeurs non nulles du tableau d'entiers ta.

Attention
Nous avons déjà signalé plus haut que  l'équivalence suivante entre un for et un while
for (Expr1 ; Expr2 ; Expr3 ) Instr º Expr1
while ( Expr2
{ Instr ;
   Expr3
}
valide dans le cas général, était mise en défaut si le corps d'instruction contenait un continue.

Voyons ce qu'il en est en reprenant l'exemple précédent. Essayons d'écrire la boucle while qui lui serait équivalente selon la définition générale. Voici ce que l'on obtiendrait :
for ( i = 0, n = 0 ; i<8i++ , k = 2*n )
{ if ( ta[i] = = 0 ) continue ;
  tb[n] = ta[i];
  n++;
}

i = 0; n = 0 ; 
while ( i<8
{ if ( ta[i] = = 0 ) continue ;
   tb[n] = ta[i];
   n++;
   i++ ; k = 2*n;
}

Dans le while le continue réexécute la condition de rebouclage i<8 sans exécuter l'expression  i++ ; k = 2*n; (nous avons d'ailleurs ici une boucle infinie). Une boucle while équivalente au for précédent pourrait être la suivante :
 for ( i = 0, n = 0 ; i<8i++ , k = 2*n )
{ if ( ta[i] = = 0 ) continue ;
  tb[n] = ta[i];
  n++;
}

 


 i = 0; n = 0 ; 
 while ( i<8
{ if ( ta[i] = = 0 )
  i++ ; k = 2*n;
     continue ;
   }
   tb[n] = ta[i];
   n++;
}

 
 

6. Switch...case

Syntaxe  :

bloc switch :

Sémantique :
La partie expression d'une instruction switch doit être une expression ou une variable du type byte, char, int ou bien short.
La partie expression d'un bloc switch doit être une constante ou une valeur immédiate du type byte, char, int ou bien short.

switch <Epr1> s'appelle la partie sélection de l'instruction : il y a évaluation de <Epr1> puis selon la valeur obtenue le programme s'exécute en séquence à partir du case contenant la valeur immédiate égal. Il s'agit donc d'un déroutement du programme dès que <Epr1> est évaluée vers l'instruction étiquetée par le case <Epr1> associé.

Exemples :
Java - source Résultats de l'exécution
int  x = 10;

switch (x+1)
   { case 11 : System.out.println(">> case 11");
      case 12 : System.out.println(">> case 12"); 
      default : System.out.println(">> default"); 
   }

>> case 11
>> case 12
>> default
int  x = 11;

switch (x+1)
   { case 11 : System.out.println(">> case 11");
      case 12 : System.out.println(">> case 12"); 
      default : System.out.println(">> default"); 
   }

>> case 12
>> default

Nous voyons qu'après que (x+1) soit évalué, selon sa valeur (11 ou 12) le programme va se dérouter vers case 11 ou case 12 et continue en séquence (suite des instructions du bloc switch)

Utilisée telle quelle, cette instruction n'est pas structurée et donc son utilisation n'est pas conseillée sous cette forme. Par contre elle est très souvent utilisée avec l'instruction break afin de simuler le comportement de l'instruction structurée case..of du pascal (ci-dessous deux écritures équivalentes) :
:
Exemple de switch..case..break
Pascal-Delphi Java
var x : char ;
....
case x of
 'a' : InstrA;
 'b' : InstrB;
 else InstrElse
end;
char x ;
....
switch (x)
{
    case 'a' : InstrA ; break;
    case 'b' : InstrB ; break;
    default : InstrElse;

Dans ce cas le déroulement de l'instruction switch après déroutement vers le bon case, est interrompu par le break qui renvoie la suite après la fin du bloc switch. Une telle utilisation correspond à une utilisation de if...else imbriqués (donc utilisation structurée) mais devient plus lisible que les if ..else imbriqués, elle est donc fortement conseillée dans ce cas.

En reprenant les deux exemples précédents :

Exemples :
Java - source Résultats de l'exécution
int  x = 10;

switch (x+1)
   { case 11 : System.out.println(">> case 11");
                     break;
      case 12 : System.out.println(">> case 12"); 
                     break;
      default : System.out.println(">> default"); 
   }

>> case 11
int  x = 11;

switch (x+1)
   { case 11 : System.out.println(">> case 11");
                     break;
      case 12 : System.out.println(">> case 12"); 
                     break;
      default : System.out.println(">> default"); 
   }

>> case 12

Programmes équivalents switch et if...else :
Java - switch Java - if...else
int  x = 10;

switch (x+1)
   { case 11 : System.out.println(">> case 11");
                     break;
      case 12 : System.out.println(">> case 12"); 
                     break;
      default : System.out.println(">> default"); 
   }

int  x = 10;

if (x+1= = 11)System.out.println(">> case 11");
else
if (x+1= = 12)System.out.println(">> case 12");
else
System.out.println(">> default"); 

 


 
 

7. try...catch

Nous reviendrons plus loin sur les exceptions et l'instruction try..catch. Nous donnons ici la syntaxe d'une version simple et nous indiquons que sa sémantique est semblable à celle du bloc try..except de Delphi. Sachons pour l'instant que Java dispose d'un mécanisme puissant présent dans les langages robustes Ada, C++, Delphi pour intercepter et traiter les erreurs ou incidents survenant dans un bloc d'instruction.

L'instruction try...catch sert à traiter de tels incidents, elle dispose d'un bloc try (pour les instructions à protéger)et d'un ou plusieurs blocs catch (pour divers genres de traitement en cas d'incidents).

try {
   BLOC à protéger
  }
   catch (TypeErreur1  Err1) {
      TRAITEMENT d'une erreur du type TypeErreur1
  }
catch (TypeErreur2  Err2) {
      TRAITEMENT d'une erreur du type TypeErreur2
  }
...
catch (TypeErreurX  ErrX) {
      TRAITEMENT d'une erreur du type TypeErreurX
  }

Ci-dessous une exemple permettant d'intercepter une erreur dans la division de l'enteir x par l'entier y :

Exemple de try...catch
Pascal-Delphi Java
var x , y : integer;
try
 x := 1;
 y := 0;
 Memo.lines.add("division ="+x div y);
except
  on Err : EIntError do begin
   Memo.lines.add("Calcul impossible.");
   Memo.lines.add(Err.message);
  end
end;
int x , y ;
try {
    x = 1;
    y = 0;
   System.out.println( "division ="+x/y);
  } 
catch (ArithmeticException Err) {
   System.out.println("Calcul impossible.");
   System.out.println(Err.getMessage());
  }