Partie 1/2
Vendredi 9 novembre 2018 Formateur : Vincent Jug´ e
. vincent.juge
@u-pem.fr
Exercice 1.
Recopier le texte ci-dessous dans un fichier que l’on appelleraHello.javaet que l’on enregistrera : public class Hello {
public static void main(String[] args) { System.out.println("Hello!");
} }
Ouvrir une ligne de commande et aller dans le r´epertoire o`u a ´et´e enregistr´e le fichier Hello.java, puis compiler ce fichier `a l’aide de la commandejavac Hello.java. On obtient alors un fichier intitul´eHello.class, `a peu pr`es illisible, mais que l’on peutex´ecuter`a l’ade de la commandejava Hello.
Que voit-on s’afficher sur la ligne de commande ? Et que se passe-t-il si l’on change la phraseHello! pour la remplacer par la phraseBonjour `a tous !dans le fichierHello.java?
Exercice 2.
Recopier le code de la classeSomme, ci-dessous, dans un fichier que l’on appelleraSomme.javaet que l’on enregistrera. Que voit-on s’afficher sur la ligne de commande ?
public class Somme {
public static void main(String[] args) { int a = 2;
int b = 3;
int c = a + b;
int d = 4 + 5;
System.out.println(c);
System.out.println(d);
System.out.println(10 + 2);
} }
Que se passe-t-il si on remplace la ligneint a = 2;para = 2;? parint a = b;? parint a;?
Exercice 3.
Ecrire une classe´ Calcul, dans le fichierCalcul.java, qui calcule et affiche les valeurs de 2 + 2 et de 3×5. Le programme doit donc afficher :
4 15
Il n’y a pas d’espace au d´ebut et en fin de ligne et toutes les lignes, y compris la derni`ere, sont termin´ees par un retour `a la ligne.
Notez que l’on peut passer directement une valeur num´erique `a print et println. Plus exactement, il y a plusieurs fonctions avec le mˆeme nom et, dans ce cas, Java choisit laquelle appeler en fonction du type de l’argument.
Qu’affiche le code de la classeIntOrDoubleci-dessous ? Pouvez-vous expliquer pourquoi les deux lignes sont diff´erentes ? public class IntOrDouble {
public static void main(String[] args) { int a = 5;
int b = 2;
int c = a / b;
double A = 5;
double B = 2;
double C = A / B;
System.out.println(c);
System.out.println(C);
} }
Exercice 5.
Qu’affiche le code de la classeTwoVarci-dessous ? Pouvez-vous expliquer pourquoi les deux derni`eres lignes sont diff´erentes ? public class TwoVar {
public static void main(String[] args) { int a = 0;
int b = 0;
System.out.println(a);
System.out.println(b);
a = 1;
System.out.println(a);
System.out.println(b);
} }
Exercice 6.
Qu’affiche le code de la classeIncrementci-dessous ? Pouvez-vous expliquer pourquoi les deux lignes sont diff´erentes ? public class Increment {
public static void main(String[] args) { int a = 0;
System.out.println(a);
a = a + 1;
System.out.println(a);
} }
Le RER doit passer 1074 minutes apr`es minuit. Pour les usagers, cependant, il est indispensable de disposer d’un horaires en heures et minutes. Compl´eter les lignes h = ...; et m = ...; du code de la classe Heure ci-dessous pour afficher l’horaire de passage selon le formatheures:minutes.
public class Heure {
public static void main(String[] args) { int n = 1074;
int h = ...;
int m = ...;
System.out.print(h);
System.out.print(":");
System.out.println(m);
} }
On pourra utiliser l’op´erateur%, qui calcule le reste d’une division d’un entier par un autre.
Exercice 8.
Qu’affiche le code de la classeIfTestci-dessous ? public class IfTest {
public static void main(String[] args) { int n = 5;
int m = 2 + 2;
if (n > m) {
System.out.println("n est plus grand que m.");
} else {
System.out.println("n n’est pas plus grand que m.");
}
if (n == m + 1) {
System.out.println("n est ´egal `a m + 1");
} } }
Que se passe-t-il si on change la ligneint m = 2 + 2;pour la remplacer par la ligneint m = 2 + 3;?
Exercice 9.
On souhaite tester si l’entier 123456789 est divisible par 111. Compl´eter le code de la classe TestDiv ci-dessous pour qu’il affiche 123456789 est divisible par 111 si 123456789 est divisible par 111, et qu’il affiche 123456789 n’est pas divisible par 111sinon.
public class TestDiv {
public static void main(String[] args) { int n = 123456789;
int d = 111;
if (...) {
System.out.println("123456789 est divisible par 111");
} else {
System.out.println("123456789 n’est pas divisible par 111");
} } }
Ecrire une classe´ TestGrandqui teste affiche Grand si 1234×8765 est strictement plus grand que 4321×5678, et qui affichePetitsinon.
Exercice 11.
Qu’affiche le code de la classeWhileLoopci-dessous ? public class WhileLoop {
public static void main(String[] args) { int i = 0;
while (i < 10) {
System.out.println(i);
i = i+1;
} } }
Comment modifier ce code pour afficher les entiers compris entre 4 et 25 ? Les entiers pairs compris entre 4 et 25 ? Remarque : Au lieu d’´ecrirei = i+1;, on peut aussi ´ecrirei++;.
Exercice 12.
Qu’affiche le code de la classeForLoopci-dessous ? public class ForLoop {
public static void main(String[] args) { for (int i = 0; i < 10; i++) {
System.out.println(i);
} } }
Comment modifier ce code pour afficher les entiers compris entre 4 et 25 ? Les entiers pairs compris entre 4 et 25 ?
Exercice 13.
Compl´eter le code de la classe WhileSmallSquarepour qu’il affiche un par un, dans l’ordre croissant, les entiers n>0 tels quen261234. On souhaite que chaque entier soit affich´e sur une ligne diff´erente de celles des autres entiers.
public class WhileSmallSquare {
public static void main(String[] args) { int s = ....;
int n = ....;
while (....) {
System.out.println(n);
n++;
} } }
Peut-on s’en sortir en utilisant une boucleforplutˆot qu’une bouclewhile?
Remarque : En g´en´eral, on pr´ef`ere utiliser une boucleforsi, d’une ´etape sur l’autre, une seule variable change de valeur, et qu’elle change toujours de la mˆeme mani`ere, par exemple en croissant de 1. Dans les autres cas, on privil´egiera l’usage d’une bouclewhile.
Qu’affiche le code de la classeForImbriqueci-dessous ? Et si on change la valeur initiale de la variablen? public class ForImbrique {
public static void main(String[] args) { int n = 5;
for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) {
System.out.print(" ");
System.out.print(j);
}
System.out.println();
} } }
Exercice 15.
BAttention B Avant de traiter cet exercice, il faut appeler le formateur ou savoir comment mettre fin brutalement `a l’ex´ecution d’un programme Java.
Qu’affiche le code de la classeInfiniteLoopci-dessous ? Pouvez-vous expliquer pourquoi ? public class InfiniteLoop {
public static void main(String[] args) { for (int i = 1; 0 < i; i++) {
System.out.println(i);
} }
Exercice 16.
Qu’affiche le code de la classeSyracuseci-dessous ? Et si on change la valeur initiale den? public class Syracuse {
public static void main(String[] args) { long n = 100;
while (n > 1) {
System.out.println(n);
if (n % 2 == 0) { n = n / 2;
} else {
n = 3 * n + 1;
} } } }
Remarque : En g´en´eral, quand un programme contient une boucleforouwhile, il convient de s’assurer au pr´ealable que l’on pourra bien finir par en sortir. Cependant, ce n’est pas ´evident.
Par exemple, on pense que, quelle que soit la valeur de n choisie initialement, si elle est positive, alors le programme ci-dessus finit par afficher l’entier 1 avant de s’arrˆeter ; cela a pu ˆetre v´erifi´e exp´erimentalement pour des milliards de valeurs. N´eanmoins, cette affirmation n’a, `a ce jour, jamais pu ˆetre prouv´ee, et il se pourrait donc qu’elle soit en fait fausse.
Qu’affiche le code de la classeConcatci-dessous ? Pouvez-vous expliquer les r´esultats obtenus aux quatre derni`eres lignes ? public class Concat {
public static void main(String[] args) { String s = "Bonjour";
String t = " `a tous !";
String st = "Bonjour `a tous";
System.out.println(st);
String st2 = s + t;
System.out.println(s + t);
System.out.println(st2);
System.out.println("Bonjour" + " `a tous");
int n = 2 + 3;
System.out.println("n = " + n);
System.out.println("n = " + (2 + 3));
System.out.println(("n = " + 2) + 3);
System.out.println("n = " + 2 + 3);
} }
Remarque : Java fait de son mieux pour procurer `a l’utilisateur un maximum de souplesse dans l’affichage d’informations.
Cependant, cette souplesse peut aussi aboutir `a des r´esultats parfois surprenants et non d´esir´es. Il faut donc faire attention :
— utilis´e entre deux chaˆınes de caract`eres (String) ou entre une chaˆıne de caract`eres et autre chose, le symbole+est le symbole de laconcat´enationentre chaˆınes de caract`eres ; si on l’utilise entre une chaˆıne de caract`ere et un nombre, ce nombre est lui-mˆeme pr´ealablement transform´e en une chaˆıne de caract`eres ;
— utilis´e entre deux nombres, c’est le symbole de l’addition ;
— quand on utilise plusieurs symboles +d’affil´ee, Java effectue les additions (ou les concat´enations) de la gauche vers la droite.
Exercice 18.
Dans le code de la classeTableauci-dessous, on cr´ee nos premiers tableaux. Qu’affiche ce code ? public class Tableau {
public static void main(String[] args) { int[] tab = {1,3,5};
int a = 1;
System.out.println(tab[0]);
System.out.println(tab[1]);
System.out.println(tab[2]);
System.out.println(tab[a]);
int n = tab[0] + tab[1];
System.out.println(n);
} }
Que se passe-t-il si on remplace la ligneint a = 1;parint a = 3;? parint a = -1;? parint a = tab[0];?
Puisqu’il ne faut jamaisd´epasserd’un tableau, il est important d’en connaˆıtre la longueur. Qu’affiche le code de la classe LongueurTableauci-dessous ?
public class LongueurTableau {
public static void main(String[] args) { int[] tab1 = {1,3,5};
int[] tab2 = {0,1,2,3,4};
int[] tab3 = new int[8];
System.out.println(tab1.length);
System.out.println(tab2.length);
System.out.println(tab3.length);
int n = tab3[0];
System.out.println(n);
} }
Que se passe-t-il si on remplace la ligneint[] tab1 = 1,3,5;parint[] tab1;? et si, `a la place, on remplace `a la ligne int n = tab3[0];parint n = tab3[7];? parint n = tab3[8];?
Exercice 20.
Qu’affiche le code de la classeChangeTableauci-dessous ? Pouvez-vous expliquer pourquoi ? public class ChangeTableau {
public static void main(String[] args) { int[] tab = {1,3,5};
int a = tab[0];
System.out.println(a);
System.out.println(tab[0]);
tab[0] = 7;
System.out.println(a);
System.out.println(tab[0]);
a = tab[0];
System.out.println(a);
System.out.println(tab[0]);
} }
Exercice 21.
Qu’affiche le code de la classeFonction1ci-dessous ? public class Fonction1 {
public static int carre(int a) { return a * a;
}
public static void main(String[] args) { int a = 3;
int b = carre(a);
System.out.println(a);
System.out.println(b);
} }
Et si l’on remplace les lignesint a = 3;,int b = carre(a);etSystem.out.println(a);de la fonctionmainparint c = 3;,int b = carre(c); etSystem.out.println(c);?
Qu’affiche le code de la classeFonction2ci-dessous ? public class Fonction2 {
public static int fois2(int a) { int c = a * 2;
return c;
}
public static void main(String[] args) { int c = 3;
int b = fois2(c);
System.out.println(c);
System.out.println(b);
} }
Et si l’on remplace les lignesint c = a * 2;et return c;de la fonction fois2parint d = a * 2;et return d;?
Exercice 23.
Compl´eter le code de la fonction somme pour que le programme SommeEntiers ci-dessous affiche la somme des entiers compris entre 1 et 100.
public class SommeEntiers {
public static int somme(int n) { int sum = 0;
for (int i = 1; i <= n; i++) { ....
}
return sum;
}
public static void main(String[] args) { int n = 100;
int m = somme(n);
System.out.println(m);
} }
Et si l’on remplace le code de la fonctionmainpar la seule ligneSystem.out.println(somme(100));?
Exercice 24.
Quand on ex´ecute un programme Java en ligne de commande, on peut ajouter des arguments au programme que l’on ex´ecute, s´epar´es par des espaces. Ces arguments sont r´ecup´er´es dans le tableauString[] argsque l’on voit ´ecrit dans la fameuse lignepublic static void main(String[] args) {.
Qu’affiche le code de la classeAfficheArgsci-dessous ? On essaiera d’ex´ecuter le programmeAfficheArgsavec diff´erents arguments.
public class AfficheArgs {
public static void main(String[] args) { int l = args.length;
for (int i = 0; i < l; i++) { System.out.println(args[i]);
} } }
Compl´eter le code de la fonctionsommeTabpour que le programmeSommeTableauci-dessous affiche la somme des entiers compris dans le tableautab.
public class SommeTableau {
public static int sommeTab(int[] tableau) { int sum = 0;
....
return sum;
}
public static void main(String[] args) { int[] tab = {3,1,4,1,5,9,2,6,5};
int m = sommeTab(tab);
System.out.println(m);
} }
Exercice 26.
Qu’affiche le code de la classeFactorielleci-dessous ? Pouvez-vous expliquer pourquoi ? public class Factorielle {
public static int fac1(int n) { int sum = 1;
for (int i = 1; i <= n; i++) { sum = sum * i;
}
return sum;
}
public static int fac2(int n) { if (n > 0) {
return n * fac2(n-1);
} else { return 1;
} }
public static void main(String[] args) { int n = 8;
int f1 = fac1(n);
int f2 = fac2(n);
System.out.println(f1);
System.out.println(f2);
} }
Exercice 27.
Reprendre le code de la classeSommeEntiers, vue `a l’exercice 23, et y modifier la fonctionsommepour la transformer en une fonction r´ecursive, de la forme suivante :
public static int somme(int n) { if (n > 0) {
....
} else { return 0;
} }
Compl´eter le code de la fonction inverseTabpour que, lorsqu’elle prend en argument un tableautab, le r´esultat qu’elle renvoie soit un autre tableau de la mˆeme longueur que tab, mais o`u l’ordre des ´el´ements a ´et´e invers´e. Par exemple, le programmeInverseTableauci-dessous doit afficher2 4 9 7 12 3.
public class InverseTableau {
public static int[] inverseTab(int[] tab) { int[] resultat = ...
...
return resultat;
}
public static void main(String[] args) { int[] tab1 = {3,12,7,9,4,2};
int[] tab2 = inverseTab(tab1);
System.out.println(tab2[0] + "," + tab2[1] + "," + tab2[2] + "," + tab2[3] + "," + tab2[4] + "," + tab2[5]);
} }
Exercice 29.
Compl´eter le code de la fonction afficheTabpour que, lorsqu’elle prend en argument un tableautab, le r´esultat qu’elle renvoie soit une chaˆıne de caract`eres qui renvoie les entr´ees du tableau, espac´ees par des virgules et des symboles d’espaces.
Par exemple, le programmeAfficheTableauci-dessous doit afficher : 2, 4, 9, 7, 12, 3
1, 2, 3 4
public class AfficheTableau {
public static String afficheTab(int[] tab) { String resultat = ...
...
return resultat;
}
public static void main(String[] args) { int[] tab1 = {2,4,9,7,12,3};
int[] tab2 = {};
int[] tab3 = {1,2,3};
int[] tab4 = {4};
System.out.println(afficheTab(tab1));
System.out.println(afficheTab(tab2));
System.out.println(afficheTab(tab3));
System.out.println(afficheTab(tab4));
} }
Attention : il ne doit pas y avoir d’espace apr`es le dernier ´el´ement du tableau et, si le tableautabest vide, la chaˆıne de caract`eres renvoy´ee doit elle aussi ˆetre ´egale `a la chaˆıne vide. D’autre part, la fonction afficheTab doit se contenter de renvoyerune chaˆıne de caract`eres, et certainement pas afficher elle-mˆeme cette chaˆıne de caract`eres !
Ex´ecuter le code de la classe EntreeSortie ci-dessous puis ´ecrire deux chaˆınes de caract`eres en ligne de commande, s´epar´ees par un espace, alors que le programme est en train de s’ex´ecuter. Qu’affiche alors le programme ?
import util.Scanner;
public class EntreeSortie {
public static void main(String[] args) {
System.out.println("´Ecrire, ci-dessous, deux cha^ınes de caract`eres s´epar´ees par un espace :");
Scanner scan = new Scanner(System.in);
String s = scan.next();
String t = scan.next();
scan.close();
System.out.println(t + " " + s);
} }
On avait l’habitude de manipuler les canaux desortievers la ligne de commande, o`u l’on peut afficher des informations, via les commandesSystem.out.printet System.out.println.
Pour r´ecup´erer des informations que l’utilisateur (ou un autre processus) ´ecrit sur la ligne de commande, il nous suf- fit d’´ecrire la ligne Scanner scan = new Scanner(System.in);. On peut alors r´ecup´erer une par une les chaˆınes de caract`eres ´ecrites par l’utilisateur, au moyen de la commande scan.next();. Si l’utilisateur a ´ecrit des informations sp´ecifiques, par exemple la chaˆıne de caract`eres “12”, on aurait aussi pu r´ecup´erer directement l’entier 12 au moyen de la commandescan.nextInt();et, si l’on avait voulu r´ecup´erer toute une ligne sous forme d’une unique chaˆıne de caract`eres (avec, potentiellement, des espaces dedans), on aurait pu utiliser la commandescan.nextLine();
Par ailleurs, la ligneimport util.Scanner;qui figure en pr´eambule de notre code est tr`es importante. En effet, les objets de typeScannerne sont pas automatiquement reconnus par Java (au contraire desString, les chaˆınes de caract`eres, ou bien desint, les entiers). En revanche, ce sont eux-mˆemes des objets dont le code est ´ecrit en Java. Il faut donc indiquer au programmeEntreeSortieo`u aller chercher le code des objets de typeScanner.
Ce code est disponible dans ce que l’on appelle la biblioth`eque standard de Java. La biblioth`eque standard n’est autre qu’un immense recueil o`u ont ´et´e cod´es en Java de multiples objets tels que lesScanner. Certains fragments de la biblioth`eque, comme ceux qui contiennent la classeStringsont d´ej`a charg´es par d´efaut dans tous les programmes Java.
D’autres, comme ceux qui contiennent la classe Scanner, ne le sont pas : en pratique, ils sont moins souvent utilis´es, et les concepteurs de Java ont pr´ef´er´e n’int´egrer par d´efaut qu’une toute petite partie de la biblioth`eque standard. En effet, devoir charger l’int´egralit´e de la biblioth`eque avant de pouvoir ex´ecuter le moindre programme causerait une baisse brutale de performances sur de nombreux appareils faisant tourner des programme Java.
Tous les d´etails sur le contenu de la biblioth`eque standard sont disponibles sur
https://docs.oracle.com/en/java/javase/11/docs/api/index.html.
Nous verrons plus en profondeur, notamment dans la deuxi`eme partie du cours, comment acc´eder aux informations sur la biblioth`eque standard : cela nous permettra, par exemple, de d´ecouvrir des constructions analogues `a celles des lignes Scanner scan = new Scanner(System.in);,scan.next();, scan.nextInt();et scan.nextLine();.
Exercice 31.
La classeMathfait partie de la biblioth`eque standard, mais elle est automatiquement charg´ee dans tout programme Java.
La documentation sur cette classe est disponible sur
https://docs.oracle.com/javase/11/docs/api/java/lang/Math.html.
Qu’affiche le code de la classeAffichePici-dessous ? public class AffichePi {
public static void main(String[] args) { double pi = Math.PI;
System.out.println(pi);
} }
A quelles lignes de la documentation sur la classe` Math peut-on trouver des informations sur la commandeMath.PIque l’on vient d’utiliser ? Quelle(s) ligne(s) de code faudrait-il rajouter pour afficher ensuite la valeur approch´ee de √
2 ?
Compl´eter le code des fonctionsafficheHeureetHMSToSecondsci-dessous, pour que :
— si elle prend en param`etre un nombre entier qui repr´esente une dur´ee en secondes, la fonction formatHeurerenvoie (sans afficher) une chaˆıne de caract`eres indiquant l’heure correspondante au formatheures:minutes:secondes;
— si ses param`etres respectifs sont un nombre d’heures, de minutes et de secondes, la fonctionHMSToSeconds renvoie (sans afficher) la dur´ee correspondante en secondes.
Qu’affiche alors le code de la classeJeuxSurLHeureci-dessous ? public class JeuxSurLHeure {
public static String formatHeure(int temps) { ...
}
public static int HMSToSeconds(int h, int m, int s) { ...
}
public static void main(String[] args) { int h = 2;
int m = 20;
int s = 30;
int total = HMSToSeconds(h,m,s);
System.out.println(total);
String hms = formatHeure(h,m,s);
System.out.println(hms);
} }
Proposer ensuite une fonction qui, si son argument tempscontient une dur´ee en secondes, affiche (sans renvoyer quelque r´esultat que ce soit) une chaˆıne de caract`eres indiquant l’heure correspondante au format heures:minutes:secondes.
Pouvez-vous tester cette fonction ?
Exercice 33.
Une ann´ee est ditebissextile si elle comporte un 29 f´evrier. C’est le cas de toutes les ann´ees divisibles par 4, `a l’exception de celles divisibles par 100, qui ne sont bissextiles que si elles sont ´egalement divisibles par 400.
Compl´eter le code de la fonction estBissextilepour que celle-ci, quand elle prend en param`etre un nombre entier qui est l’ann´ee `a tester, renvoie true si cette ann´ee est bissextile et false sinon. Compl´eter ensuite le code de la fonction affichageBissextilepour que celle-ci, quand elle prend en param`etre l’ann´ee `a tester, affiche un message indiquant en clair si l’ann´ee est bissextile ou non.
Qu’affiche alors le code de la classeBissextile ci-dessous ? public class Bissextile {
public static boolean estBissextile(int annee) { ...
}
public static void affichageBissextile(int annee) { ...
}
public static void main(String[] args) { affichageBissextile(1900);
affichageBissextile(1901);
affichageBissextile(1904);
affichageBissextile(2000);
affichageBissextile(2018);
} }
Compl´eter le code de la fonction maxTableau pour que celle-ci, quand elle prend en param`etre un tableau d’entiers sup´erieurs ou ´egaux `a 0, renvoie le plus grand entier contenu dans le tableau, et renvoie 0 si le tableau est vide.
Compl´eter ´egalement le code de la fonction sommeTableau pour que celle-ci, quand elle prend en param`etre un tableau d’entiers (pas forc´ement positifs), renvoie la somme de ces entiers, et renvoie 0 si le tableau est vide.
Enfin, compl´eter le code de la fonction main`a votre guise pour tester vos fonctionsmaxTableauetsommeTableau.
public class MaxSommeTableau {
public static int maxTableau(int[] tableau) { ...
}
public static int sommeTableau(int[] tableau) { ...
}
public static void main(String[] args) { ...
} }
Exercice 35.
Lire la documentation de la classeArrays, pr´esente dans la biblioth`eque Java, et en particulier des deux fonctionspublic static void sort(int[] a) et public static String toString(int[] a) de cette classe. Cette documentation se trouve ici :
https ://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Arrays.html#sort(int[])Sting https ://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Arrays.html#toString(int[])s
Pouvez-vous en d´eduire, a priori, ce qu’affichera le code de la fonctionSortAndShowArraysci-dessous ? L’ex´ecution de ce code confirme-t-il votre d´eduction ?
public class SortAndShowArrays {
public static void main(String[] args) { int[] tab = {1,3,4,5,9,7,2,1,0,-5,1,12,2};
System.out.println(Arrays.toString(tab));
Arrays.sort(tab);
System.out.println(Arrays.toString(tab));
} }
Si l’on remplace chacune des lignes System.out.println(Arrays.toString(tab)); par System.out.println(tab);, que se passe-t-il ? En confrontant cet exercice `a l’exercice 29, quels enseignements pouvez-vous tirer ?