Langages objets Les opérateurs et les expressions
Opérateurs et expressions
Instructions de contrôle
Débugage
M2 Pro CCI, Informatique
Emmanuel Waller, LRI, Orsay
originalité des notions d'opérateur et
d'expression
classiques : arithmétiques, relationnels, logiques en général (hors Java, C, C++) :
manipulation de bits expressions : formées à l'aide d'opérateurs :
ont une valeur
affectation, incrémentation
ne font rien
règles de priorité instructions :
règles de conversion de type font quelque chose
n'ont pas de valeur
les opérateurs arithmétiques
présentation des opérateurs
Java : binaires : + - * / : opérandes de même type (int, long,
float, double), mais conversions implicites permettent
i++ aussi byte, char, short
a une valeur
unaire : - +
fait quelque chose
% (modulo) : entiers, flottants
i = 5;
7 / 2 vaut 3 : entier
fait quelque chose
a une valeur les priorités relatives des opérateurs
expression; est une instruction (conséquences pour règles
fonctions) désambigüer par parenthèses
les conversions implicites dans les
expressions
comportement en cas d'exception ex :
il y a circonstances où un opérateur ne peut fournir un int n, p; double x; (n * x) + p
résultat correct n et p convertis par compilateur en double
entiers : division par zéro : arrêt du programme + résultat : double
message
règles, type char, être soigneux, nombreux cas,
flottants : jamais d'arrêt : Infinity, -Infinity, NaN
surprises, subtilités, ...
les opérateurs relationnels les opérateurs logiques
< <= > >= == != ! : négation
renvoient un booléen & : et
== et != s'appliquent à : booléens, objets, ^ : ou exclusif
tableaux | : ou inclusif
&& : et, avec court-circuit
|| : ou inclusif, avec court-circuit
ex : if (i<t.length && t[i] == 0) ...
l'opérateur d'affectation usuel : = les opérateurs d'incrémentation et de
i = 5 est une expression qui :
effetcue une action : l'affectation de la valeur 5 à i décrémentation
possède une valeur : celle de i après affectation : 5 l'opérateur ++ : but : remplacer i = i + 1
c = b + 3 : expression ++i
à gauche de = : référence à un emplacement dont incrémente i de 1
on peut modifier la valeur (variables, etc.) valeur : i après incrémentation
possible : i = j = 5 : i++ : idem, valeur : i avant incrémentation
évalue j = 5, qui vaut 5, et l'affecte à i i++; équivalent ++i;
valeur finale de toute l'expression : 5 -- décrémentation
subtilités de conversion cause affectation tous types numériques
les opérateurs d'affectation élargie l'opérateur de cast
i += k équivalent à i = i + k le programmeur peut forcer la conversion d'une
+= -= *= /= %= ^= &= (et aussi expression dans un autre type de son choix avec
manipulations de bits : <<= >>= <<<=) cast
subtilités conversions
ex : int n, p; (double) (n/p) : valeur :
1.calcul de n/p : entier
2.conversiondu résultat en double
les opérateurs de manipulation de bits l'opérateur conditionnel
travailler sur le motif binaire (octets bit à bit) if (a>b)
d'une valeur max = a;
bit à bit : &, |, ^ else
décalage : <<, >>, >>>, ~ max = b;
max = si (a>b) alors a sinon b
max = a>b ? a : b
L'opérateur d'affectation usuel
opérateurs et expressions : Les opérateurs d'incrémentation et de
récapitulatif décrémentation : ex : i++, i--
Les opérateurs d'affectation élargie : ex : +=
Originalité des notions d'opérateur et d'expression L'opérateur de cast
Les opérateurs arithmétiques Les opérateurs de manipulation de bits
Les conversion implicites dans les expressions L'opérateur conditionnel
Les opérateurs relationnels (Delannoy chapitre 4)
Les opérateurs logiques
Les instructions de contrôle de Java séquencement
bloc
if
switch
do ... while
while
for
break et continue
Le séquencement le bloc d'instructions
suite d'instructions (simple, de contrôle, bloc)
le corps d'une fonction est une séquence placées entre accolades { et }
d'instructions
ex : vu dans chap. 1
elles sont exécutées l'une après l'autre dans cet
ordre (sauf cas particuliers présentés plus loin :
ex inutiles :
break, continue, exceptions) {}
{ i = 1; }
{ ; } // rappel chap. 2 : existe instruction vide : ;
remarque : inutile ajouter ; après { . . . }
syntaxe :
L'instruction if
if (condition)
instruction1 imbrication des instructions if
[ else ex : if (a) if (b) c else d
instruction2 ] else correspond-il à if (a) ou if (b) ?
condition : différent : ex : a faux : d ou rien ?
booléenne quelconque
un else se rapporte toujours au dernier if
parenthèses obligatoire toute condition Java
rencontré auquel un else n'a pas encore été
instruction1 et instruction2 quelconques : simple, attribué
de contrôle, bloc ex : if (a) {if (b) c else d}
[ . . . ] : facultatif
ne rien faire si a faux
exemple L'instruction switch
2 paramètres, afficher expression sur le 2ème en ex : à partir d'un entier n, afficher sa valeur en
fonction différentes valeurs du premier français, et « grand » s'il est trop grand (en gros)
ci-joint
démonstration
int n;
n = ... lecture clavier ...
switch (n) {
case 0 : System.out.println("zéro");
break; 1.évaluer expression switch (expr) : vaut i
case 1 : System.out.println("un");
break;
2.rechercher dans bloc une étiquette case x, x
case 3 : System.out.println("trois");
expression constante int, où x est cette valeur
break; 3.si existe se brancher à cette instruction
default : System.out.Println("grand");
sinon passer à l'instruction qui suit le bloc switch
}
System.out.println("Au revoir");
ex : n = 0 :
l'étiquette default : on s'y branche si aucun
étiquette ne correspond
zéro
switch (n) {
Au revoir
case 0 : System.out.println("zéro");
sans les break : n = 0 :
break;
zéro
case 1 : System.out.println("un");
un
break;
trois
default : System.out.Println("grand");
Au revoir
}
System.out.println("Au revoir");
ex : n = 3 : grand
switch (n) {
case 0 : System.out.println("zéro"); ex : n = 1
break; petit
case 1 :
moyen
case 2 : System.out.println("petit");
Au revoir
case 3 :
case 4 : possible :
case 5 : System.out.println("moyen"); plusieurs instructions par étiquette
break; étiquettes sans instruction
default : System.out.Println("grand");
}
System.out.println("Au revoir");
exemple l'instruction do . . . while
ex : à partir d'un entier, lui retirer 3 et afficher ce
2 paramètres, afficher expression sur le 2ème en qu'il reste en recommençant jusqu'à arriver à zéro
fonction différentes valeurs du premier int n = 29;
ci-joint do {
démonstration n = -3;
System.out.println("il en reste" + n);
} while (n >= 2);
répète instruction (ici bloc) tant que condition
vraie
exemple
Ci-joint condition testée que après que tout le bloc fini
Démonstration (donc corps au moins une fois)
do instruction while (condition)
n est la « variable de boucle » : elle contrôle les
passages
exemples l'instruction while
ex : payer un café à 29 centimes avec des pièces
do ; while (...); // infinie ? action ? de 3 centimes
do { } while (...); // idem ? int n = 0;
do { } while (true); // idem ? while (n < 29) {
System.out.println("il manque encore" + (29 - n));
do instruction while (true);
n += 3; // ici on paye
// utile si sortie par break
}
répète instruction (ici bloc) tant que condition
vraie
exemple
Ci-joint condition examinée avant corps boucle (donc
Démonstration possible corps jamais)
while (condition) instruction
for ([ initialisation ]; [ condition ]; instruction) {
l'instruction for ...
vue dans chap. 2 }
for (i=1, j=3; i<5; i++, j+=i) { ... } condition absente considérée comme vraie
suite d'expressions séparés par des virgules initialisation : choix exclusif : déclaration ou liste
d'expressions (virgule n'est pas un opérateur, cf
for (int i=1, j=3; . . .) { ... }
C, C++)
ou une déclaration : int une seule fois, puis
impossible : for (int i=1, double x=0; ...) { ... }
variables, éventuellement initialisées (sinon ici
inutile), séparées par des virgules attention compteur non entier (erreur d'arrondi) :
portée de i et j : corsp du for, inconnues après for (double x=0.; x!=1.0; x+=1) { ... } : infinie
Boucles imbriquées : exemple 1
exemples :
Afficher 5 lignes, contenant chacune 0 1 2 3 4
for ( ; ; ) ; // infinie ? action ?
Principe : transparent suivant
for ( ; ; ) { } // idem ?
for ( ; ; ) instruction // idem ?
Ci-joint
remarque Démonstration
for est une boucle conditionnelle
pas vraie boucle avec compteur
for (i=0; i<5; i++) { ... i-- ... } : possible, déconseillé
pour i de 0 à 4
afficher la ligne Boucles imbriquées : exemple 2
afficher la ligne =
pour j de 0 à 4
Afficher 5 lignes, la première contenant 0, la
deuxième 0 1, etc. la dernière 0 1 2 3 4
print j
println
Ci-joint
pour i de 0 à 4 Démonstration
pour j de 0 à 4
print j
println
Noter le bloc dans la boucle extérieure
Les instructions de branchement break
déjà vu : dans switch
inconditionnel break et continue possible dans les trois boucles :
interrompt le déroulement de la boucle en passant à
l'instruction suivant la boucle
utile que si break dépend d'un if (sinon sortie dès
premier tour)
si boucles imbriquées, break sort uniquement de la
plus interne
impossible hors boucle ou switch
sortir de plusieurs boucles : break avec étiquette
for (int i=1; i<=4; i++) {
continue System.out.println("début du tour " + i);
if (i<3) continue;
permet de passer prématurément au tour de System.out.println("fin du tour " + i);
boucle suivant (la fin du tour en cours n'est pas }
faite) System.out.println("après la boucle");
branchement avant les « incrémentations » début du tour 1
début du tour 2
si boucles imbriquées : concerne que interne début du tour 3
sortie plusieurs niveaux : continue avec étiquette fin du tour 3
début du tour 4
fin du tour 4
après la boucle
les instructions de contrôle : récapitulatif
séquencement
remarque
bloc
if syntaxe Java identique à C et C++ (sauf détail
switch syntaxe programme principal et déclaration
fonction)
do ... while
autrement dit : « Java sans objets c'est
while simplement C » (Java conçu pour)
for Toujours pas d'objets
break et continue
(Delannoy chapitre 5)
débugage (et méthodologie de
Exemple : tirages aléatoires
développement)
Bibliothèque Math
Indépendant du chapitre « instructions de
contrôle »
Tirer un nombre réel aléatoire dans [0,1[
(vérifier si bornes ouvert ou fermé)
Ci-joint
Démonstration
« méthodologie de développement »
débugage (et méthodologie de
développement) résoudre le problème sur un exemple à la main
écrire algorithme/modules en français sur papier
méthodologie de développement
données
notion d'erreur
traitements
erreurs lors de la compilation écrire le code Java
erreurs lors de l'exécution faire tourner totalement un fragment du problème
exemple l'étendre
rem : exécuter programme chaque fois que ajouté 5 lignes
tester et débuguer
mieux : cahier des charges, spécification, tests, codage
notion d'erreur erreurs lors compilation
deux catégories :
syntaxe : détectées lors de la compilation fichier source peut présenter erreurs de syntaxe
sémantique (logique) : constatées pendant l'exécution compilateur :
Un informaticien (même débutant) doit les détecte
systématiquement : affiche pour chaque erreur message indiquant ce qu'il
Les lire a compris
Les comprendre en totalité ne génère pas d'exécutable
la fenêtre doit être assez grande pour voir la
totalité des messages
causes erreurs compilation
erreurs pendant l'exécution
environnement : fichier pas trouvé par
compilateur exécution d'un programme compilé peut conduire
fichier pas dans répertoire, non sauvegardé, erreur à des « opérations » qui n'ont pas de sens en Java
d'extension, de casse, d'orthographe (coquille), etc. : erreurs sémantiques (logiques)
syntaxe ex : division par zéro, indice tableau hors bornes
résoudre une seule erreur, la première, puis la JVM :
recompiler (elle peut avoir créé les autres)
interrompt l'exécution
message d'erreur : numéro de ligne du fichier, la
affiche le contexte du programme au moment de
ligne, ce que le compilateur comprend, ce qu'il
attendait l'erreur
causes erreurs exécution Exemple
environnement : mêmes problèmes que Expliquer ce qui a mené aux messages d'erreur
compilation, pas le bon nom de classe (indépendants) suivants
sémantique (logique) : détailler le message
une ligne par fonction en cours au moment de l'erreur
(ex : f(g(h(x))))
valeur des paramètres et ligne du fichier source
se lit de bas en haut
etc.
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 6 Listes.java:20: cannot resolve symbol
at Liste.creer(Listes.java:22) symbol : variable args
at Listes.main(Listes.java:56) location: class Liste
tmp.suivant = new Liste(Integer.parseInt(args[i]));
^
« méthodologie pour débuguer » délégués ?
bugs sémantiques (à l'exécution)
localiser le bug : en affichant toutes les variables