Teaching - 2i002 - (TME: sujets)


2i002 : Introduction à la programmation Objet

Exercices supplémentaires

Exercice 1 : Evaluation d'expression

Qu'affiche le morceau de programme suivant ?

boolean b;  
char c = 'd';  
int x = 8;  
b = false;  

if (!(b && x >= 0) || c >= 'a' && c <= 'z' && x > 20) {      
        if (x == 99 && c == 'N') System.out.println("Bonjour");    
        else System.out.println("Good Morning");  
} else {      
        if (x == 0 ||  c == 'B') System.out.println("Ciao");
        else System.out.println("Kenavo");  
}
 

Ce programme affiche "Good Morning"

En utilisant une évaluation abrégée, on a :

  • pour le 1er if : non (faux et vrai) ou (vrai et vrai et faux), donc vrai (priorité des opérateurs : d'abord les [$>$]= et [$<$]=, puis les && et enfin le ||)
  • pour le 2eme if : (faux et faux), donc faux

Exercice 2 : Evaluation et affichage

L'affichage dans une fenêtre Console se fait grâce à l'appel de la méthode println :

System.out.println(argument);

Cette méthode admet un seul argument de type chaine de caractères . Si ce n'est pas le cas, cet argument est évalué et converti en chaîne de caractères avant affichage. Aide : voir les informations au début de l'exercice (exo:cstEtconversion).

Qu'affichent les instructions suivantes ? (Il peut y avoir des erreurs)

System.out.println(34);

34

System.out.println(1+2);

3 Evaluation (addition)

System.out.println("1"+"2");

12 Evaluation (concatenation)

System.out.println(1+1.0);

2.0 Evaluation (conversion en double)

System.out.println('1'+"2");

12 Evaluation (concatenation)

System.out.println(1+"2");

12 Evaluation (concatenation)

System.out.println(`1'+`2');

99 char convertis en int('1' code 49 et '2' code 50)

System.out.println('1'+'c'+"bon");

148bon addition ('1' code 49 et 'c' code 99), puis concaténation

System.out.println(true);

true

System.out.println(true && false);

false

System.out.println(false && 1 == 0);

false

System.out.println(false || 1 == 0);

false

System.out.println(1+1 == 2);

true

System.out.println('a' < 'B');

false Les majuscules sont avant les minuscules (code 'a' : 97 ; code 'B' : 66)

System.out.println("true" > "false");

ERREUR l'opérateur [$>$] ne peut pas s'appliquer sur les chaînes de caractères

System.out.println(true + false);

ERREUR l'opérateur + ne peut pas s'appliquer sur des booléens

System.out.println("true" + "false");

truefalse

System.out.println(true > false);

ERREUR l'opérateur [$>$] ne peut pas s'appliquer sur des booléens

Exercice 3 : Constantes et conversion de types

On peut sauter les questions 3 et 4, si on ne veut pas passer de temps sur les problèmes de codage.

  • Une constante numérique entière est codée dans un int .
  • Une constante numérique réelle est codée dans un double .
  • Les caractères sont codés en Unicode sur 16 bits. Les majuscules ont un code (en base 10) compris entre 65 ('A') et 90 ('Z'); les minuscules entre 97 ('a') et 122 ('z') ; les chiffres entre 48 ('0') et 58 ('9')
  • Dans une expression numérique, un char est converti en entier non négatif.

Pour aborder quelques problèmes liés à la syntaxe et aux types primitifs, on considère la classe suivante :

public class TestExp {  
        public static void main(String[] args){      
                int x = 0;      
                double y = 1;      
                double z = 2;      
                if (x < y < z)          
                        System.out.println("OK");      
                else System.out.println("FAUX");  

        }
}
 

Faire remarquer que les chaînes de caractères sont entre "...";

Question 1 :

Détailler la conversion générée par le compilateur lors de l'instruction double y = 1 .

1 est une constante entière codée dans un int. Cet int est converti en double, la valeur résultante est affectée à y.

Question 2 :

Montrer que l'expression x [$<$] y [$<$] z est incorrecte (erreur de compilation). La modifier pour qu'il n'ait plus d'erreur.

(x [$<$] y) est une comparaison entre deux nombres. Le résultat est de nature booléenne c'est-à-dire égal à true ou false. Un booléen ne peut être inférieur ou supérieur à un nombre. Ce sont deux entités qui ne sont pas comparables.

if ( x [$<$] y && y [$<$] z)

Pas besoin de parenthèses en plus (Cf. priorité des opérateurs)

Question 3 :

On écrit maintenant : char x = 0; . Comment s'analyse cette instruction ?

Quelle est la valeur binaire codée dans x ?

0 est une constante entière codée dans un int. x est une variable de type char codée sur 16 bits. On peut recopier un nombre entier dans un char, pourvu que la valeur puisse tenir sur 16 bits, c'est-à-dire soit inférieure ou égale à 65 535 (216-1). La valeur binaire prise par x est alors la valeur binaire du nombre situé à droite du symbole d'affectation. En l'occurrence zéro.

On peut dire que le code de x est zéro (tous les bits à 0). Le type char peut être utilisé dans les calculs.

Question 4 :

On écrit maintenant : char x = `0' . Analyser cette instruction. Quelle est la valeur décimale de x ? Exprimer cette valeur en binaire sur 16 bits. `

0' est une constante de type char codée selon le code Unicode sur 16 bits. Le code est recopié dans x. c'est-à-dire 48 en base 10, 30 en hexadécimal et 0000 0000 0011 0000 en binaire.

Question 5 :

Deux classes de test ont été définies précédemment. Quels noms donner aux fichiers de ces deux classes ? Comment compiler ces fichiers ? Comment exécuter ce programme ?

Nom classe = nom fichier

javac ****.java ou javac *.java

java ***** (attention, il ne faut pas mettre le .class)

Quelle est la syntaxe des commandes de compilation et d'exécution ?

javac nom de fichier

java nom de la classe qui contient la méthode main

Exercice 4 : Priorité des opérateurs

int a, b, c, d;
a = 10; b = 3; c = 3;
double x, y, z;
Question 1 :

Parenthéser l'expression suivante :

a = b = c = d = 1;

L'affectation est le seul opérateur qui s'évalue de la droite vers la gauche (et non de la gauche vers la droite comme les autres)

Question 2 :

En vous référant à la table de priorité des opérateurs (en annexe page \pageref{sec:tabpriorite}), évaluer :

d = a*c/b;

d = (a*c)/b, deux opérateurs de même niveau, de gauche à droite, d = 10

d = a/b*c;

d = (a/b)*c ; deux opérateurs de même niveau, de gauche à doite, mais division entière, d = 9

y = 1 / 100;

y = 0.0, car division entière

x = 1; y = x / 100;

y = 0.01, car division réelle

Question 3 :

Parenthéser et indiquer les différentes conversions générées par le compilateur pour évaluer :

y = a + b * x / c;

y = (a + ((b * x)/c))

conversion de b en double, conversion de c en double, division réelle, conversion de a en double

Question 4 :

Parenthéser l'expression suivante. Les parenthèses doivent illustrer clairement l'ordre d'évaluation des expressions en Java.

y = 3 + a * x * y - 5 / z;

y = ((3 + ((a * x) * y)) - (5 / z));

Question 5 :

Parenthéser l'instruction, puis en donner une forme simplifiée :

y = c + 4 / 5 * Math.sin(x-3) - 3

y = ((c + ((4 / 5) * sin(x-3))) - 3)

comme 4 / 5 donne 0, on a donc y = c - 3

Autres exos possibles :

1) Ecrire une boucle qui calcule la somme des n premiers entiers

2) Trouver tous les nombres de 3 chiffres a,b,c tels que abc =a3+b3+c3

3) Afficher les tables de vérité

Exercice 5 : SFCF

Dans son programme de fidélisation, la société SFCF s'intéresse à ses plus fidèles voyageurs. L'analyse des besoins a permis de retenir pour un voyageur les caractéristiques suivantes :

nom, prénom, numéro adhérent, date de naissance, situation familiale, nombre d'enfants, nombre de points cumulés, montant en euros équivalent, statut de "super grand voyageur", taux de réduction.

Le statut de "super grand voyageur" s'obtient dès que le nombre de points cumulés atteint 5000 points. La situation familiale est codée par le premier caractère des libellés : C élibataire, M arié, P acsé, V euf, D ivorcé.

Question 1 :

Choisir un nom de variable et donner un type primitif, si possible, pour chacune des caractéristiques (voir annexe pour les types primitifs).

int nuAdherent (peut être aussi une chaîne) ; char SitFam; int nbEnfants; int nbPointsCumul; double mtEuros; boolean statutSGV; double tauxReduc;

Dans l'ensemble du fascicule, on mettra assez systématiquement des double et non des float

Dire des choses sur l'art et la manière d'écrire les noms de variables

On peut aussi introduire ici les types String et Date (et en profiter pour introduire la convention d'écriture pour les classes : minuscules/majuscules)

Question 2 :

Initialiser les variables correspondant aux caractéristiques suivantes : situation familiale, nombre d'enfants, nombre de points cumulés, montant en euros équivalent, statut de "super grand voyageur", taux de réduction. Par défaut, le voyageur est célibataire, n'est pas "super grand voyageur", n'a ni enfants, ni points cumulés et pas de réduction.

SitFam = 'C'; nbEnfants = 0; nbPointsCumul = 0; mtEuros = 0; statutSGV = false; tauxReduc =0;

Dire qu'on peut aussi faire l'initialisation en même temps que la déclaration.

char SitFam = 'C'; int nbEnfants = 0; int nbPointsCumul = 0; double mtEuros = 0; boolean statutSGV = false; float tauxReduc =0;

Faire remarquer que les caractères sont entre '...' et non "..."

Question 3 :

Lors de l'achat d'un billet, le client a gagné 500 points. Mettre à jour la variable correspondante et calculer le montant en euros équivalent sachant qu'un point vaut 1,50 €.

Lorsque le client constate qu'il peut obtenir un voyage gratuit, il choisit un voyage équivalent à 2000 points. Mettre à jour les variables en conséquence.

nbPointsCumul= nbPointsCumul+500; ou nbPointsCumul+=500;

mtEuros= nbPointsCumul*1.5; ou mtEuros+=500*1.5;

nbPointsCumul= nbPointsCumul-2000; ou nbPointsCumul-=21000;

mtEuros= nbPointsCumul*1.5; ou mtEuros-=2000*1.5;

Vérifier que les types sont compatibles et en profiter pour montrer les conversions de type implicites.

Question 4 :

Lorsque le nombre de points cumulés est supérieur à 5000, le client obtient le statut "super grand voyageur". Par ailleurs, s'il est "super grand voyageur", il bénéficie d'un taux de réduction à 5il bénéficie en outre d'une prime exceptionnelle de 100 points. Ecrire l'instruction qui permettra tester et de mettre à jour les variables concernées.

Insister sur la différence entre = et ==

if (nbPointsCumul >=5000) statutSGV=true;
// ou mieux:
statutSGV = nbPointsCumul >=5000;

Dans un premier temps, il peut être judicieux de faire uniquement le test sur le nombre d'enfants

if (nbEnfants<3)  
        tauxReduc=0.05;
else tauxReduc=0.10;

if (statutSGV) {
        if (nbEnfants<3)  
                tauxReduc=0.05;
        else tauxReduc=0.10;
}
if (sitFam != 'C') nbPointsCumul += 100;

Leur faire remarquer que ce n'est pas statutSGV == true, une maladresse qu'ils font souvent

Question 5 :

Pour l'impression des billets, la société SFCF souhaite aussi avoir une variable identite contenant le nom et le prénom du voyageur. Déclarer et initialiser cette variable.

String identite = nom+" "+prenom;

Insister sur la différence de signification du +. Dire qu'il s'agit bien ici d'une opération de concaténation.