orld {
Introduction
public static
void
System.out.p main(String[] args)
rintln("Hello {
} world");
1
class HelloW
orld {
public static
void
System.out.p main(String[] args)
rintln("Hello {
} world");
001001010100010010010
101010100101001010010
101010101010010010010
101001000101001011000
CAFEBABE00000032001D0A0006000F09 . . . . . . . 2 . . . . . . . .
000010 001000110800120A0013001407001507 . . . . . . . . . . . . . . . .
000020 00160100063C696E69743E0100032829 . . . . . < i n i t > . . . ( )
000030 56010004436F646501000F4C696E654E V . . . C o d e . . . L i n e N
compilateur
000040 756D6265725461626C650100046D6169 u m b e r t a b l e . . . m a i
000050 6E010016285B4C6A6176612F6C616E67 n . . . ( [ L j a v a / l a n g
000060 2F537472696E673B295601000A536F75 / S t r i n g ; ) V . . . S o u
000070 72636546696C6501000F48656C6C6F57 r c e F i l e . . . H e l l o w
000080 6F726C642E6A6176610C000700080700 o r l d . j a v a . . . . . .
000090 170C0018001901000B48656C6C6F2077 . . . . . . . . . H e l l o w
0000A0 6F726C6407001A0C001B001C01000A48 o r l d . . . . . . . . . . . H
0000B0 656C6C6F576F726C640100106A617661 e l l o w o r l d . . . j a v a
0000C0 2F6C616E672F4F626A6563740100106A / l a n g / O b j e c t . . . j
0000D0 6176612F6C616E672F53797374656D01 a v a / l a n g / S y s t e m .
0000E0 00036F75740100154C6A6176612F696F . . o u t . . . L j a v a / i o
0000F0 2F5072696E7453747265616D3B010013 / P r i n t S t r e a m ; . . .
000100 6A6176612F696F2F5072696E74537472 j a v a / i o / P r i n t S t r
000110 65616D0100077072696E746C6E010015 e a m . . . p r i n t l n . . .
000120 284C6A6176612F6C616E672F53747269 ( L j a v a / l a n g / S t r i
000130 6E673B29560021000500060000000000 n g , ) V . ! . . . . . . . . .
class HelloW
orld {
bytecode class HelloW
orld {
public static public static
void void
machine
System.out.p main(String[] args) System.out.p main(String[] args)
rintln("Hello { rintln("Hello {
} world"); } world");
virtuelle
001001010100010010010
101010100101001010010
101010101010010010010
101001000101001011000
2
réfléchir au problème; réfléchir au problème;
concevoir la séquence d'instructions concevoir la séquence d'instructions
? class HelloW
orld {
public static
void
System.out.p main(String[] args)
rintln("Hello {
} world");
Erreurs à l'exécution:
class HelloW
orld {
public static
le programme a été mal conçu class HelloW
orld {
public static
void void
System.out.p main(String[] args) System.out.p main(String[] args)
rintln("Hello { rintln("Hello {
} world");
tester le programme sur la } world");
tester le programme sur la
machine virtuelle machine virtuelle
3
Une variable possède 3 caractéristiques:
• Son identificateur, qui est le nom par lequel la donnée
123
1
Initialisation Initialisation
Une variable non initialisée ne peut être utilisée.
En même temps qu'elle est déclarée, une variable peut être initialisée, c'est-à-
dire lui donner une valeur avant de l'utiliser.
Par exemple:
La ligne: n nCarre
int nCarre;
System.out.println(nCarre);
int n = 4; 4 ?
donne une erreur à la compilation:
déclare donc une variable appelée n et lui donne la valeur 4.
variable nCarre might not have been initialized
System.out.println(nCarre);
4 ? int n = 4;
int n = 4; double x = 1.0; n x
int nCarre;
type pour les valeurs décimales:
la variable x ne peut contenir que 4 1.0
des valeurs décimales
2
Déclaration de variables Déclaration de variables
De façon générale, une déclaration de variable suit le schéma: D'autres exemples de déclaration:
int m = 1;
type identificateur = valeur_initiale; on peut déclarer plusieurs variables
int p = 1, q = 0;
simultanément.
double x = 0.1, y; Ne pas en abuser
ou éventuellement:
N'oubliez pas le point-virgule ; à la fin
type identificateur;
3
Types de variables Affectations
La ligne:
Les principaux types élémentaires sont:
– int, pour les valeurs entières (pour integer, entiers en anglais); nCarre = n * n;
– double, pour les nombres à virgule, par exemple 0.5
est une affectation.
et aussi:
Attention, ce n'est pas une égalité mathématique: Une affectation est
– float: aussi pour les nombres à virgule, moins précises mais occupant une instruction qui permet de changer une valeur à une variable.
moins de mémoire que les doubles;
– char: pour les caractères (A..Z etc.);
– …
Affectations Affectations
L'exécution d’une affectation se décompose en deux temps : L'exécution d’une affectation se décompose en deux temps :
16 nCarre n
16 nCarre n
nCarre = n * n; ? 4 2 nCarre = n * n; ?
16 4
la valeur de l’expression est stockée dans la variable
à gauche du signe =
L’ancienne valeur de nCarre est perdue.
4
Affectations
De façon plus générale, une affectation suit le schéma: Attention: Ne confondez pas une affectation avec une égalité mathématique.
nom_de_variable = expression;
Toutes les deux utilisent le signe égal =, mais l'affectation est un mécanisme
dynamique.
N'oubliez pas le point-virgule ; à la fin
Une expression calcule une valeur, qui doit être de même type que la
Par exemple, les deux instructions:
variable.
Exemples d'expression: copie la valeur de b dans a
a = b;
• 4
b = a; copie la valeur de a dans b
• n * n
• n * (n + 1) + 3 * n – 2
ne sont pas identiques.
Nous reviendrons sur les expressions un peu plus loin.
En mathématiques:
On peut écrire aussi des affectations telles que:
b=a+1
a = a + 1;
signifie que tout au long des calculs, a et b vérifieront toujours cette relation.
Autrement dit, quel que soit a, b sera toujours égal à a+1
Ce type d’affectation, où une variable apparaît de chaque côté du signe =
permet de résoudre de nombreux problèmes.
En Java:
Cette affectation signifie:
a = 5;
« calculer l’expression de a + 1 et ranger le résultat dans a. Cela revient à
b = a + 1; donne à b la valeur de a+1, c’est-à-dire 6. augmenter de 1 la valeur de a »
a = 2; Nous reviendrons sur ce point dans la suite.
donne à a la valeur 2, sans que b ne soit modifiée!
b contient donc toujours 6.
5
Déclaration de constantes
Il peut arriver que la valeur d'une variable ne doive pas changer après
l'initialisation. Dans ce cas, il faut ajouter le mot-clé final devant la déclaration:
Par exemple:
6
Expression et Opérateurs
A droite du signe égal dans une affectation se trouve une expression:
Une expression calcule une valeur, qui doit être de même type que la
variable.
1
On dispose aussi des opérateurs += , -= , *= , /= Opérateurs relatifs au type int
Par exemple: Dans le cas des int, il existe aussi:
0 % 4 vaut 0 car 0 = 0 * 4 + 0
1 % 4 vaut 1 car 1 = 0 * 4 + 1
b *= a; 2 % 4 vaut 2 car 2 = 0 * 4 + 2
est équivalent à 3 % 4 vaut 3 car 3 = 0 * 4 + 3
b = b * a; 4 % 4 vaut 0 car 4 = 1 * 4 + 0
5 % 4 vaut 1 car 5 = 1 * 4 + 1
...
2
Affectation d’une valeur entière à La division entière
une variable décimale
En revanche, il est possible d'affecter une valeur de type int à une variable
de type décimale, par exemple double.
Exemple: double x;
l'expression 1 / 2 est d'abord évaluée
int n = 3;
x = 1 / 2; elle vaut 0
double x = 2 * n;
0 la valeur 0 est affectée à x
0.0
3
Fonctions mathématiques
Java fournit les fonction mathématiques usuelles, ainsi que des constantes comme Pi.
Fonctions mathématiques
Ces fonctions et constantes s'utilisent en suivant la notation:
class ExempleMathematique
{
public static void main(String[] args) {
import java.util.Scanner;
class ExempleAngle
{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
4
Pour écrire à l’écran
affiche la valeur de la variable n
fonction d'affichage
Les variables : sur le terminal
(et non pas la lettre n)
ce qui est entre guillemets On peut aussi afficher la valeur d'une expression: 4
(") est affiché littéralement
System.out.println("Le double de " + n + " est " + 2 * n + ".");
1
Déroulement du programme pas-à-pas n
int n = 4;
int nCarre;
int n = 4;
int nCarre;
4
nCarre = n * n; nCarre = n * n;
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
System.out.println("Le carre de " + n + " est " + nCarre + "."); System.out.println("Le carre de " + n + " est " + nCarre + ".");
System.out.println("Le double de n est " + 2 * n + "."); System.out.println("Le double de n est " + 2 * n + ".");
n nCarre n nCarre
int n = 4;
int nCarre;
4 ? int n = 4;
int nCarre;
4 ?
nCarre = n * n; nCarre = n * n;
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
System.out.println("Le carre de " + n + " est " + nCarre + "."); System.out.println("Le carre de " + n + " est " + nCarre + ".");
System.out.println("Le double de n est " + 2 * n + "."); System.out.println("Le double de n est " + 2 * n + ".");
2
n nCarre n nCarre
int n = 4;
int nCarre;
4 16 int n = 4;
int nCarre;
4 16
nCarre = n * n; nCarre = n * n;
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
System.out.println("Le carre de " + n + " est " + nCarre + "."); System.out.println("Le carre de " + n + " est " + nCarre + ".");
System.out.println("Le double de n est " + 2 * n + "."); System.out.println("Le double de n est " + 2 * n + ".");
n nCarre n nCarre
int n = 4;
int nCarre;
4 16 int n = 4;
int nCarre;
4 16
nCarre = n * n; nCarre = n * n;
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
System.out.println("Le carre de " + n + " est " + nCarre + "."); System.out.println("Le carre de " + n + " est " + nCarre + ".");
System.out.println("Le double de n est " + 2 * n + "."); System.out.println("Le double de n est " + 2 * n + ".");
3
n nCarre Qu’affiche ce programme ?
int a = 2;
int n = 4;
int nCarre;
4 16 int b = 1;
b = a * (b + 2);
nCarre = n * n;
System.out.println(a + ", " + b);
System.out.println("La variable n contient " + n);
System.out.println("Le carre de " + n + " est " + nCarre + ".");
System.out.println("Le double de n est " + 2 * n + ".");
A: a, b
?
Ce qui s'affiche :
La variable n contient 4. B: 1, 2
Le carre de 4 est 16.
Le double de n est 8.
C: 2, 1
▌ D: 2, 6
int a = 2; int a = 2;
int b = 1; int b = 1;
b = a * (b + 2); b = a * (b + 2);
a a b
2 2 1
4
int a = 2; int a = 2;
int b = 1; int b 2=* (1
1;+ 2) = 2 * 3 = 6
b = a * (b + 2); b = a * (b + 2);
a b a b
2 1 2 1
int a = 2; int a = 2;
int b 2=* (1
1;+ 2) = 2 * 3 = 6 int b = 1;
b = a * (b + 2); b = a * (b + 2);
a b a b
2 6 2 6
Affiche:
2, 6
5
Qu’affiche ce programme ?
int a = 5; int a = 5;
int b = a + 3; int b = a + 3;
a = 1; a = 1;
A: 5, 4 a
B: 1,
C: 1,
1
4 ? 5
D: 1, 8
int a = 5; int a = 5;
int b = a + 3; int b = a + 3;
a = 1; 5 + 3 = 8 a = 1;
a b a b
5 8 5 8
6
int a = 5; int a = 5;
int b = a + 3; int b = a + 3;
a = 1; a = 1;
a b a b
1 8 Affiche: 1 8
1, 8
Qu’affiche ce programme ?
int a = 1; int a = 1;
int b = 2; int b = 2;
a = b; a = b;
b = a; b = a;
A: 1, 1
?
a
B: 1, 2
C: 2, 1 1
D: 2, 2
7
int a = 1; int a = 1;
int b = 2; int b = 2;
a = b; a = b;
b = a; b = a;
a b a b
1 2 1 2
int a = 1; int a = 1;
int b = 2; int b = 2;
a = b; a = b;
b = a; b = a;
a b a b
2 2 2 2
8
Supposons qu'on ait déclaré et initialisé deux variables a et b.
int a = 1;
a b int b = 2;
int temp = a;
Affiche:
2, 2 2 2 a = b;
b = temp;
a b a b temp
1 2 1 2 1
int a = 1; int a = 1;
int b = 2; int b = 2;
int temp = a; int temp = a;
a = b; a = b;
b = temp; b = temp;
9
a b temp a b temp
1 2 1 2 2 1
int a = 1; int a = 1;
int b = 2; int b = 2;
int temp = a; int temp = a;
a = b; a = b;
b = temp; b = temp;
a b temp a b temp
2 2 1 2 1 1
int a = 1; int a = 1;
int b = 2; int b = 2;
int temp = a; int temp = a;
a = b; a = b;
b = temp; b = temp;
10
import java.util.Scanner;
11
Déroulement du programme pas-à-pas Déroulement du programme pas-à-pas
Scanner keyb = new Scanner(System.in); Scanner keyb = new Scanner(System.in);
System.out.println("Entrez une valeur pour n"); System.out.println("Entrez une valeur pour n");
int n = keyb.nextInt(); int n = keyb.nextInt();
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
keyb
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
keyb keyb
12
Déroulement du programme pas-à-pas Déroulement du programme pas-à-pas
Scanner keyb = new Scanner(System.in); Scanner keyb = new Scanner(System.in);
System.out.println("Entrez une valeur pour n"); n System.out.println("Entrez une valeur pour n"); n
int n = keyb.nextInt(); int n = keyb.nextInt();
int nCarre = n * n;
2 int nCarre = n * n;
2
System.out.println("La variable n contient " + n); System.out.println("La variable n contient " + n);
4
Ce qui s'affiche: Ce qui s'affiche:
Entrez une valeur pour n Entrez une valeur pour n
2 2
▌ ▌
13
Attention avec nextLine() !
int i = keyb.nextInt();
String s1 = keyb.nextLine();
String s2 = keyb.nextLine();
Si on tape:
25 francs
23 francs
è i contient 25, s1 contient francs, s2 contient 23 francs
Si on tape:
14
euros
43
è i contient 14, s1 est vide, s2 contient euros !
car nextLine() lit ce qui suit 14 jusqu'à la fin de la ligne, c'est-à-dire rien !
14
import java.util.Scanner;
class PremierExempleIf
{
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
Branchements conditionnels System.out.print("Entrez votre nombre:");
int n = scanner.nextInt();
if (n < 5) {
System.out.println("Votre nombre est plus petit que 5.");
} else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
}
System.out.println("fin du programme");
}
}
Mot-clé if Condition
if (n < 5) { if (n < 5) {
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
1
Une accolade ouvrante
Cette instruction sera exécutée si la condition est vraie.
if (n < 5) { if (n < 5) {
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
if (n < 5) { if (n < 5) {
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
2
Une accolade ouvrante
if (n < 5) { if (n < 5) {
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
n
System.out.print("Entrez votre nombre:");
int n = scanner.nextInt();
if (n < 5) {
?
System.out.println("Votre nombre est plus petit que 5.");
} else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
if (n < 5) { }
System.out.println("Votre nombre est plus petit que 5.");
} else { System.out.println("fin du programme");
System.out.println("Votre nombre est plus grand ou egal a 5.");
} Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre:
▌
Une accolade fermante
3
n n
System.out.print("Entrez votre nombre:"); System.out.print("Entrez votre nombre:");
int n = scanner.nextInt(); int n = scanner.nextInt();
if (n < 5) {
? if (n < 5) {
3
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: Entrez votre nombre:
▌ 3
▌
n n
System.out.print("Entrez votre nombre:"); System.out.print("Entrez votre nombre:");
int n = scanner.nextInt(); int n = scanner.nextInt();
?
if (n < 5) {
3 if (n < 5) {
3
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: Entrez votre nombre:
3 3
▌ ▌
4
n n
System.out.print("Entrez votre nombre:"); System.out.print("Entrez votre nombre:");
int n = scanner.nextInt(); int n = scanner.nextInt();
if (n < 5) {
3 if (n < 5) {
3
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: Entrez votre nombre:
3 3
Votre nombre est plus petit que 5. Votre nombre est plus petit que 5.
▌ ▌
n n
System.out.print("Entrez votre nombre:"); System.out.print("Entrez votre nombre:");
int n = scanner.nextInt(); int n = scanner.nextInt();
if (n < 5) {
3 if (n < 5) {
7
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: Entrez votre nombre:
3 7
Votre nombre est plus petit que 5. ▌
fin du programme
▌
5
n n
System.out.print("Entrez votre nombre:"); System.out.print("Entrez votre nombre:");
int n = scanner.nextInt(); int n = scanner.nextInt();
?
if (n < 5) {
7 if (n < 5) {
7
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: Entrez votre nombre:
7 7
▌ Votre nombre est plus grand ou egal a 5.
▌
n
System.out.print("Entrez votre nombre:");
int n = scanner.nextInt();
if (n < 5) {
7
System.out.println("Votre nombre est plus petit que 5.");
} else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
} if (n < 5) {
System.out.println("Votre nombre est plus petit que 5.");
System.out.println("fin du programme"); } else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
Ce qui s'affiche dans la fenêtre Terminal: }
Entrez votre nombre:
7
Votre nombre est plus grand ou egal a 5.
fin du programme
▌
6
Les accolades délimitent un bloc d'instructions Les accolades délimitent un bloc d'instructions
if (n < 5) { if (n < 5) {
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} else { } else {
System.out.println("Votre nombre est plus grand ou egal a 5."); System.out.println("Votre nombre est plus grand ou egal a 5.");
} }
if (n < 5) { if (n < 5)
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
System.out.println("Votre nombre est " + n); else
System.out.println("Votre nombre est plus grand ou egal a 5.");
} else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
} Néanmoins, une bonne pratique est de toujours utiliser des blocs, même quand il n'y a qu'une seule
instruction.
Ca facilite l'ajout d'instructions.
7
n
System.out.print("Entrez votre nombre: ");
int n = scanner.nextInt();
Une instruction if peut ne pas avoir de deuxième partie.
Par exemple, si on veut ne rien afficher si n est plus grand ou égal à 5, il suffit d'enlever la deuxième if (n < 5) {
3
partie, à partir du else: System.out.println("Votre nombre est plus petit que 5.");
}
if (n < 5) {
System.out.println("Au revoir");
System.out.println("Votre nombre est plus petit que 5.");
}
n n
System.out.print("Entrez votre nombre: "); System.out.print("Entrez votre nombre: ");
int n = scanner.nextInt(); int n = scanner.nextInt();
if (n < 5) {
3 if (n < 5) {
3
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: 3 Entrez votre nombre: 3
Votre nombre est plus petit que 5. Votre nombre est plus petit que 5.
▌ Au revoir
▌
8
n n
System.out.print("Entrez votre nombre: "); System.out.print("Entrez votre nombre: ");
int n = scanner.nextInt(); int n = scanner.nextInt();
if (n < 5) {
7 if (n < 5) {
3
System.out.println("Votre nombre est plus petit que 5."); System.out.println("Votre nombre est plus petit que 5.");
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
Entrez votre nombre: 7 Entrez votre nombre: 7
▌ Au revoir
▌
9
Choix imbriqués: exemple Supposons:
x y z
if (x == y) { if (x == y) { 1 1 1
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
} else { Attention à ne pas abuser de cette solution. } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { Au-delà de 3 niveaux, le code devient vite illisible! } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); System.out.println("Les trois valeurs sont differentes.");
} }
} }
} }
x y z x y z
Supposons: Supposons:
if (x == y) { 1 1 1 if (x == y) { 1 1 1
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
Les trois valeurs sont egales. est affiché
} else { } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); System.out.println("Les trois valeurs sont differentes.");
} }
} }
} }
10
x y z x y z
Supposons: Supposons:
if (x == y) { 1 1 1 if (x == y) { 1 1 1
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
} else { } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); System.out.println("Les trois valeurs sont differentes.");
} }
} }
} }
x y z x y z
Supposons: Supposons:
if (x == y) { 1 2 2 if (x == y) { 1 2 2
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
} else { } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); System.out.println("Les trois valeurs sont differentes.");
} }
} }
} }
11
x y z x y z
Supposons: Supposons:
if (x == y) { 1 2 2 if (x == y) { 1 2 2
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
} else { } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); Seules les deuxtrois
System.out.println("Les dernieres
valeursvaleurs sont egales. est affiché
sont differentes.");
} }
} }
} }
x y z x y z
Supposons: Supposons:
if (x == y) { 1 2 2 if (x == y) { 1 2 2
if (y == z) { if (y == z) {
System.out.println("Les trois valeurs sont egales."); System.out.println("Les trois valeurs sont egales.");
} else { } else {
System.out.println("Seules les deux premieres valeurs sont egales."); System.out.println("Seules les deux premieres valeurs sont egales.");
} }
} else { } else {
if (x == z) { if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales."); System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else { } else {
if (y == z) { if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales."); System.out.println("Seules les deux dernieres valeurs sont egales.");
} else { } else {
System.out.println("Les trois valeurs sont differentes."); System.out.println("Les trois valeurs sont differentes.");
} }
} }
} }
12
x y z
Supposons:
if (x == y) { 1 2 2
if (y == z) {
System.out.println("Les trois valeurs sont egales.");
} else {
System.out.println("Seules les deux premieres valeurs sont egales.");
}
} else {
if (x == z) {
System.out.println("Seules la 1ere et la 3eme valeurs sont egales.");
} else {
if (y == z) {
System.out.println("Seules les deux dernieres valeurs sont egales.");
} else {
System.out.println("Les trois valeurs sont differentes.");
}
}
}
13
Les conditions
L’instruction if fait apparaître une condition entre parenthèses
Condition
Conditions if (n < 5) {
System.out.println("Votre nombre est plus petit que 5.");
} else {
System.out.println("Votre nombre est plus grand ou egal a 5.");
}
Nous allons voir maintenant comment s’écrivent les conditions d’une façon générale.
Une condition simple compare deux expressions. Une conditionUn seul signe
simple = représente
compare l'affectation
deux expressions.
Elle utilise un opérateur de comparaison, comme < ou > Elle utilise un opérateur de comparaison, comme < ou >
Par exemple, si on veut tester si la variable n est égale à 5, il faut
écrire:
Opérateurs de comparaison du langage Java: Opérateurs de comparaison du langage C++:
if (n == 5)
Opérateur de comparaison Signification Opérateur de comparaison Signification
< inférieur à et non pas: < inférieur à
> if (n = 5)>
supérieur à supérieur à
== égal à == égal à
<= inférieur ou égal à <= inférieur ou égal à
>= supérieur ou égal à >= supérieur ou égal à
!= différent de != différent de
1
int a = 1;
int b = 2;
if (a == b) {
Attention: System.out.println("Cas 1");
Il n'y a pas d'espaces entre les deux } else {
caractères System.out.println("Cas 2");
}
int a = 1; int a = 1;
int b = 2; int b = 2;
if (a != b) { if (a <= b) {
System.out.println("Cas 2"); System.out.println("Cas 3");
} else { } else {
System.out.println("Cas 1"); System.out.println("Cas 4");
} }
if (2 * a != b) { if (2 * a <= b) {
System.out.println("b est different du double de a."); System.out.println("b est superieur ou egal au double de a.");
} }
affiche affiche
Cas 2 Cas 3
b est superieur ou egal au double de a.
2
Les opérateurs logiques Exemple avec l'opérateur logique &&
On peut relier des conditions simples par des opérateurs logiques. n
System.out.println("Entrez un nombre entre 1 et 10:");
L'opérateur logique && (ET): int n = scanner.nextInt();
faux 0
faux
par exemple, la condition Supposons que la valeur
if ((n >= 1) && (n <= 10)) { entrée pour n soit 0
(a < b) && (c < d) System.out.println("correct");
} else {
est vraie uniquement si les deux conditions (a < b) et (c < d) sont toutes les deux vraies. System.out.println("incorrect"); incorrect est affiché
}
Exemple avec l'opérateur logique && Exemple avec l'opérateur logique &&
n n
System.out.println("Entrez un nombre entre 1 et 10:"); System.out.println("Entrez un nombre entre 1 et 10:");
int n = scanner.nextInt(); int n = scanner.nextInt();
faux 12 vrai 5
vrai faux vrai vrai
Supposons que la valeur Supposons que la valeur
if ((n >= 1) && (n <= 10)) { entrée pour n soit 12 if ((n >= 1) && (n <= 10)) { entrée pour n soit 12
System.out.println("correct"); System.out.println("correct");
} else { } else {
System.out.println("incorrect"); incorrect est affiché System.out.println("incorrect"); correct est affiché
} }
3
Les opérateurs logiques Exemple avec l'opérateur logique ||
L'opérateur logique || (OU): System.out.println("Entrez deux valeurs:"); m n
int n = scanner.nextInt();
vrai
par exemple, la condition int m = scanner.nextInt();
vrai 1 -1
(a < b) || (c < d) if ((m >= 0) || (n >= 0)) {
System.out.println("au moins une valeur est positive");
} else {
est vraie si au moins une des deux conditions (a < b) ou (c < d) est vraie.
System.out.println("les deux valeurs sont negatives");
}
Supposons que la valeur entrée pour m soit +1, et la
valeur entrée pour n soit -1
au moins une valeur est positive est affiché les deux valeurs sont negatives est affiché
4
Les opérateurs logiques
L'opérateur logique ! (NON):
!(a < b)
Nous verrons des exemples d'utilisation de cet opérateur plus loin dans la suite du cours.
5
Erreurs classiques
Le test d'égalité s'écrit ==, et pas =
Erreurs classiques
if (a == 1); // !!! Si on utilise des accolades même quand il n'y a qu'une instruction dans le bloc, et
System.out.println("a vaut 1"); qu'on écrive le test de la façon suivante:
1
System.out.println("Entrez le premier nombre:");
Erreurs classiques int n = scanner.nextInt();
System.out.println("Entrez le deuxieme nombre:");
Ne pas oublier les accolades, l'indentation ne suffit pas: int p = scanner.nextInt();
if (n < p)
if ((n < p) && (2 * n >= p)) {
System.out.println("n est plus petit que p"); System.out.print("1");
max = p; }
else
System.out.println("n est plus grand ou egal a p"); if ((n < p) || (2 * n >= p)) {
System.out.print("2");
}
génère à la compilation l'erreur:
error: 'else' without 'if' if (n < p) {
if (2 * n >= p) {
System.out.print("3");
Voici une meilleure présentation du code précédent: } else {
if (n < p) System.out.print("4");
}
System.out.println("n est plus petit que p");
} A: 2
?
System.out.println(); B: 24
max = p;
else Qu’affiche ce programme quand l’utilisateur entre 1 et 2 ? C: 123
System.out.println("n est plus grand ou egal a p"); D: 1234
if ((n < p) && (2 * n >= p)) { if ((n < p) && (2 * n >= p)) {
System.out.print("1"); System.out.print("1");
} }
if (n < p) { if (n < p) {
if (2 * n >= p) { if (2 * n >= p) {
System.out.print("3"); System.out.print("3");
} else { } else {
System.out.print("4"); System.out.print("4");
} }
} A: 2 } A: 2
? ?
System.out.println(); B: 24 System.out.println(); B: 24
Qu’affiche ce programme quand l’utilisateur entre 1 et 3 ? C: 123 Qu’affiche ce programme quand l’utilisateur entre 2 et 1 ? C: 123
D: 1234 D: 1234
2
Le type boolean
Le type boolean (pour booléen) est le type des conditions.
Le type booléen (boolean) Une variable de type booléen est souvent appelée simplement un booléen.
Exemple:
int a = 1, b = 2;
boolean test1 = (a == b);
boolean test2 = (a < b);
Il permet de déclarer des variables contenant la valeur d'une condition. Il permet de déclarer des variables contenant la valeur d'une condition.
Une variable de type booléen est souvent appelée simplement un booléen. Une variable de type booléen est souvent appelée simplement un booléen.
Un booléen ne peut prendre que deux valeurs possibles: true ou false Un booléen ne peut prendre que deux valeurs possibles: true ou false
3
Le type bool Le type bool
Le type boolean (pour booléen) est le type des conditions. Le type boolean (pour booléen) est le type des conditions.
Il permet de déclarer des variables contenant la valeur d'une condition. Il permet de déclarer des variables contenant la valeur d'une condition.
Une variable de type booléen est souvent appelée simplement un booléen. Une variable de type booléen est souvent appelée simplement un booléen.
Un booléen ne peut prendre que deux valeurs possibles: true ou false Un booléen ne peut prendre que deux valeurs possibles: true ou false
On peut initialiser des booléens à l'aide des constantes false et true. On peut initialiser des booléens à l'aide des constantes false et true.
On peut utiliser des booléens comme des conditions. Par exemple: On peut utiliser des booléens comme des conditions. Par exemple:
• on peut utiliser des opérateurs logiques (&&, || et !) entre booléens; • on peut utiliser des opérateurs logiques (&&, || et !) entre booléens;
• on peut utiliser un booléen comme condition dans un if. • on peut utiliser un booléen comme condition dans un if.
int a = 1, b = 2; int a = 1, b = 2;
c
boolean c = true; boolean c = true;
boolean d = (a == b); boolean d = (a == b); true
boolean e = (d || (a < b)); boolean e = (d || (a < b));
if (e) { if (e) {
System.out.println("e vaut true"); System.out.println("e vaut true");
} }
4
On peut initialiser des booléens à l'aide des constantes false et true. On peut initialiser des booléens à l'aide des constantes false et true.
On peut utiliser des booléens comme des conditions. Par exemple: On peut utiliser des booléens comme des conditions. Par exemple:
• on peut utiliser des opérateurs logiques (&&, || et !) entre booléens; • on peut utiliser des opérateurs logiques (&&, || et !) entre booléens;
• on peut utiliser un booléen comme condition dans un if. • on peut utiliser un booléen comme condition dans un if.
int a = 1, b = 2; int a = 1, b = 2;
c c d
boolean c = true; boolean c = true;
boolean d = (a == b); true boolean d = (a == b); true false
boolean e = (d || (a < b)); boolean e = (d || (a < b));
if (e) { if (e) {
System.out.println("e vaut true"); System.out.println("e vaut true");
} }
On peut initialiser des booléens à l'aide des constantes false et true. On peut initialiser des booléens à l'aide des constantes false et true.
On peut utiliser des booléens comme des conditions. Par exemple: On peut utiliser des booléens comme des conditions. Par exemple:
• on peut utiliser des opérateurs logiques (&&, || et !) entre booléens; • on peut utiliser des opérateurs logiques (&&, || et !) entre booléens;
• on peut utiliser un booléen comme condition dans un if. • on peut utiliser un booléen comme condition dans un if.
int a = 1, b = 2; int a = 1, b = 2;
c d c d
boolean c = true; boolean c = true;
boolean d = (a == b); true false boolean d = (a == b); true false
boolean e = (d || (a < b)); boolean e = (d || (a < b));
e
if (e) { if (e) {
System.out.println("e vaut true"); System.out.println("e vaut true");
} } true
5
On peut initialiser des booléens à l'aide des constantes false et true. On peut initialiser des booléens à l'aide des constantes false et true.
On peut utiliser des booléens comme des conditions. Par exemple: On peut utiliser des booléens comme des conditions. Par exemple:
• on peut utiliser des opérateurs logiques (&&, || et !) entre booléens; • on peut utiliser des opérateurs logiques (&&, || et !) entre booléens;
• on peut utiliser un booléen comme condition dans un if. • on peut utiliser un booléen comme condition dans un if.
int a = 1, b = 2; int a = 1, b = 2;
c d c d
boolean c = true; boolean c = true;
boolean d = (a == b); true false boolean d = (a == b); true false
boolean e = (d || (a < b)); boolean e = (d || (a < b));
e e
if (e) { if (e) {
System.out.println("e vaut true"); System.out.println("e vaut true");
} true } true
6
Les blocs
En Java, les instructions peuvent être regroupées en blocs.
Les blocs d'instructions Les blocs sont identifiés par des délimiteurs de début et de fin : { et }
Exemple:
{
Scanner keyb = new Scanner(System.in);
int i;
double x;
if (i != 0) { if (i != 0) {
int j = 0; int j = 0;
... ...
j = 2 * i; j = 2 * i;
... ...
} }
// A partir d'ici, on ne peut plus utiliser j // A partir d'ici, on ne peut plus utiliser j
1
Notion de portée Notion de portée
‣ Les variables déclarées à l'intérieur d'un bloc sont appelées variables locales ‣ Les variables déclarées à l'intérieur d'un bloc sont appelées variables locales
(au bloc). Elles ne sont accessibles qu'à l'intérieur du bloc. (au bloc). Elles ne sont accessibles qu'à l'intérieur du bloc.
‣ Les variables déclarées en dehors de main sont de portée globales (à la ‣ Les variables déclarées en dehors de main sont de portée globales (à la
classe). classe).
Elles sont accessibles dans toute la classe. Elles sont accessibles dans toute la classe.
2
Portée : règle Portée : cas des itérations
En Java, on ne peut pas utiliser le nom d'une variable La déclaration d'une variable à l'intérieur d'une itération est une déclaration locale
déclarée plus globalement pour déclarer une autre au bloc de la boucle, et aux deux instructions de test et d'incrément:
if (i != 0) {
int j = 0; variable.
... Cela permet d'éviter des ambiguïtés entre noms de for(int i = 0; i < 5; ++i) {
j = 2 * i; variables. System.out.println(i);
... }
if (j != 2) { // A partir d'ici, on ne peut plus utiliser ce i
int j = 0; // interdit
...
j = 3 * i;
...
}
...
}
3
Les boucles conditionnelles Il y a 3 structures de contrôle:
• les branchements conditionnels,
• les itérations, et
• les boucles conditionnelles.
1
System.out.println("Entrez le nombre de notes");
int nombreDeNotes = clavier.nextInt(); Indique le début
int nombreDeNotes; de la boucle
Comment forcer l'utilisateur à entrer
double somme = 0; une note supérieure à 0 ? do {
System.out.println("Entrez le nombre de notes");
if (nombreDeNotes > 0) { nombreDeNotes = clavier.nextInt();
for(int i = 1; i <= nombreDeNotes; ++i) { } while(nombreDeNotes <= 0);
System.out.println("Entrez la note numero " + i);
double note = clavier.nextDouble(); Corps de la boucle:
somme = somme + note; Il est exécuté au moins une fois dans le
} cas de la boucle do..while
System.out.println("Moyenne = " + somme / nombreDeNotes);
} Condition. Elle est testée juste après chaque exécution du corps de la boucle:
• si elle est vraie, le corps de la boucle est exécuté une nouvelle fois;
• si elle est fausse, on sort de la boucle.
La différence est que la condition est testée avant d’entrer dans la boucle. Si la
• Les instructions à l'intérieur de la boucle do…while sont toujours exécutées au moins une fois.
condition est fausse, les instructions dans la boucle ne sont donc pas exécutées.
• Si la condition ne devient jamais fausse, les instructions dans la boucle sont répétées
indéfiniment !
2
Exemple Erreurs classiques
Il n'y a pas de ; à la fin de la condition du while...:
int i = 100;
do { while (i < 10); // !!
++i;
Le point-virgule est considéré comme le corps de la boucle,
System.out.println("bonjour"); et l'instruction ++i est après la boucle.
} while (i < 10);
sera interprété comme
affichera une fois bonjour. Si i est inférieur à 10, on entre dans la boucle pour ne jamais
Dans les 2 cas,
en ressortir puisque la valeur de i ne sera jamais modifiée.
la condition i < 10 est fausse. while(i < 10)
;
int i = 100; ++i;
while (i < 10) {
System.out.println("bonjour");
} En revanche, il y a un point-virgule à la fin du do..while:
n'affichera rien. do {
++i;
} while(i < 10);
3
int nombreDeNotes; Comment trouver la condition ?
do {
System.out.println("Entrez le nombre de notes"); On veut répéter la boucle tant que le nombre de notes est incorrect,
nombreDeNotes = clavier.nextInt(); le nombre de notes est incorrect si il est inférieur ou égal à 0,
if (nombreDeNotes <= 0) { ce qui donne la condition précédente:
System.out.println("il faut entrer un nombre supérieur a 0");
while (nombreDeNotes <= 0);
}
} while(nombreDeNotes <= 0);
4
Supposons qu'on veuille en plus limiter le nombre d'essais à 3.
On peut ajouter une variable qui va compter le nombre d'essais utilisés:
int nombreADeviner = 5;
la boucle doit être répétée
int nombreADeviner = 5; int nombreEntre; Comment modifier la condition pour que
int nombreEntre; int nombreEssais = 0; la boucle s'arrête quand le nombre
tant que l'utilisateur n'a pas trouvé le nombre à deviner, c'est-à-dire
tantdo
que nombreEntre est différent de nombreADeviner, d'essais dépasse 3 ?
{ do {
la condition est donc:
System.out.println( "Entrez un nombre entre 1 et 10"); System.out.println("Entrez un nombre entre 1 et 10");
nombreEntre = clavier.nextInt(); nombreEntre = clavier.nextInt();
} while(nombreEntre != nombreADeviner); ++nombreEssais;
} while( condition ? );
System.out.println("Trouve");
System.out.println("Trouve");
int nombreADeviner = 5;
int nombreEntre;
int nombreEssais = 0;
do {
System.out.println("Entrez un nombre entre 1 et 10");
int nombreADeviner(5);
la boucle doit être répétée
int nombreEntre;
nombreEntre = clavier.nextInt();
++nombreEssais;
tantint
quenombreEssais(0);
l'utilisateur n'a pas trouvé le nombre à deviner et qu'il reste des essais,
} while(nombreEntre != nombreADeviner && nombreEssais < 3);
c'est-à-dire
tantdoque
{ nombreEntre est différent de nombreADeviner et que Si on veut afficher un message pour indiquer à l'utilisateur s'il a trouvé le nombre ou
cout << "Trouve" << endl;
cout << "Entrez un nombre entre 1 et 10" << endl; si il a épuisé ses essais, on peut ajouter après la boucle:
nombreEssais est inférieur à 3,
cin >> nombreEntre;
la condition est donc:
nombreEssais++;
if (nombreEntre == nombreADeviner) {
System.out.println("Trouve");
} while(nombreEntre != nombreADeviner && nombreEssais < 3);
} else {
System.out.println("Perdu. Le nombre etait " + nombreADeviner);
}
5
int nombreADeviner = 5;
int nombreEntre;
int nombreEssais = 0;
do {
System.out.println("Entrez un nombre entre 1 et 10");
nombreEntre = clavier.nextInt();
++nombreEssais;
} while(nombreEntre != nombreADeviner && nombreEssais < 3);
6
Itérations : introduction
Il y a 3 structures de contrôle:
• les branchements conditionnels,
• les itérations, et
• les boucles conditionnelles.
le programme affichera les carrés des 5 premiers entiers: Déclaration et initialisation: Incrémentation:
n'est exécutée qu'une seule fois, exécutée à la fin de chaque tour de boucle. Elle permet
avant d'entrer dans la boucle de changer la valeur du compteur de boucle (ici, la
le carre de 0 vaut 0 variable i).
le carre de 1 vaut 1
le carre de 2 vaut 4 Rappel: ++i; ajoute 1 à la variable i. Cette instruction
le carre de 3 vaut 9 fait la même chose que i = i + 1;
le carre de 4 vaut 16
1
Comme pour le if, les accolades ne sont obligatoires que si plusieurs instructions
doivent être répétées.
for(int i = 0; i < 5; ++i) { Si il n'y a qu'une seule instruction, on peut ne pas utiliser d'accolades:
System.out.println("le carre de " + i + " vaut " + i * i); for(int i = 0; i < 5; ++i)
} System.out.println("i = " + i);
Corps de la boucle: Mais, toujours comme pour le if, il est conseillé de garder les accolades:
Bloc d'instructions qui seront exécutées for(int i = 0; i < 5; ++i) {
à chaque tour de boucle. System.out.println("i = " + i);
}
Pas-à-pas i
La variable i est déclarée et initialisée à 0
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
▌ ▌
2
i i
0 0
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
System.out.println("le carre de " + i + " vaut " + i * i); System.out.println("le carre de " + i + " vaut " + i * i);
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
▌ le carre de 0 vaut 0
▌
i i
0 1
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
System.out.println("le carre de " + i + " vaut " + i * i); System.out.println("le carre de " + i + " vaut " + i * i);
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
le carre de 0 vaut 0 le carre de 0 vaut 0
▌ ▌
3
i i
1 1
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
System.out.println("le carre de " + i + " vaut " + i * i); System.out.println("le carre de " + i + " vaut " + i * i);
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
le carre de 0 vaut 0 le carre de 0 vaut 0
le carre de 1 vaut 1 le carre de 1 vaut 1
▌ ▌
i i
4 5
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
System.out.println("le carre de " + i + " vaut " + i * i); System.out.println("le carre de " + i + " vaut " + i * i);
} }
Ce qui s'affiche dans la fenêtre Terminal: Ce qui s'affiche dans la fenêtre Terminal:
le carre de 0 vaut 0 le carre de 0 vaut 0
le carre de 1 vaut 1 le carre de 1 vaut 1
le carre de 2 vaut 4 le carre de 2 vaut 4
le carre de 3 vaut 9 le carre de 3 vaut 9
le carre de 4 vaut 16 le carre de 4 vaut 16
▌ ▌
4
Syntaxe de l'instruction for
System.out.println("5 multiplie par 1 vaut " + 5 * 1); System.out.println("5 multiplie par 1 vaut " + 5 * 1);
System.out.println("5 multiplie par 2 vaut " + 5 * 2); System.out.println("5 multiplie par 2 vaut " + 5 * 2);
System.out.println("5 multiplie par 3 vaut " + 5 * 3); System.out.println("5 multiplie par 3 vaut " + 5 * 3);
System.out.println("5 multiplie par 4 vaut " + 5 * 4); System.out.println("5 multiplie par 4 vaut " + 5 * 4);
System.out.println("5 multiplie par 5 vaut " + 5 * 5); System.out.println("5 multiplie par 5 vaut " + 5 * 5);
... ...
à il faut utiliser une boucle for pour éviter cette répétition. par
for(int i = 1; i <= 10; ++i) {
System.out.println("5 multiplie par " + i + " vaut " + 5 * i);
}
La variable i prend ici les valeurs de 1 à 10.
5
Que s'affiche-t-il quand on exécute le code :
A: 0p 1 2p 3 4p
B: 0p 1 2 3 4
C: 0 1 2p 3 4
?
D: 0p 1p 2p 3p 4p
6
Exemples d'autres formes de boucles for
approfondissements et
la variable p prendra les valeurs de 0, 2, 4, 6, 8 (p += 2 est équivalent à p = p + 2);
1. On s'est trompé sur la condition: 1. On s'est trompé sur la condition:
Par exemple: Par exemple:
for(int i = 0; i > -1; ++i) { // !!! for(int i = 0; i > -1; ++i) { // !!!
1
Pas de point-virgule (;) à la fin de Attention aux accolades
l'instruction for for(int i = 0; i < 5; ++i)
Les instructions suivantes n'affichent qu'une seule fois la chaine "bonjour": System.out.println("i = " + i);
for(int i = 0; i < 10; ++i); System.out.println("Bonjour");
System.out.println("bonjour");
affiche:
i = 0
Le point-virgule seul est considéré comme une instruction (qui ne fait rien). i = 1
i = 2
Le corps de la boucle est donc constitué de cette instruction qui ne fait rien: i = 3
for(int i = 0; i < 10; ++i) i = 4
Bonjour
;
System.out.println("bonjour"); Interprétation:
for(int i = 0; i < 5; ++i)
i prendra les valeurs de 0 à 10, puis l'ordinateur sortira de la boucle, et exécutera l'instruction System.out.println("i = " + i);
System.out.println("bonjour"); System.out.println("Bonjour");
une seule fois.
1. Ça ne fera sans doute pas ce que vous voulez: n'oubliez pas que la boucle for, de son System.out.println("Entrez la note numero 3");
côté, incrémente la variable i. double note3 = clavier.nextDouble();
2
Sans boucle for, en n'utilisant que 2 variables: Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4:
Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4: Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4:
3
Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4: Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4:
Pour vérifier le programme précédent, supposons que l'utilisateur entre les notes 5, 4, 6 et 4:
double somme = 0;
Même programme en utilisant une boucle for.
note
System.out.println("Entrez la note numero 1");
double note = clavier.nextDouble();
somme = somme + note; 6
System.out.println("Entrez la note numero 2"); double somme = 0;
somme
note = clavier.nextDouble();
somme = somme + note;
for(int i = 1; i <= 4; ++i) {
System.out.println("Entrez la note numero 3"); 9 System.out.println("Entrez la note numero " + i);
note = clavier.nextDouble();
double note = clavier.nextDouble();
somme = somme + note;
somme = somme + note;
System.out.println("Entrez la note numero 4"); }
note = clavier.nextDouble();
somme = somme + note;
System.out.println("Moyenne = " + somme / 4);
System.out.println("Moyenne = " + somme / 4);
4
Comment modifier le code pour laisser l'utilisateur choisir le nombre de notes ?
note
5
double somme = 0; somme double somme = 0;
Il y a un bug!
5
Une solution:
Boucles imbriquées
System.out.println("Entrez le nombre de notes"); Reprenons l'exemple précédent de la table de multiplication par 5:
int nombre_de_notes = clavier.nextInt();
for(int i = 1; i <= 10; ++i) {
System.out.println("5 multiplie par " + i + " vaut " + 5 * i);
double somme = 0;
}
if (nombre_de_notes > 0) { Supposons qu'on veuille maintenant afficher toutes les tables de multiplication, de 2 à 10.
for(int i = 1; i <= nombre_de_notes; ++i) {
System.out.println("Entrez la note numero " + i); Il suffit de mettre la boucle précédente dans une autre boucle, et de remplacer le 5 par...ce qu'il
double note = clavier.nextDouble(); faut.
somme = somme + note;
}
affiche 9 fois la table de multiplication par 5 affiche la table de multiplication par 2, puis par 3, jusque 10.
6
j j
j i j i
7
j i j i
j i j
8
j j
j i j i
9
Que s'affiche-t-il quand on exécute le code :
Itérations
if (i == j) {
System.out.print("*");
} else {
System.out.print(j);
A: C:
} *123 ****
} *123 ****
}
System.out.println(""); *123 ****
?
B: D:
012* *123
012* 0*23
012* 01*3
B: D:
?
0 0123
01 0123
012 0123
1
Rencontre du 5e type
Types avancés I (en Java) Ils permettent de représenter, dans des variables, des concepts simples du monde
modélisé dans le programme :
dimensions, sommes, tailles, expressions logiques, ...
Jamila Sam
Jean-Cédric Chappelier Cependant, de nombreuses données plus sophistiquées ne se réduisent pas à un
Vincent Lepetit objet informatique élémentaire.
Faculté I&C
+ un langage de programmation évolué doit donc fournir le moyen de composer
les types élémentaires pour construire des types plus complexes, les types
composés.
38 Dugenou 1.70 38 M
22 Pahut 1.63 22 F
I Toute variable de type évolué, comme les tableaux ou les chaînes de
caractères (String) que vous allez voir dans ce cours, stocke une référence
(adresse) vers une valeur :
I tableaux v
I structures de données hétérogènes String v = "Welcome";
(par exemple, « un enregistrement » dans le tableau de droite ci-dessus)
I chaînes de caractères ref
"Welcome"
(par exemple, le « nom »)
I ...
Types de base et types évolués (2) Petit exemple introductif
I Toute variable de type de base stocke directement une valeur
I Toute variable de type évolué stocke une référence vers une valeur
+ Attention : ceci a une très grande incidence sur la sémantique des Supposons que l’on souhaite écrire
opérateurs = et == en Java ! Score Écart à la moyenne
un programme de jeu à plusieurs
1000 -1860
+ Cela a aussi un incidence sur l’affichage joueurs.
1500 -1360
2490 -370
I double x = 13.5 veut dire « J’affecte à x la valeur 13.5 »
6450 3590
I String s = "coucou" veut dire « J’affecte à s une référence à la chaîne de ... ...
caractères coucou » Commençons modestement par... deux joueurs.
En clair, si v1 et v2 sont de type évolué :
I v1 = v2 affecte l’adresse de v2 à la variable v1
I v1 == v2 compare l’adresse de v2 avec celle de v1
I System.out.println(v1); affiche l’adresse de v1 (dans le cas général)
Nous y reviendrons . . .
Solution avec les moyens actuels Solution avec les moyens actuels (2)
... System.out.println ("Score Joueur 1:");
Scanner keyb = new Scanner(System.in); int score1 = keyb.nextInt();
System.out.println ("Score Joueur 2:");
// Lecture des donnees et calculs int score2 = keyb.nextInt();
System.out.println ("Score Joueur 1:"); System.out.println ("Score Joueur 3:");
int score1 = keyb.nextInt(); int score3 = keyb.nextInt();
System.out.println ("Score Joueur 2:"); System.out.println ("Score Joueur 4:");
int score2 = keyb.nextInt(); int score4 = keyb.nextInt();
// Calcul de la moyenne System.out.println ("Score Joueur 5:");
double moyenne = (score1 + score2); int score5 = keyb.nextInt();
moyenne /= 2;
// Affichages // calcul de la moyenne
System.out.println("Score Ecart Moyenne"); double moyenne = (score1 + score2 + score3 + score4 + score5);
System.out.println(score1 + " " + (score1 - moyenne)); moyenne /= 5;
System.out.println(score2 + " " + (score2 - moyenne));
...
Les crochets indiquent que la variable peut contenir Exemple : avec des littéraux :
plusieurs éléments du type spécifié
int[] scores = {1000, 1500, 2490, 6450};
Il existe deux techniques pour initialiser les éléments : Exemple : avec des expressions :
1. Dans l’instruction de déclaration int[] scores = {(2500 * 10),(4200 * 10)};
2. Dans des instructions séparées
int[] scores
int[] scores
Il est impératif que l’élément auquel vous voulez accéder existe effectivement !
Affichage d’un tableaux de taille fixe Accès aux éléments d’un tableau (1)
Très souvent, on voudra accéder aux éléments d’un tableau en effectuant une
itération sur ce tableau.
Le code suivant :
Il existe en fait au moins trois façons d’itérer sur un tableau :
double[] t1 = {1.1, 2.2, 3.4} ; I avec les itérations sur ensemble de valeurs
System.out.println(t1);
for(Type element : tableau)
affiche la référence au tableau t1, donc une adresse. + Type est le type des éléments du tableau
I avec une itération for « classique » :
Si l’on veut faire afficher les entrées du tableau référencé par t1, il faut prévoir une
boucle (itération) ! for(int i=0; i < TAILLE; ++i)
+ TAILLE ? ? voir plus loin
I avec des itérateurs (non présenté dans ce cours)
Accès aux éléments d’un tableau (2) Nombre d’éléments d’un tableau
Pour connaître la taille d’un tableau :
I nomTableau.length
Attention, les itérations sur ensemble de valeurs : Exemple :
for(Type element : tableau)
est très simple et élégant mais : int[] scores = {1000, 1500, 2490, 6450};
System.out.println(scores.length); // 4
I ne permet pas modifier le contenu du tableau boolean[] bs = {true, false};
I ne permet d’itérer que sur un seul tableau à la fois : il n’est pas possible de System.out.println(bs.length); // 2
traverser en une passe deux tableaux pour les comparer par exemple
I ne permet l’accès qu’à un seul élément : on ne peut pas par exemple comparer Attention ! length donne le nombre possible d’éléments. Le remplissage effectif
un élément du tableau et son suivant du tableau n’a pas d’importance !
I itère d’un pas en avant seulement.
Exemple :
Attention !
1. Problème d’indice I L’indice est toujours un int
I Il faut respecter les bornes du tableau :
2. Accès avant la construction du tableau
+ Toujours énumération de [0] à [T-1] (où T est la taille du tableau)
Exemple : Exemple :
int[] entiers1 = {1, 2, 3}; // Déclaration-initialisation int[] entiers1 = {1, 2, 3}; // Déclaration-initialisation
entiers1[0] = 4; // OK entiers1[0] = 4; // OK
int[] entiers2; // Déclaration int[] entiers2; // Déclaration
entiers2[0] = 4; // Erreur ! entiers2 = new int[10]; // Initialisation
entiers2[0] = 4;
Types de base / Types évolué (rappel) Types de base / Types évolué (rappel)
a=b
a=b
Type de base Type évolué
Type de base Type évolué
a=2 a = new int[4];
nouveau tableau a=2 a [1] = 3;
a a
3 2 a a
3 2
0 1 3 2 6
b b
3 b b
3
tableau[i]
new int[nbJoueurs][nbParties]; { 4, 5, 6 },
4 5 6
{ 7, 8 },
{ 9, 0, 1 } 7 8
scores[i] est un tableau de nbParties entiers }; 9 0 1
tableau[2][1]
+ scores est bien un tableau de tableaux.
tableau[2] : 7 8
En faisant une analogie avec les mathématiques, un tableau à une dimension représente
donc un vecteur, un tableau à deux dimensions une matrice et un tableau de plus de deux
dimensions un tenseur.
int[][] y = { {1, 2}, {3, 4}, {5, 6} }; Cas 2 : On ne connaît pas tous les éléments lors de la déclaration
1. 1re boucle : fait varier le 1er indice 1. 1re boucle : fait varier le 1er indice
Exemple : Exemple : Variante (tous les éléments de la 1re dimension ayant la même taille)
for(int i = 0; i < y.length; ++i) { System.out.println(y[0].length); // 2
for(int j = 0; j < y[i].length; ++j) { System.out.println(y[1].length); // 2
System.out.println(y[i][j]); System.out.println(y[2].length); // 2
} for (int i = 0; i < y.length; ++i)
} for (int j = 0; j < y[0].length; ++j)
System.out.println (y[i][j]);
Le type String Le type char
char c9 = '\a';
+ Pour les String l’affichage est défini de sorte à prendre en compte la référence
pointée plutôt que la référence elle-même. C’est une exception.
Concaténation Concaténation
Les combinaisons suivantes sont possibles pour la concaténation de deux chaînes :
chaine1 + chaine2 produit une nouvelle chaîne associée à la valeur littérale String + String
constituée de la concaténation des valeurs littérales de chaine1 et de chaine2. String + typeDeBase typeDeBase + String
Exemple : constitution du nom complet à partir du nom de famille et du prénom : où String correspond à une variable ou une valeur littérale de type String, et
typeDeBase à une variable ou une valeur littérale de l’un des types de base (char,
String nom;
String prenom; boolean, double, int etc.).
....
nom = nom + " " + prenom;
Exemple revisité (avec char) :
Important ! La concaténation ne modifie jamais les chaînes concaténées. Elle String nom;
effectue une copie de ces chaînes dans une autre zone en mémoire. String prenom;
....
nom = nom + ' ' + prenom;
Concaténation (Non-)Egalité de Strings
Les opérateurs suivants :
Les concaténations de la forme String+char constituent donc un moyen très
pratique pour ajouter des caractères à la fin d’une chaîne. == égalité
!= non-égalité
De même la concaténation char+String permet l’ajout d’un caractère en début de
chaîne.
testent si deux variables String font référence (ou non) à la même zone mémoire
Exemple : ajout d’un ’s’ final au pluriel :
(occupée par une chaîne de caractères).
String reponse = "solution";
//...
Ceci est le cas lorsque les variables de types String ont été initialisées au moyen
if (n > 1) { de littéraux
reponse = reponse + 's';
} Exemple : utilisation de l’opérateur !=
System.out.println(s1.equals(s4)); // true
s1 s3 System.out.println(s1.equals(s2)); // false
s2 "abc"
s4
Comment faire pour comparer les contenus référencés plutôt que les
références ?
+ Traitement spécifique aux String
Les tableaux en Java Les ArrayList
Un tableau dynamique, est une collection
de données homogènes,
dont le nombre peut changer au cours du
En Java, on utilise : déroulement du programme,
par exemple lorsqu’on ajoute ou retire
taille initiale connue a priori ? des éléments au/du tableau.
non oui
oui ArrayList ArrayList Les tableaux dynamiques sont définis en Java par le biais du type
taille pouvant varier lors de
l’utilisation du tableau ? tableaux de taille tableaux de taille ArrayList
non
fixe fixe
Pour les utiliser, il faut tout d’abord importer les définitions associées à l’aide de la
directive suivante :
import java.util.ArrayList;
à placer en tout début de fichier
Une variable correspondant à un tableau dynamique se déclare de la façon Un tableau dynamique initialement vide (sans aucun élément) s’initialise comme
suivante : suit :
ArrayList<type> identificateur; ArrayList<type> identificateur = new ArrayList<type>();
où identificateur est le nom du tableau et type correspond au type des éléments où identificateur est le nom du tableau et type correspond au type des éléments
du tableau. du tableau.
Le type des éléments doit nécessairement correspondre à un type évolué.
Exemple :
Exemple :
ArrayList<String> tableau = new ArrayList<String>();
ArrayList<String> tableau;
Méthodes spécifiques Méthodes spécifiques
Un certain nombre d’opérations sont directement attachées au type ArrayList. Quelques fonctions disponibles pour un tableau dynamique nommé tableau, de
type ArrayList<type> :
L’utilisation de ces opérations spécifiques se fait avec la syntaxe suivante :
nomDeTableau.nomDeMethode(arg1, arg2, ...); tableau.size() : renvoie la taille de tableau (un entier)
tableau.get(i) : renvoie l’élément à l’indice i dans le tableau (i est un entier
Exemple : compris entre 0 et tableau.size() - 1)
ArrayList<String> prenoms = new ArrayList<String>(); tableau.set(i, valeur) : affecte valeur à la case i du tableau (cette case doit
avoir été créée au préalable)
System.out.println(prenoms.size()); // affiche 0
class ArrayListExemple {
public static void main(String[] args){
ArrayList<String> liste = new ArrayList<String>(); En Java, à chaque type de base correspond un type évolué prédéfini :
}
}
}
Exemple Exemple
Ecrivons un programme qui (ré)initialise un tableau dynamique d’entiers en les Ecrivons un programme qui (ré)initialise un tableau dynamique d’entiers en les
demandant à l’utilisateur, qui peut demandant à l’utilisateur, qui peut
I ajouter des nombres strictement positifs au tableau I ajouter des nombres strictement positifs au tableau
tab.add(2000);
tab.add(2000);
System.out.println((tab.get(0)).equals(tab.get(1))); // true
(Non-)Egalité de Strings (Non-)Egalité de Strings (2)
String s1 = "abc";
// s1 pointe vers le littéral "abc"
Les opérateurs suivants : String s2 = "abc";
// idem (donc même zone mémoire que s1)
String s3 = s2; // s3 stocke la même adresse que s2
String s4 = s1 + "";
// s4 contient l'adresse d'une nouvelle chaîne
== égalité // (construite par concaténation)
System.out.println((s1==s2) && (s2==s3)); // affiche true
!= non-égalité System.out.println(s4); // affiche abc
System.out.println((s1==s4)); // affiche false
testent si deux variables String font référence (ou non) à la même zone mémoire Situation en mémoire :
(occupée par une chaîne de caractères).
"abc" + ""
Ceci est le cas lorsque les variables de types String ont été initialisées au moyen
de littéraux s1 s3
s2 "abc"
Exemple : utilisation de l’opérateur != s4
while (reponse != "oui") ....; Comment faire pour comparer les contenus référencés plutôt que les
références ?
+ Traitement spécifique aux String
Comparaison de String
String s1 = "abc";
String s2 = "aBc";
String s4 = s1 + "";
System.out.println(s1.equals(s4)); // true
System.out.println(s1.equals(s2)); // false
Les char d’un String Les chars d’un String (2)
I L’instruction chaine.charAt(index) donne le caractère occupant la position
index dans la String chaine
I L’instruction chaine.indexOf(caractere) donne la position de la première
occurence du char caractere dans la String chaine, et -1 si caractere n’est Exercice : qu’affichera le programme suivant :
pas dans chaine. String essai = "essai";
I chaine1.length() donne la taille (c’est-à-dire le nombre de caractères) de String test = "";
chaine1. Attention : il y a une paire de parenthèses ; différent des tableaux ! for (int i = 1; i <= 3; ++i) {
test = test + essai.charAt(6-2*i);
Exemple : test = essai.charAt(i) + test;
}
String s1 = "abcmbx"; System.out.println(test);
int longueur = s1.length(); // 6
char c1 = s1.charAt(0); // a
char c2 = s1.charAt(longueur - 1); // x
int i = s1.indexOf('b'); // 1
+ Les caractères sont numérotés comme les éléments d’un tableau (à partir de 0)
Un littéral introduit par l’utilisateur suite à une instruction de lecture n’est pas dans
le pool des littéraux
Pour récupérer un caractère (char) avec la classe Scanner, il faut faire : Pour qu’il y soit, il faut l’y mettre explicitement au moyen de intern
// Lire la ligne qui contient un caractère Exemple
Scanner keyb = new Scanner(System.in);
Scanner s = new Scanner(System.in);
String s = keyb.nextLine();
String response;
do {
// Prendre comme caractère le premier élément de la String
response = s.nextLine();
char c = s.charAt(0);
//on met le littéral lu dans le pool
response = response.intern();
System.out.println("Read: " + response);
// sans le intern, la boucle ne s'arrête pas!
} while (response != "oui");
Traitements spécifiques aux chaînes replace
Nous avons vu que certains traitements sont spécifiques aux String.
Ils s’utilisent en fait tous avec la syntaxe particulière suivante :
nomDeChaine.nomDeTraitement(arg1, arg2 ...); chaine.replace(char1, char2) : construit une nouvelle chaîne valant chaine où
char1 est remplacé par char2.
Ces traitements s’appellent des méthodes en Java.
Exemple :
+ Ils produisent toujours une nouvelle chaîne de caractères String exemple = "abracadabra";
String avecDesEtoiles = exemple.replace(’a’, ’*’);
substring
+ les fonctions
Notion de réutilisabilité : illustration Notion de réutilisabilité : illustration
if if if
...
...
...
do { do { do {
z=f(u,v,t); do {
f
...
} while } while } while } while
...
...
for
...
for for
...
...
Les étapes 1 et 2 n’ont pas lieu pour une méthode sans arguments. int score (double points, double tempsJeu)
{ // ... comme avant ... }
Les étapes 4 et 5 n’ont pas lieu pour une méthode sans valeur de retour (void).
L’évaluation de l’appel d’une méthode peut être schématisé de la façon suivante : « Appeler la méthode f » = utiliser la méthode f : x = 2 * f(3);
« 3 est passé en argument » = (lors d’un appel) la valeur 3 est copiée dans un
static double g() { paramètre de la méthode :
x = 2 * f(3);
int y, z; static int f(int x) {
...
... « la méthode retourne la valeur de y » = l’expression de l’appel de la méthode sera
. . . z = f(y) . . .
|{z} ... remplacée par la valeur retournée
... return . . . ;
return y;
} } }
...
x = 2 * f(3);
static int f{. . . }
Autres exemples : « cos(0) retourne le cosinus de 0 », « cos(0) retourne 1 ».
Le passage des arguments (1) Le passage des arguments (2)
Considérons la situation suivante (pseudo-code) : Java ne manipule pas les types élémentaires comme les types évolués :
static void methode(Type v) { Modifier v pour un type élémentaire n’a qu’une seule interprétation possible :
// traitement modifiant v v
}
Type v1 = .. ; // initialisation de v1
methode(v1);
Pour un type évolué :
// v1 EST-ELLE MODIFIEE ICI OU NON???
v
Il y a donc deux questions à poser au lieu d’une : En Java, il n’existe que le passage par valeur : une méthode travaille toujours sur
une copie de la valeur qui lui est passée en paramètre
static void methode(Type v) { // Type :type EVOLUÉ
// traitement modifiant l'objet référencé par v
// traitement modifiant v lui même (référence) val x
} 1
// ailleurs:
Type v1 = ..; // initialisation de v1 copie
methode(v1);
//1. v1 est-elle modifiée ici?
//2. l'objet référencé par v1 est-il modifié 1
// ici?
Passage par valeur : type élémentaire Passage par valeur : type évolué
static void methode(Type v) { // Type :type EVOLUÉ
// traitement modifiant l'objet référencé par v
// traitement modifiant v lui même (référence)
static void methode(Type v) { }
// traitement modifiant v // ailleurs:
} Type v1 = ..; // initialisation de v1
methode(v1);
// ailleurs, dans le programme principal, //1. v1 est-elle modifiée ici?
// par exemple: //2. l'objet référencé par v1 est-il modifié
Type v1 = .. ; // initialisation de v1 // ici?
methode(v1);
// v1 EST-ELLE MODIFIEE ICI OU NON??? I On a toujours un passage par valeur donc la référence v est une copie de v1.
I Cependant, Type étant évolué, l’argument qui est donné à methode lors de
+ Si Type est un type élémentaire
la réponse à la question dans le code est NON !! l’appel methode(v1) est une copie de la référence à v1 (son adresse) : l’objet
pointé par v est le même que l’objet pointé par v1. Toute modification faite
sur l’objet référencé via v est donc visible via v1 !
+ La réponse à la question 2 est donc OUI (et reste non pour la question 1)
Exemple de passage par valeur (type élémentaire) Type évolué : modification de la référence
public static void main(String[] args) { public static void main(String[] args) {
int val = 1; int[] tab = {1};
m(val); m(tab); // tab (référence)
System.out.println(" val=" + val); // PASSAGE PAR VALEUR AUSSI
} System.out.println(" tab[0]= " + tab[0]);
}
static void m(int x) { static void m(int[] x) {
x = x + 1; int[] t = {100};
System.out.print(" x=" + x); x = t; //Modification de la référence
} //(on met une autre adresse dans x)
System.out.print("x[0]= " + x[0]);
}
L’exécution de ce programme produit l’affichage :
x=2 val=1
L’exécution de ce programme produit l’affichage :
Ce qui montre que les modifications effectuées à l’intérieur de la méthode m() x[0]= 100 tab[0]= 1
ne se répercutent pas sur la variable extérieure val associée au paramètre x et
Les modifications faites dans la méthode sur la référence elle-même ne sont pas
passée par valeur.
visibles à l’extérieur de la méthode !
Type évolué : modification de l’objet référencé Entête
Toute méthode est caractérisée par un entête
public static void main(String[] args) {
int[] tab = {1};
m(tab); I nom
System.out.println(" tab[0]= " + tab[0]); I paramètres
}
static void m(int[] x) { I type de (la valeur de) retour
x[0] = 100; // modification de l'objet
liste de paramètres
// référencé par x z }| {
System.out.print("x[0]= " + x[0]); Syntaxe : type nom ( type1 id_param1 , ..., typeN id_paramN )
}
Au niveau de ce cours, on ajoutera le mot clé static au début de chaque entête.
L’exécution de ce programme produit l’affichage : Mais deviendra une exception dans le cours « Programmation Orientée Objet ».
x[0]= 100 tab[0]= 100
Les modifications faites dans la méthode sur l’objet référencé restent visibles à Exemples d’entêtes :
l’extérieur de la méthode ! static double moyenne(double x, double y)
(on a copié dans x la référence tab : x et tab pointent sur le même tableau.)
static int nbAuHasard()
Remarques sur l’instruction return (2/4) Remarques sur l’instruction return (3/4)
public static void main(String[] args) Par convention, tout programme Java doit avoir une méthode main, qui est appelée
{ automatiquement quand on exécute le programme.
int val = saisieEntier();
System.out.println(val);
} L’entête autorisée pour main est :
Jamila Sam
Jean-Cédric Chappelier
Vincent Lepetit
Faculté I&C
Le jeu
| | | | | | | |
| | | | | | | |
| | | |X| | | |
| | |X|O|O|X|O|
| | |O|X|X|X|O|
| |O|O|X|X|O|X|
==1=2=3=4=5=6=7==
| | | | | | | |
| | | | | | | |
| | | |X|O| | |
| | |X|O|O|X|O|
| | |O|X|X|X|O|
| |O|O|X|X|O|X|
==1=2=3=4=5=6=7==
Le joueur O a gagne !
Développement
type_des_elements[][]
Type des éléments
type_des_elements ?
...
int[][] grille;
grille[0][0] = VIDE;
grille[2][3] = JAUNE;
Premières méthodes
I initialise : méthode qui initialise une grille ;
I affiche : méthode qui affiche une grille.
Méthode initialise
private final static int VIDE = 0;
private final static int JAUNE = 1;
private final static int ROUGE = 2;
...
...
...
...
...
joue(grille, 3, rouge);
joue(grille, 2, jaune);
joue(grille, 3, rouge);
Tester la méthode joue
static void joue(int[][] grille, int colonne, int couleur)
{
// on parcourt la colonne en partant du bas jusqu'à trouver une case vide :
int ligne = grille.length - 1;
while (grille[ligne][colonne] != VIDE) {
--ligne;
}
// on remplit la case vide trouvée :
grille[ligne][colonne] = couleur;
}
...
static void main()
{
int[][] grille = new int[6][7];
initialise(grille);
affiche(grille);
joue(grille, 3, ROUGE);
affiche(grille);
joue(grille, 2, JAUNE);
affiche(grille);
joue(grille, 3, ROUGE);
affiche(grille);
Méthode joue
static joue(int[][] grille, int colonne, int couleur)
{
// on parcourt la colonne en partant du bas jusqu'à trouver une case vide,
// ou jusqu'en haut de la colonne si la colonne est pleine :
int ligne = grille.length - 1;
// si on n'est pas arrivé jusqu'en haut de la colonne, on remplit la case vide trouvée,
// sinon c'est que la colonne est pleine et le coup n'est pas valide :
if (!pleine) {
grille[ligne][colonne] = couleur;
return true;
} else {
return false;
}
}
Méthode joue
static boolean joue(int[][] grille, int colonne, int couleur)
{
// on parcourt la colonne en partant du bas jusqu'à trouver une case vide,
// ou jusqu'en haut de la colonne si la colonne est pleine :
int ligne = grille.length - 1;
// si on n'est pas arrivé jusqu'en haut de la colonne, on remplit la case vide trouvée,
// sinon c'est que la colonne est pleine et le coup n'est pas valide :
if (!pleine) {
grille[ligne][colonne] = couleur;
return true;
} else {
return false;
}
}
Tester la nouvelle méthode joue
public static void main(String[] args)
{
int[][] grille = new int[6][7];
initialise(grille);
affiche(grille);
if (!valide) {
System.out.println("impossible d'ajouter un pion sur cette colonne");
}
affiche(grille);
}
}
Tester la nouvelle méthode joue
static boolean joue(int[][] grille, int colonne, int couleur)
{
int ligne = grille.length - 1;
boolean pleine = false;
while ((!pleine) && (grille[ligne][colonne] != VIDE)) {
if (ligne == 0) {
pleine = true;
} else {
--ligne;
}
}
if (!pleine) {
grille[ligne][colonne] = couleur;
return true;
} else {
return false;
}
}
...
for(int i = 0; i < 10; ++i) {
boolean valide = joue(grille, 3, ROUGE);
if (!valide) {
System.out.println("impossible d'ajouter un pion sur cette colonne");
}
affiche(grille);
}
Une version alternative de la méthode joue
static boolean joue(int[][] grille, int colonne, int couleur)
{
// si la colonne est pleine, le coup n'est pas valide :
if (grille[0][colonne] != VIDE) {
return false;
}
// on parcourt la colonne en partant du bas jusqu'à trouver une case vide :
int ligne = grille.length - 1;
while (grille[ligne][colonne] != VIDE) {
--ligne;
}
// on remplit la case vide trouvée :
grille[ligne][colonne] = couleur;
return true;
}
Encore une autre version de la méthode joue
static boolean joue(int[][] grille, int colonne, int couleur)
{
int ligne = grille.length - 1;
do {
System.out.print("Joueur ");
if (couleurJoueur == JAUNE) {
System.out.print("X");
} else {
System.out.print("O");
}
System.out.println(" : entrez un numéro de colonne");
do {
demandeEtJoue(grille, couleurJoueur);
affiche(grille);
do {
demandeEtJoue(grille, couleurJoueur);
affiche(grille);
++compteur;
ligne = ligne + dirLigne;
colonne = colonne + dirColonne;
return compteur;
}
Méthode compte
static int compte(int[][] grille,
int ligneDepart, int colonneDepart,
int dirLigne, int dirColonne)
{
int compteur = 0;
++compteur;
ligne = ligne + dirLigne;
colonne = colonne + dirColonne;
return compteur;
}
Retour sur la méthode estCeGagne
static boolean estCeGagne(int[][] grille, int couleurJoueur)
{
for(int ligne = 0; ligne < grille.length; ++ligne) {
for(int colonne = 0; colonne < grille[ligne].length; ++colonne) {
int couleurCase = grille[ligne][colonne];
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
return false;
Retour sur la méthode estCeGagne
int couleurCase = grille[ligne][colonne];
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
return false;
}|
Retour sur la méthode estCeGagne
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
return false;
}|
Retour sur la méthode estCeGagne
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(compte(grille, ligne, colonne, -1, +1) >= 4) ||
return false;
}|
Retour sur la méthode estCeGagne
if (couleurCase == couleurJoueur) {
if (
// en diagonale, vers le haut et la droite:
(ligne >= 3 && colonne <= grille[ligne].length - 4 &&
compte(grille, ligne, colonne, -1, +1) >= 4) ||
if (
// en diagonale, vers le haut et la droite:
(ligne >= 3 && colonne <= colonneMax &&
compte(grille, ligne, colonne, -1, +1) >= 4) ||
if (
// en diagonale, vers le haut et la droite:
(ligne >= 3 && colonne <= colonneMax &&
compte(grille, ligne, colonne, -1, +1) >= 4) ||
affiche(grille);
affiche(grille);
if (gagne) {
// attention, on a change la couleur pour la couleur de l'autre joueur !
if (couleurJoueur == JAUNE) {
System.out.println("Le joueur O a gagne !");
} else {
System.out.println("Le joueur X a gagne !");
}
} else {
System.out.println("Match nul !");
}
}
Fonction plein
Méthode plein
// plein(grille)
static boolean plein(int[][] grille)
{
// Si on trouve une case vide sur la premiere ligne, la grille n'est pas pleine :
for(int cellule : grille[0]) {
if (cellule == VIDE) {
return false;
}
}
On peut en effet se poser la question puisque si i vaut 0, le second opérande (25 / i > 12)
de l’expression conditionnelle va causer une division par zéro s’il est évalué.
La réponse à cette question est en fait NON en raison de ce que l’on appelle l’évaluation
paresseuse ("lazy evaluation" en anglais) : l’évaluation des opérandes se fait de la gauche
vers la droite et seuls les opérandes nécessaires à la détermination de la valeur logique sont
évalués. Dans le cas de notre exemple, comme l’opérande (i != 0) est faux, l’expression
conditionnelle est fausse et (25 / i > 12) n’est pas évaluée.
De façon générale :
– pour une condition de la forme X1 && X2 && ... && Xn, les opérandes Xi ne
sont évalués que jusqu’au premier opérande faux (s’il existe, auquel cas la condition est
fausse, sinon elle est vraie) ;
– pour une condition de la forme X1 || X2 || ... || Xn, les opérandes ne sont évalués
que jusqu’au premier opérande vrai (s’il existe, auquel cas la condition est vraie, sinon
elle est fausse).
L’évaluation des conditions suivantes ne causera donc aucun problème à l’exécution même
si i vaut 0 :
– (i != 0) && (25 / i > 12)
– (i == 0) || (25 / i < 12)
1
L’instruction conditionnelle switch
J. Sam, J.-C. Chappelier, V. Lepetit
1 L’instruction switch
Ainsi une séquence d’instructions if telle que celle-ci :
if (i == 1)
Instructions 1
else if (i == 12)
Instructions 2
...
else if (i == 36)
Instructions N
else
Instructions N+1
switch (i) {
case 1:
Instructions 1;
break;
case 12:
Instructions 2;
break;
...
case 36:
Instructions N;
break;
default:
Instructions N+1;
break;
}
1
Lors de l’exécution d’un instruction switch, l’expression suivant le mot clé switch est
évaluée 1 . L’exécution se poursuit alors au niveau du case correspondant au résultat de
l’évaluation.
Cette exécution continue en séquence, sans aucune évaluation de condition, jusqu’à ce que
le mot réservé break soit rencontré ou que la fin de l’instruction soit atteinte.
La première portion de code ci-dessus n’est donc équivalente, du point de vue de l’exé-
cution, qu’à un switch où chaque cas de termine par un break (comme c’est le cas de
l’exemple ci-dessus).
Dans le cas où l’évaluation de l’expression ne retourne pas une valeur correspondant à un
case, le programme exécute les instructions correspondant au cas par défaut (précédées
du mot clé default).
switch (a+b) {
case 2:
case 8: instruction2; // lorsque (a+b) vaut 2 ou 8
case 4:
case 3: instruction3; // lorsque (a+b) vaut 2, 3, 4 ou 8
break;
case 0: instruction1; // exécuté uniquement lorsque
break; // (a+b) vaut 0
default: instruction4; // dans tous les autres cas
break;
}
2
Le fait de ne pas mettre d’instruction en face d’un cas permet simplement de mettre en
œuvre un « ou logique » entre plusieurs conditions : on exécute instruction2 si (a +
b) vaut 2 ou 8 par exemple. Cela permet d’éviter des répétitions inutiles de code. Mais il
vaut peut être mieux dans un premier temps éviter ce genre d’optimisation, peu facilement
compréhensible à la première lecture...
3 switch vs if..else
switch est moins général que if..else :
– la valeur sur laquelle on teste doit être soit de type intégral : char, int, byte, short
. . . ou String (mais ce dernier type seulement depuis Java 7) ;
– l’expression testée est toujours la même (le « i » ou « a+b » des exemples précédents) ;
– les cas doivent être des constantes (pas de variables).
3
i++ ou ++i ?
J.-C. Chappelier, J. Sam, V. Lepetit
On rencontre souvent dans la littérature et dans des exemples de code l’utilisation de l’opé-
rateur d’incrémentation postfixé, comme par exemple dans l’expression i++, alors que
dans le cours nous avons opté pour une notation préfixée, par exemple ++i.
Y a-t-il une différence et si oui quelle est-elle ? Et pourquoi un tel choix pour le cours ?
1 Effet et valeur
Avant tout vous ne pourrez pas pleinement comprendre ce dont il s’agit si vous ne distin-
guez pas ce que fait une expression de ce qu’elle vaut.
En Java, toute expression fait quelque chose et vaut quelque chose. Elle vaut quelque chose
en ce sens qu’on peut par exemple la mettre à droite d’une affectation.
Par exemple, « i = 3 » est une affectation, mais en Java, c’est aussi une expression. C’est
une expression qui fait une affectation de la valeur 3 à la variable i. Mais cette expression
vaut aussi quelque chose, c’est-à-dire que l’on peut parfaitement écrire : j = i = 3; ce
qui signifie : j = (i = 3); ou encore : « met dans j la valeur de l’expression ‘i =
3’ ». Ceci est tout à fait licite en Java.
Je m’empresse immédiatement de dire qu’il faut absolument éviter d’utiliser ce genre d’ex-
pressions qui rendent le code beaucoup moins intelligible. Rappelez vous que vous devez
toujours écrire le code le plus clair possible !
Que vaut donc l’expression « i = 3 » ? Il se trouve qu’elle vaut le résultat de l’affectation,
donc 3 ici. Ainsi j = (i = 3); est la même chose que
i = 3;
j = i;
2 i++ et ++i
Je peux maintenant expliquer la différence entre les expressions « i++ » et « ++i »:
– ces deux expressions font exactement la même chose : elles incrémentent i ;
– en revanche, leurs valeurs sont différentes.
1
Si vous n’utilisez pas la valeur de ces expressions 1 , il n’y aura donc pour vous aucune
différence.
Utiliser leur valeur signifierait par exemple écrire des choses comme : j = ++i;, ce que
je vous déconseille une fois de plus de faire.
Leur seule différence est donc au niveau de leur valeur : i++ vaut la valeur de i avant
incrémentation alors que ++i vaut la valeur de i après incrémentation.
Si l’on prend l’exemple suivant :
int i = 3;
int j = i; // i et j ont la même valeur
int k = 0;
int l = 0;
k = ++i; // opérateur préfixé
l = j++; // opérateur postfixé
A l’issue de ce bout de code, i et j auront tous les deux la valeur 4 (les deux opérateurs font
la même chose), mais k aura la valeur 4 alors que l aura la valeur 3 (les deux opérateurs
ne valent pas la même chose).
3 Lequel préférer ?
Encore une fois, si vous n’utilisez pas la valeur de retour et si vous n’êtes pas dans un
langage qui permette de surcharger (= redéfinir) ces opérateurs 2 , alors il n’y aura pour
vous aucune différence pratique entre ces deux notations.
Ceci dit, il y deux bonnes raisons de préférer la notation préfixée (++i) à celle postfixée
(i++) : l’une conceptuelle et l’autre plus pragmatique dans les langages où ces opérateurs
peuvent être surchargés.
La raison conceptuelle est la suivante : quelle opération voulons nous exprimer par i++
(ou ++i) ? Si c’est « i = i + 1 » alors la seule qui lui soit totalement équivalent est
++i.
En effet, quelle est la valeur de l’expression i = i + 1 ? C’est bien la valeur de i après
incrément, la même que celle de ++i.
En d’autres termes, par quoi remplacer i = i + 1 dans
j = i = i + 1;
Le seul remplacement valide entre i++ et ++i est le second :
j = ++i;
2
D’un point de vue pratique maintenant : si le langage permet de surcharger ces opérateurs
(C++, qui est l’objet de notre autre cours, le permet), alors il faut toujours préférer la
notation préfixée (++i) car elle est sensiblement moins coûteuse.
Je prétends en effet, sans le démontrer ici, que l’opérateur préfixé peut s’implémenter sans
aucune copie, alors qu’il est impossible de faire l’opérateur postfixé sans copie. L’opérateur
postfixé coûte donc toujours une copie de plus que l’opérateur préfixé. Si ces opérateurs
sont surchargés pour des objets coûteux à copier, alors la différence de performance se fera
sentir !
Pour ces deux raisons, il est donc préférable d’utiliser l’opérateur préfixé (++i) à celui
postfixé (i++). Et c’est pour cela qu’il en est ainsi dans ce cours.
3
Limitations des types entiers et réels
V. Lepetit, J. Sam, et J.-C. Chappelier
Cependant, tous ces types ne peuvent représenter que des valeurs comprises dans un certain
intervalle. Pour donner une idée de l’ordre de grandeur, voici les intervalles utilisés par
Java :
Plus l’intervalle est grand, plus une variable du type correspondant occupera de place en
mémoire.
Pour voir l’impact que peuvent avoir ces limitations en pratique, vous pouvez exécuter le
programme suivant 1 :
public class Depassement {
int n = 10;
System.out.println( n );
n = n * n;
System.out.println( n );
1. Ce programme pourra se réécrire de façon plus compacte dès que vous aurez vu les boucles.
1
n = n * n;
System.out.println( n );
n = n * n;
System.out.println( n );
n = n * n;
System.out.println( n );
n = n * n;
System.out.println( n );
Ce programme initialise la variable n à 10, et l’élève au carré plusieurs fois. Les valeurs
affichées devraient donc être toutes des puissances de 10, mais en exécutant le programme,
vous verrez que ce n’est pas le cas pour les dernières valeurs, qui sont trop grandes pour
être représentées correctement par le type int. Vous pouvez également changer le type de
n de int à long et short pour voir l’impact sur les valeurs calculées.
Soyez donc vigilants quand votre programme doit travailler avec de grandes valeurs !
Mais en pratique, la limitation de ces types affecte surtout la précision des valeurs représen-
tées : les valeurs réelles, y compris celles entre les intervalles donnés ci-dessus, ne peuvent
pas toutes être représentées. Considérons le programme suivant :
double a = 37.0;
double racine = Math.sqrt(a);
2
}
}
double a = 37.0;
double racine = Math.sqrt(a);
if (a == racine * racine) {
System.out.println( "ok" );
}
n’affiche rien, contrairement à ce qu’on pourrait s’attendre. Si vous devez absolument com-
parer des valeurs de type double vous pouvez utiliser un test tel que celui-ci :
double a = 37.0;
double racine = Math.sqrt(a);
où epsilon est une très petite valeur et abs calcule la valeur absolue. Cette valeur de-
vrait être choisie selon la précision du type utilisé, mais comment déterminer cette valeur
idéalement sort largement du cadre de ce cours.
2. Nous utilisons parfois de tels tests dans notre cours, mais uniquement par souci de simplicité.