Dans cette étude, nous allons aborder les concepts fondamentaux de la programmation, tels que les types de données, les variables, les constantes, les commentaires, ainsi que les instructions de branchement et de boucles.
La plus petite unité indépendante d'un programme en Java est l'instruction. Chaque instruction doit se terminer par le symbole (;). En langage naturel, cela correspond à une phrase. L'instruction est constituée d'identificateurs et de symboles.
Les identificateurs servent à donner des noms
aux variables, types, constantes, méthodes, etc... La règle à utiliser
pour les identificateurs est décrite ci-dessous.
Un identificateur doit débuter par une lettre,
qui peut être suivie d'une séquence de lettres ou de chiffres. Ils ne peuvent
en aucun cas commencer par un chiffre. De plus, ils ne peuvent pas contenir
des caractères de ponctuation ni d'espace. Notez que le sens des termes
"lettres" et "chiffres" est plus large en Java que dans beaucoup d'autres langages.
Une lettre est définie comme l'un des caractères ' A' . . . ' z' , ' a' . .
. ' z' , '_' , ou n'importe quel caractère Unicode
représentant une lettre dans une langue quelconque. Par exemple, un utilisateur
français ou allemand peut employer des caractères accentués, tels que "à"
ou "ê", dans un nom de variable. De
même, les lecteurs grecs peuvent utiliser µ. Tous les caractères d'un
nom de variable sont significatifs, ainsi que la casse de chaque caractère (minuscule
ou majuscule). La longueur possible d'un nom est théoriquement illimitée.
exemples d'identificateurs: carré_entier _9
var3Salut
étudiantidentificateurs non valables: Hello!
7val 9_Premier+deuxième
un deux
En java, les instructions sont regroupées à l'aide d'accolades { }. Le groupe de caractères placé entre ces accolades est appelé bloc, ou bloc d'instructions. C'est, en fait, un ensemble d'instructions. Les blocs peuvent être imbriqués.
Les commentaires de java, comme ceux de la plupart des langages de programmation, n'apparaissent pas dans le programme exécutable. Vous pouvez donc ajouter autant de commentaires que vous le souhaitez sans craindre de gonfler la taille du code compilé. Java propose trois types de commentaires. Le plus courant est //, qui débute un commentaire allant jusqu'à la fin de ligne.
Lorsque des commentaires plus longs sont nécessaires, il est possible de placer un // au début de chaque ligne, mais il est plus courant d'employer /* et */ pour délimiter un long commentaire.
Pour en savoir plus sur les commentaires et sur Javadoc
Java est un langage fortement typé. Cela signifie que le type de chaque variable doit être déclaré. Il existe huit types primitifs (prédéfinis) en java. Six d'entre eux sont des types numériques (quatre types d'entiers et deux types de réels à virgule flottante); à ceux-ci s'ajoutent le type caractère char, utilisé pour le codage Unicode (voir la section consacrée au type char), et le type boolean, pour les valeurs booléennes (vraies ou fausses).
Les types entiers représentent les nombres sans partie décimale. Les valeurs négatives sont autorisées. Java dispose des quatre types.
Type occupation en mémoire Intervalle (limites incluses) int
short
long
byte4 octets
2 octets
8 octets
1 octet- 2147483648 à 2147483647 (un peu plus de 2 milliards)
- 32768 à 32767
- 9223372036854775808L à 9223372036854775807L
-128 à 127
Tous les types entiers représentent des nombres signés; il n'existe pas de mot clé unsigned (c'est à dire non signé) comme c'est le cas avec C et C++. Il faut savoir que, sous java, l'intervalle valide des types de nombres entiers ne dépend pas de la machine sur laquelle s'exécute le code.
Le suffixe des entiers longs est L
(par exemple, 40000000000L). Le préfixe des entiers hexadécimaux 0x (par exemple, OxCAFE). |
Les types à virgule flottante expriment les nombres réels disposant d'une partie décimale. Il existe deux types de réels :
Type | Occupation en mémoire | Intervalle |
---|---|---|
float |
4 octets 8 octets |
Environ ± 3.40282347E+38F (6 ou 7 décimales significatives) Environ ± 1.79769313486231570E+308 (15 chiffres significatifs) |
Le terme double indique que les nombres de ce type ont une précision deux fois supérieure à ceux du type float (on les appelle parfois variables à double précision). On choisira de préférence le type double dans la plupart des applications. La précision limitée de float se révèle insuffisante dans de nombreuses situations. Les nombres de type float ont pour suffixe F, par exemple 3. 402F. Les nombres à décimales exprimés sans ce suffixe F sont toujours considérés comme étant du type double.
if (x == Double.NaN) // n'est jamais vrai
Toutes les valeurs "pas un nombre" sont considérées comme distinctes. Pour cela vous devez employer la méthode isNaN() de la classe enveloppe Double pour réaliser ce genre de test :
if (Double.isNaN(x)) // vérifier si x est "pas un nombre"
Pour en savoir plus sur les classes enveloppes.
§
Attention : Les nombres à virgule flottante ne conviennent pas aux calculs financiers, dans lesquels les erreurs d'arrondi sont inadmissibles. La commande System.out.println(2.0-1.1) produit 0.899999999999999, et non 0.9 comme vous pourriez le penser. Ces erreurs d'arrondi proviennent u fait que les nombres à virgule flottante sont représentés dans un système de nombres binaires. Il n'existe pas de représentation binaire précise de la fraction 1/10, tout comme il n'existe pas de représentation précise de la fraction 1/3 dans un système décimal. Si vous voulez obtenir des calculs numériques précis sans erreurs d'arrondi, utilisez la classe BigDecimal.
Avant tout, précisons que l'apostrophe est employée pour spécifier une constante char. Par exemple, 'H' est un caractère, et "H" une chaîne contenant un seul caractère. Ensuite, le type char désigne des caractères en représentation Unicode. Le système Unicode est un système de caractères "larges", codés sur deux octets, car il est prévu pour gérer tous les caractères de toutes les langues écrites. Cela offre un jeu de 65 536 caractères (parmi lesquels environ 35 000 sont employés actuellement). C'est évidemment un jeu beaucoup plus riche que le jeu ASCII/ANSI codé sur un octet - et n'offrant que 255 caractères. Ainsi, les caractères comme ' a ' , ' 1 ' et ' [ ' représentent des caractères Unicode valides. Les caractères Unicode peuvent s'exprimés en notation hexadécimale, de '\u0000' à '\uFFFF'. Le préfixe \u désigne une valeur Unicode, spécifiée par les quatre chiffres hexadécimaux qui suivent.
En plus de la séquence d'échappement \u indiquant le codage d'un caractère Unicode, java autorise l'emploi de séquences d'échappement pour les caractères spéciaux.
Code d'échappement | Désignation | Valeur Unicode |
---|---|---|
\b |
Retour arrière |
\u0008 |
Malheureusement, au fil du temps, ce qui devait arriver arriva. Unicode a grossi au-dela des 65535 caractères, principalement du fait de l'ajout d'un très grand jeu d'idéogramme utilisés pour le chinois, le japonais et le coréen. Le type char à 16 bits est désormais insuffisant pour décrire tous les caractères Unicode.
Nous allons expliquer comment ce problème a été résolu en Java, et ce depuis Java 5.0. Un point de code est une valeur de code associée à un caractère dans un schéma de codage. Dans la norme Unicode, les points de code sont écrits en hexadécimal et préfixés par U+, par exemple U+0041 pour le point de code de la lettre 'A'. Unicode possède des points de code regroupés en 17 plans de codes. Le premier, appelé plan multilingue de base, est constitué de caractères Unicode "classiques" ayant les points de code U+0000 à U+FFFF. Seize autres plans, ayant les ppoints de code U+10000 à U+10FFFF, contiennent les caractères complémentaires.
Le codage UTF-16 permet de représenter tous les points de code Unicode dans un code de longueur variable. Les caractères du plan multilingue de base sont représentés sous forme de valeurs de 16 bits, appelées unités de code. Les caractères complémentaires sont englobés sous forme de paires consécutives d'unités de code. Chacune des valeurs d'une paire de codage se situe dans une plage inutilisée de 2048 octets du plan multilingue de base, appelé zone de remplacement (U+D800 à U+DBFF pour la première unité de code, de U+DC00 à U+DFFFF pour la deuxième unité de code).
Ceci est assez intéressant, car vous pouvez immédiatement dire si une unité de code procède à un codage sur un seul caractère ou s'il s'agit de la première ou de la deuxième partie d'un caractère complémentaire. Par exemple, le symbole mathématique pour l'ensemble des entiers ∑ a le point de code U+1D56B et est codé par les deux unités de code U+D835 et U+DD6B.
En Java, le type char décrit une unité de code en codage UTF-16.
§
Il est recommandé de ne pas utiliser le type char dans vos programmes, à moins d'être à l'aise dans la manipulation des unités de code UTF-16. Il vaux mieux presque traiter les chaînes sous forme de type de données abstraits.
Le type boolean (booléen) peut posséder deux valeurs, false (faux) ou true (vrai). Il est employé dans des opérations de test logique utilisant les opérateurs relationnels supportés par Java (et par la plupart des langages de programmation).
Info C++ : En C, il n'existe pas de type booléen. Cependant, par convention, une valeur de zéro signifie faux et toute autre valeur signifie vrai.
Attention : En Java, la conversion est interdite entre les
booléens et les nombres - même par transtypage
§
Une variable ne doit quelquefois contenir qu'un jeu de valeurs limité. Vous pouvez par exemple vendre des vêtements ou des pizzas en quatre formats : petit, moyen, grand et très grand. Bien sûr, ces formats pourraient être codés sous forme d'entiers 1, 2, 3 et 4 ou des caractères P, M, G et T. Mais cette configuration est sujette à erreur. Une variable peut trop facilement contenir une valeur éronnée (comme 0 ou m).
enum Taille {Petit, Moyen, Grand, TrèsGrand};
Nous pouvons, dès lors, déclarer des variable de ce type là :
Taille t = Taille.Moyen;
Une variable de type Taille ne peut contenir que l'une des valeurs listées dans la déclaration de type ou la valeur spéciale null qui indique que la variable n'est définie sur aucune valeur.
Nous retrouverons le type énuméré plus en détail lors d'une étude prévue à cet effet.
§
Si la précision des types de base entier et flottant n'est pas suffisante, vous pouvez avoir recours à des classes très utiles du paquetage java.math, appelées BigInteger et BigDecimal. Ces classes permettent de manipuler des nombres comprenant une longue séquence arbitraire de chiffres.
BigInteger grand = BigInteger.valueOf(100);
BigInteger addition = grand.add(autre); // addition = grand + autre
BigInteger calcul = addition.multiply(grand.add(BigInteger.valueOf(2))); // calcul = addition * (grand + 2)
Pour la classe BigInteger, il existe également la méthode mod() pour renvoyer le reste de la division.
§
Java, comme le C++ et les langages fondés sur le Pascal, demande que le type de chaque variable soit déclaré. Vous déclarez une variable en spécifiant d'abord son type, puis son nom (identificateur). Voici quelques exemples de déclarations :
Le point-virgule est nécessaire, car une déclaration est une instruction Java complète. Il est possible de déclarer plusieurs variables sur une même ligne en utilisant le séparateur virgule comme le montre la dernière ligne de l'exemple.
Après avoir déclarée une variable, il est important de l'initialiser à l'aide d'une instruction d'affectation. Vous ne devriez jamais utiliser une variable non initialisée (et le compilateur vous en empêcherait en cas de besoin). L'affectation d'une variable déclarée se fait à l'aide du symbole d'égalité "=", précédé à gauche par le nom de la variable et suivi à droite par une expression Java représentant la valeur appropriée.
Voici un exemple d'affectation à une variable caractère :
Une agréable facilité de Java permet de déclarer et d'initialiser simultanément une variable en une seule instruction, comme suit :
Précisons enfin que Java permet de déclarer des variables n'importe où dans le code, mais qu'une variable ne peut être déclarée qu'une seule fois dans un même bloc de méthode.
Pour prendre un exemple, Java n'éprouve pas de difficulté à multiplier un entier par un réel double; le résultat sera de type double. Plus généralement, toutes les opérations binaires effectuées sur des valeurs numériques de types différents seront acceptées, et traitées de la manière suivante :
Ce mécanisme se poursuit jusqu'aux plus petits types entiers: dans l'ordre, int, short et byte. En revanche, il arrive inévitablement que l'on veuille considérer un double comme un entier. Les conversions numériques sont possibles, mais peuvent bien entendu entraîner une perte d'information. Cette perte d'information est possible lorsque la conversion est effectuée au moyen d'un transtypage. La syntaxe du transtypage consiste à donner le type cible à la variable. Exemple :
Dans ce cas, la variable nx prend la valeur 9, car le transtypage d'une valeur réelle en valeur entière élimine la partie décimale.
Java autorise certaines conversions permettant d'affecter la valeur d'une variable à une variable d'un autre type sans transtypage explicite. Les cas permis sont les suivants :
byte -> short -> int -> long-> float -> double.
.
ce qui signifie que l'on peut toujours affecter une variable d'un type à une variable d'un autre type situé plus à droite dans cette liste.
En Java, le mot clé final sert à désigner une constante. Voici un exemple :
Le mot clé final signifie que vous affectez la variable une seule fois, et une fois pour toutes. Par convention, les noms des constantes sont entièrement en majuscules.
Il est plus courant de créer une constante qui est accessible à plusieurs méthodes de la même classe. Les constantes de ce genre sont appelées généralement constantes de classe. On définit une constante de classe à l'aide des mots clés static final. Voici un exemple utilisant une constante de classe :
Notez que la définition de la constante de classe apparaît en dehors de la méthode main. Ici, l'emploi du spécificateur d'accès public signifie que d'autres méthodes java extérieures à la classe peuvent également utiliser la constante.
Java permet d'utiliser cinq opérateurs pour accomplir des opérations arithmétiques de base.
Opérateurs Signification Exemple + Addition 3 + 4 - Soustraction 5 - 7 * Multiplication 5 * 5 / Division 14 / 7 % Modulo 20 % 7
L'opérateur de division / indique une division entière si les deux arguments sont des entiers et une division en virgule flottante dans les autres cas. Le reste d'une division entière (équivalent de la fonction modulo) est représenté par le symbole %. Par exemple, 15/4 donne 3; 15%2 donne 1 et 11.0/4 donne 2.75 (4 est une valeur entière; il faut que les types soient identiques pour effectuer l'opération, donc le 4 est transformé en 4.0; promotion vers le type supérieur). Il est possible d'employer des opérateurs arithmétiques dans une initialisation de variable :
Exercices |
Soit les déclarations suivantes : int i, j, k=5; double d, e=1.5, f=2.3; char car='A'; |
En utilisant le débogueur, donnez le résultat de chacune des opérations exécutées dans la partie ci-dessous en essayant de comprendre les traitements réalisés. La partie déclaration et la partie traitement doit se trouver dans la méthode principale main. Vous allez obtenir des erreurs de compilations. Essayez de remédier au problème. (Initialisation de j à 3). |
i = k/j; i = k%j; i = k/j + k%j; d = f/e; d = j/e + k/f; d = f/e + k/j; i = j/e + k/f; i = f/e + k/j; car = car + 1; i = car + 2; car = 'B' + ('a'-'A'); |
Comme en C et en C++, les opérateurs arithmétiques peuvent être utilisés en combinaison avec l'opérateur d'affectation pour simplifier l'écriture d'une affectation. Par exemple, l'instruction :
(En règle générale, placez l'opérateur arithmétique à gauche du signe =, par exemple *= ou %=)
Expression Signification x += y x = x + y x -= y x = x - y x *= y x = x * y x /= y x = x / y
L'opérateur d'affectation est un opérateur comme les autres, il est donc possible d'avoir des affectations successives comme cela est montré dans l'exemple ci-dessus, ( j prend la valeur 3 et i prend la valeur de j ).
Les programmeurs savent évidemment qu'une des opérations les plus courantes effectuées sur une variable numérique consiste à lui ajouter ou à lui retrancher 1. Suivant les traces de C et de C++, Java offre des opérateurs d'incrémentation et de décrémentation x++ ajoute 1 à la valeur courante et x-- retranche 1 à cette valeur. Ainsi, cet exemple :
donne à n la valeur 13. Comme ces opérateurs modifient la valeur d'une variable, ils ne peuvent pas être appliqués à des nombres. Par exemple, 4++ n'est pas une instruction valide. Ces opérateurs peuvent en réalité prendre deux formes; vous avez vu la forme "suffixe", où l'opérateur est situé derrière le nom de la variable : n++. Il peut également être placé en préfixe : ++n. Dans les deux cas, la variable est incrémentée de 1. La différence entre ces deux formes n'apparaît que lorsqu'elles sont employées dans des expressions. Lorsqu'il est placé en préfixe, l'opérateur effectue d'abord l'addition; en suffixe, il fournit l'ancienne valeur de la variable.
voici d'autres exemples en sachant qu'avant chaque opération i=3 et j=15
Opération équivalent Résultats i = ++j;
i = j++;
i++;
j = ++i + 5;
j = i++ + 5;j = j+1; i = j;
i = j; j = j+1;
i = i+1;
i = i+1; j = i+5;
j = i+5; i = i+1;i=16 et j=16
i=15 et j=16
i=4
i=4 et j=9
j=8 et i=4
Java permet d'utiliser plusieurs opérateurs pour effectuer des comparaisons entre des variables et des littéraux ou d'autres types d'informations dans un programme. Ces opérateurs s'utilisent dans des expressions qui retournent la valeur booléenne true ou false, suivant que la comparaison effectuée est avérée ou non.
Un littéral est un nombre, du texte ou une autre information
qui représente une valeur.
.
Opérateur Signification Exemple ==
!=
<
>
<=
>=
!
&&
|| Egal à
Différent de
Inférieur à
Supérieur à
Inférieur ou égal à
Supérieur ou égal à
Négation (ne pas)
Et
Ou inclusif x == 3
x != 3
x < 3
x > 3
x <= 3
x >= 3
! (x >3)
(3<x) && (x<7)
(x<3) || (x>7)
Les opérateurs && et || sont évalués de manière optimisée (en court-circuit). Cela signifie que dans l'expression (A && B) la valeur de l'expression B n'est pas calculée si l'expression A a pu être évaluée à false (puisque le résultat final serait false de toute façon).
Info : II ne faut pas oublier que Java utilise des symboles différents
pour l'affectation et le test d'égalité.
Info C++ : Java élimine le risque de bogue que peut entraîner l'emploi
du signe = à la place de
==. Une ligne qui commence par if (k = 0)
ne sera même pas compilée, car le résultat du test sera 0,
qui ne peut pas être converti en boolean.
Exercices |
Soit les déclarations suivantes : int a=5, b=2, i, j; boolean k; |
En utilisant le débogueur, donnez le résultat de chacune des opérations exécutées dans la partie ci-dessous en essayant de comprendre les traitements réalisés. La partie déclaration et la partie traitement doit se trouver dans la méthode principale main. Vous allez obtenir une erreur de compilations. Remédiez au problème. |
j = 3 * (i = a+b) ; i *= 7; j %= 3 ; i *= j += 2 ; i = a + ++b ; i = a++ + b ; i = a+++b ; k = a==7 && b!=2 ; k = !(!(a<=5) && !(b>2)) ; k = a==5 || b==0; k = 0<a<100<b; |
Pour en savoir plus sur d'autres
opérateurs
§
Comme tout langage de programmation, Java supporte les instructions conditionnelles et les boucles afin de déterminer le flux d'exécution (ou flux de contrôle). Nous commencerons par étudier les instructions conditionnelles avant de passer aux boucles. Nous terminerons par l'instruction switch, qui peut être employée lorsque vous devez tester les nombreuses valeurs possibles d'une même expression.
Avant d'examiner les structures de contrôle, vous devez savoir ce qu'est un bloc. Un bloc, ou instruction composée, est un groupe d'instructions simples délimité par une paire d'accolades. Les blocs déterminent la portée des variables. Ils peuvent être imbriqués à l'intérieur d'un autre bloc. Voici un bloc imbriqué dans le bloc de la méthode main :
La variable n fait partie du bloc de la méthode main et n'est pas connue à l'extérieur de celle-ci.
La plus simple des instructions conditionnelles de Java prend la forme :
if (condition) instruction;
mais vous souhaiterez souvent exécuter plusieurs instructions lorsqu'une condition est vraie. Dans ce cas, l'instruction conditionnelle prend la forme :
if (condition) { bloc }
La condition doit être entourée de parenthèses, et le "bloc" représente ici, comme nous l'avons dit, un nombre quelconque d'instructions délimitées par une paire d'accolades. Exemple :
Dans cet extrait de code, toutes les instructions qui se trouvent à l'intérieur des accolades seront exécutées lorsque la valeur de vosVentes sera supérieure à la valeur de cible.
L'instruction conditionnelle de Java ressemble à cela :
if (condition) instruction1 else instruction2;
ou, plus généralement, à cela :
if (condition) {bloc1} else {bloc2}
Par exemple :
La partie else est toujours facultative. Un else est toujours associé à l'instruction if la plus proche. Voici un exemple :
L'opérateur ternaire permet de réaliser un branchement conditionnel d'une manière très concise. Cet opérateur utilise deux symboles (? et :) et comprend trois opérandes. Le premier argument correspond à une condition. Si cette condition est vérifiée, on renvoie ce qui suit le point d'interrogation (?) ; dans le cas contraire, ce qui suit les deux points (:). Pour bien comprendre l'opérateur ternaire, prenons comme exemple un branchement conditionnel :
if (a > b) z = a;
else z = b;
L'exemple précédent a pour but de placer le plus grand de a ou b dans z. Cet extrait de code peut très facilement être simplifié avec l'opérateur ternaire.
z = a > b ? a : b ;
Dans un cas comme celui-ci, si le test est vrai, l'opérateur renvoie ce qui suit le point d'interrogation (c'est-à-dire a) sinon il renvoie ce qui suit les deux points (c'est-à-dire b). Cet opérateur peut aussi être utilisé dans le cas d'un appel de fonction
setBackGround( indice == 1 ? Color.white : Color.red );
Si la variable indice est égale à 1, alors la couleur blanche (Color.white) est passée à la méthode setBackGround() ; dans le cas contraire, la couleur rouge (Color. red) est passée.
L'instruction switch s'utilise selon la syntaxe suivante :
L'instruction switch permet de tester une même variable (variable) par rapport à plusieurs valeurs. Ce branchement conditionnel remplace avantageusement une suite d'instructions if sur une seule et même variable. L'expression à évaluer est indiquée entre parenthèses et ne peut être que de type char, byte, short ou int. La condition est forcément suivie d'un bloc d'instructions qui permet de répertorier l'ensemble des valeurs à tester (valeur1 et valeur2). Chaque valeur est précédée du mot clé case. Le seul type de condition pris en compte est l'égalité. Dans le cas où la variable testée est égale à une des valeurs, on exécute les instructions qui suivent le case.
Deux mots clés sont associés à l'utilisation du switch : break et default. Le premier indique que l'on doit quitter le bloc. Le second permet de préciser le traitement à effectuer dans le cas où la variable n'est égale à aucune valeur répertoriée par les directives case. L'instruction default est optionnelle et doit être placée à la fin du switch.
Par exemple, si vous créez un système de menu ayant quatre alternatives, comme celui de l'organigramme ci-contre, vous pouvez utiliser un code comparable à celui-ci :
Notez que le break permet de sortir du switch et donc de ne pas exécuter ce qui suit.
Attention : Java exécute tout le code qui suit la directive case, Jusqu'à la sortie du switch ou jusqu'à une instruction break.
Dans l'exemple ci-contre, notez qu'il n'y a une instruction break qu'à la fin de la première directive case. Dans ces conditions, les résultats de ce test sont les suivants :
•
si a est égal à 1 : i = 1 ;
• si a est égal à 2 : i = 15 ;
• si a est égal à 3 : i = 13 ;
• si a est différent de 1, 2 et 3 : i = 10.
Ces résultats montrent qu'il est impératif d'utiliser le mot clé break si vous souhaitez uniquement exécuter le code associé à chaque directive case. Par ailleurs, ce switch permet de réaliser des opérations en cascade en jouant simplement sur l'ordre des tests et en omettant volontairement l'instruction break.
Dans l'exercice qui suit, vous allez utiliser la classe Clavier qui se trouve dans le paquetage saisie. L'ensemble : de cette classe, du code source équivalent et de toute sa documentation, se trouve dans l'archive SaisieClavier.jar. Pour intégrée cette archive au sein d'une bibliothèque qui sera utilisée éventuellement par tout vos projets, demandez à votre professeur comment faire, ou bien, suivez les cours prévus à cet effet, et qui concerne les bibliothèques.
Exercices |
A partir de l'algorithme ci-dessous, fabriquer le programme Java correspondant.
Pour pouvoir saisir un entier au clavier, il faut utiliser l'instruction
: Cette classe Clavier se situe dans le paquetage saisie, et la méthode lireInt() renvoie un entier. |
Récupération de quelques sources de certaines corrections
Il existe en Java des structures de contrôle permettant de répéter des instructions.
Deux sortes de boucles peuvent être employées lorsque vous ne savez pas combien
de fois le contenu de la boucle doit être exécuté (on parle alors de boucles
indéterminées).
Il y a d'abord la boucle while, dont le corps n'est exécuté que tant qu'une
condition est vraie. Sa forme générale est la suivante :
while (condition) { bloc }
La boucle while ne s'exécute jamais si la condition est fausse dès le départ.
Le test d'une boucle while est effectué avant l'exécution du corps de la boucle.
Par conséquent, ce bloc peut ne pas être exécuté. Si vous voulez être certain
que le bloc soit exécuté au moins une fois, vous devez placer la condition de
test en fin de boucle. Pour cela, employez une boucle
do/while, dont voici la syntaxe :
do { bloc } while (condition);
Cette instruction exécute le bloc avant de tester la condition. Si celle-ci
est fausse, le programme réexécute le bloc avant d'effectuer un nouveau test,
et ainsi de suite. Par exemple, le code suivant calcule une valeur approximative
de la racine carrée d'un nombre positif à l'aide d'un processus itératif, en
répétant ce processus jusqu'à ce que les valeurs absolues de l'itération courante
et de la précédente soient très proches.
Finalement, comme un bloc peut contenir n'importe quel nombre d'instructions Java, vous pouvez imbriquer les boucles sur autant de niveaux que vous le désirez.
Java dispose d'une construction très générale pour supporter l'itération. Il s'agit de la boucle for qui s'utilise de la manière suivante :
Le début de la boucle for est constitué de trois éléments :
Comme le montre l'organigramme ci-dessus, le code suivant affiche les nombres 1 à 10 sur l'écran.
Il est aussi possible de créer des boucles décrémentales :
L'exemple ci-dessous nous montre l'une des nombreuses possibilité qu'offre la boucle for. Remarquez bien le résultat obtenu.
Chaque composant de la boucle for peut être une instruction vide. Concrètement, cela indique la possibilité d'inclure dans la boucle un point virgule sans expression ni instruction pour que cette partie de la boucle soit ignorée. II est à souligner que, si vous utilisez une instruction nuls dans votre boucle for, vous pourrez avoir à initialiser ou à incrémenter vous-même des variables ou des indices de boucle à un autre endroit du programme.
11 est aussi possible d'utiliser une instruction vide comme corps pour une boucle for si tout ce qui doit être exécuté est représenté par la première ligne de la boucle. Par exemple, la boucle for suivante recherche le premier nombre premier supérieur à 4 000. Elle appelle une méthode appelée notPrime(), qui dispose en théorie d'un moyen pour effectuer cela.
Une erreur souvent commise dans les boucles for consiste à placer accidentellement un point virgule à la fin de la ligne qui contient l'instruction for :
Dans l'exemple ci-dessus, le premier point virgule met fin à la boucle sans exécuter la ligne x = x * i dans le cadre de la boucle. La ligne x = x * i n'est exécutée qu'une fois, car elle située à l'extérieur de la boucle for. Veillez à ne pas commettre ce type d'erreur dans vos programmes Java.
En reprenant l'exemple de l'organigramme, l'implémentation ci-contre nous montre tout ce que nous pouvons écrire avec la boucle for :
Bien entendu, une boucle for équivaut à une boucle while ; choisissez le type de boucle qui vous semble convenir le mieux à la situation. Pour être plus précis :
Exercices |
|
Il existe deux opérateurs qui sont utilisés dans le cas des boucles : break et continue. Le premier permet de quitter une boucle. Le second permet de revenir à la condition de la boucle.
On sort normalement d'une boucle dès que la condition n'est plus vérifiée. II est cependant possible de prévoir une autre possibilité pour sortir d'une boucle, en utilisant l'instruction break. Cette instruction a déjà été utilisée pour sortir d'un switch, elle permet aussi de quitter une boucle.
L'instruction continue a pour objectif de remonter à la condition de la boucle. On peut ainsi ne pas exécuter une partie des instructions du corps de la boucle. Dans le cas d'une boucle for, la troisième expression sera exécutée avant le retour au test. L'exemple suivant montre l'utilisation des deux mots clés break et continue.
Ce code illustre plusieurs notions liées à la manipulation des boucles, des tests et des deux mots clés break et continue. Remarquez, sur la ligne 1, la condition de la boucle qui est égale à true. Dans ce cas, la condition est toujours vraie, ce qui permet de définir ce que l'on nomme une boucle sans fin. Cette technique constitue certainement le moyen le plus simple pour mettre en oeuvre une boucle, mais il est nécessaire dans ce cas de penser à mettre en place une condition de sortie. Le seul moyen de quitter cette boucle est donc d'utiliser l'instruction break. On peut remarquer dans ce programme que break est employé à deux reprises (ligne 3 et ligne 8). Le premier break sert à sortir du switch, mais pas de la boucle. Le second permet de quitter la boucle. La ligne 5 correspond à une instruction continue qui permet de remonter à la condition de la boucle (ligne 1) et n'a qu'un seul objectif, ne pas exécuter le code qui suit dans la boucle (situé après la ligne 5).
Pour en savoir plus sur les opérateurs
de boucle
§
Exercices |
En utilisant le débogueur, donnez le résultat de chacune des opérations exécutées dans la partie ci-dessous en essayant de comprendre les traitements réalisés. Dans le dernier calcul de i (i = j>=0 ? j : -j), que représente-t-il par rapport à j ? Que représente p par rapport à i ? Vous testerez vos résultats en fabriquant un programme de test. |