Exercices sur les classes, les variables, les types et les opérateurs
Exercices sur les classes, les variables, les types et les opérateurs
#
Prenez en note chaque question. Tentez par vos propres moyens, mais avec l’aide de tout le matériel et de l’Internet, de résoudre le problème. Prévoyez jusqu’à 15 minutes de travail par question. Après avoir bien travaillé la question, consultez la réponse.
N’allez pas trop vite. Il ne sert à rien de lire la question et d’immédiatement lire la réponse. Le but des exercices est de vous amener à travailler la matière. Si vous ne faites que regarder les solutions, vous n’apprenez pas grand chose. Oui, ça va plus vite, mais votre but ici n’est pas la rapidité.
Prenez note qu'il est permis d'utiliser une intelligence artificielle lors des exercices (Grok, ChatGPT, Gemini, etc.)
Cependant vous devriez vous entraîner à produire vos propres réponses. Vous devez être capable de produire vos propres réponses et vous devez toujours pouvoir expliquer vos solutions.
Les exercices comportent une solution vous permettant de comparer votre approche avec la nôtre. Il n'y a pas de solution unique aux problèmes en général. Vous pouvez arriver avec une solution qui est préférable ou moins bonne que celle que nous offrons. Pour faire ces questions, vous devez avoir fait toutes les lectures préalables. Vous disposez alors toujours des fondements nécessaires pour faire les exercices. Nous vous encourageons tout de même à faire vos propres recherches en complément de vos lectures. Dans certains cas, au sein de la solution que nous offrons, nous pouvons utiliser des notions techniques qui n'ont pas été vues directement dans le cours, mais qui devraient vous être facilement accessibles.
En programmation orientée objet (comme le langage Java), quelle est la différence entre une classe et une instance?
RéponseUne classe est la description abstraite d'un concept. Une instance est la matérialisation en mémoire d'un concept. Par exemple, la classe Client et l'instance Client 11 Alice Bob.
Vrai ou Faux : Le langage Java est un langage compilé en langage machine?
RéponseVrai et Faux: c'est un langage interprété par une machine virtuelle, la JVM. La code est pré-compilé dans un langage intermédiaire, le bytecode. Par la suite, lors de l'exécution, le bytecode peut être compilé en langage machine.
En Java, les entiers sont représentés en binaire selon le format « complément à deux ». Ainsi, -1 est représenté par une suite de bits où tous les bits sont à 1. Par exemple, pour un int (32 bits), -1 correspond à 0xFFFFFFFF en hexadécimal, soit 32 bits à 1.
En Java, -0.0 == 0.0 retourne true car la comparaison d’égalité (==) considère ces deux valeurs comme égales selon la norme IEEE 754. Cependant, il existe une différence binaire entre -0.0 et 0.0 (le signe du zéro), ce qui peut être détecté avec certaines méthodes comme Double.doubleToRawLongBits() ou en utilisant 1.0 / -0.0 (qui donne -Infinity), alors que 1.0 / 0.0 donne Infinity.
À l'aide d'une classe Java et en utilisant l'arithmétique entière, vous devez calculer la moyenne des tailles de 5 enfants, puis imprimer la moyenne à la console et l'écart à la moyenne pour chaque enfant:
Quelle est la différence entre un int et un long ?
RéponseUn entier de type int sera alloué en mémoire à une taille de 32 bits. Sa valeur maximale absolue est donc de 2 147 483 647. L'entier de type long permet des valeurs plus grandes car il est alloué sur un espace de 64 bits (9 223 372 036 854 775 807).
RéponseLe résultat est 0. 1: i++ => i = 34; 2: j-- => j = 43; 3 : k + i - j = 46; 4: -46; 5: -46 % 2 = 0 (le reste de la division par 2. Comme 46 / 2 = 23. Il n'y a pas de reste);
RéponseLa réponse est 12 car l'opérateur à 3 opérandes "?:" vérifie si i est plus grand ou égal à 1 (c'est le cas), alors la valeur retournée est i pré-incrémenté de 1 : 12.
Expliquez ce qu’est un débordement (overflow) lors d’un calcul avec des entiers en Java. Donnez un exemple de code qui provoque un débordement.
Réponse
Un débordement se produit lorsqu’une opération arithmétique dépasse la valeur maximale ou minimale qu’un type peut représenter. Par exemple, un int en Java varie de -2 147 483 648 à 2 147 483 647. Si on additionne 1 à la valeur maximale, on « retourne » à la valeur minimale.
Parmi les noms suivants, quels sont les noms de variable corrects en java
(qui ne seront pas rejetés à la compilation)?
Lesquels sont conseillés ?
1) _176
2) $za21
3) 5var
4) A1234_
5) var
6) monEntier
7) &var
Réponse
Nom corrects : 1, 2, 4, 5, 6. En effet, vous pouvez utiliser var comme nom de variable.
Nom conseillé : 6. En effet à moins d’avoir de sérieuses raisons
de faire autrement, il faut utiliser les minuscules pour les noms de variables
simples en java, et les majuscules pour articuler les noms de variables
composés comme monEntier. Le mot var est déconseillé puisque c'est un mot-clé contextuel.
Quel résultat est affiché à la console lors de l’exécution ? Pourquoi
?
Une erreur
10
5
Réponse
Bonne réponse : 2.
Explication : (i=5) est une expression dont la résultat est la valeur
affectée à i, c’est-à-dire 5. Ce résultat est multiplié par deux et
affecté à k, puis affecté à myInt.
La fonction retourne la valeur vraie si et seulement si un seul des deux paramètres est négatif. Par exemple, f(-1,1) est vrai, f(2,2) et f(-1,-3) sont faux.
Quelle est la valeur de l'expression 2083697005*101 en Java?
Réponse
L'expression 2083697005*101 est égale à 1. Cela s'explique par le fait que les entiers sont stockés avec 32 bits seulement et que la véritable valeur (210453397505) ne peut pas être représentée. Java tronque le résultat.
Soit deux entiers positifs (int) x et y. Sachant que la moyenne des deux valeurs est aussi un entier, donnez une expression qui calcule cette moyenne.
Réponse
On peut la calculer avec l'expression y+(x - y)/2. Il pourrait être tentant d'utiliser l'expression (x + y)/2, mais cette dernière est incorrecte comme vous pouvez le vérifier avec ce programme:
Soit une chaîne de caractère en Java: String s = "123";. Comment puis-je modifier la valeur de cette chaîne de caractères?
Réponse
En Java, les chaînes de caractères sont immutables, elles ne peuvent être modifiées. On ne peut donc pas modifier la valeur assigné à s. Par contre, on peut créer une nouvelle chaîne de caractères et réassigner la variable à cette nouvelle valeur (s = "1234";).
Expliquez la différence entre l'ensemble des nombres non négatifs, et l'ensemble des nombres positifs.
Réponse
En informatique, on définit l’ensemble des nombres positifs comme étant les nombres plus grands que zéro. Les nombres négatifs sont les nombres plus petits que zéro. Les nombres non négatifs sont donc les nombres positifs ou nuls.
Expliquez pourquoi 0.8825149536132812 est égal à 0.8825149536132813 en Java.
Réponse
Dans le cas qui nous concerne, il n'est pas possible de distinguer 0.8825149536132812 et 0.8825149536132813, des nombres à 16 chiffres significatifs. En général, il est possible de représenter l'ensemble des nombres entre -10 à la puissance 308 et 10 à la puissance 308 avec 15 chiffres de précision, mais pas 16 chiffres de précision. Les nombres 0.8825149536132812 et 0.8825149536132813 sont représentés en nombre à virgule flottante comme étant 115673 fois 2 à la puissance -17 ce qui est le nombre 0.88251495361328125.
En Java, l'expression 1.0 / 0.0 retourne Infinity (l'infini positif), car la division par zéro avec des nombres à virgule flottante (double) ne provoque pas d'exception, mais retourne une valeur spéciale représentant l'infini.
Quelle est la différence entre == et equals() pour comparer deux chaînes de caractères en Java ?
Réponse
== compare les références (adresses en mémoire), alors que equals() compare le contenu des chaînes. Il faut utiliser equals() pour vérifier si deux chaînes ont le même texte.
Quelle est la valeur de l’expression 1 + 2 + “3” + 4 + 5 en Java ?
Réponse
L’expression s’évalue de gauche à droite : 1 + 2 donne 3, puis 3 + "3" donne "33" (concaténation), puis "33" + 4 donne "334", puis "334" + 5 donne "3345". La valeur finale est "3345".
Que vaut l’expression new Integer(3) == new Integer(3) en Java ? Expliquez pourquoi.
Réponse
L’expression retourne false. Chaque appel à new Integer(3) crée un nouvel objet distinct en mémoire : les deux objets ont la même valeur mais ne sont pas le même objet. L’opérateur == compare les références (adresses) des objets, pas leur contenu. Pour comparer la valeur, il faut utiliser equals() :
Quels sont, selon vous, les principaux avantages et inconvénients de Java par rapport à d’autres langages de programmation modernes ?
Réponse
Avantages : portabilité, gestion automatique de la mémoire (garbage collector), vaste écosystème de bibliothèques et frameworks, documentation abondante.
Inconvénients : performances parfois inférieures au code natif (C/C++), syntaxe parfois verbeuse, nécessité d’installer la JVM.
Expliquez la différence entre les expressions A & B et A && B.
Réponse
Dans le contexte de Java, les expressions A & B et A && B sont toutes deux des opérateurs de type “et logique” (AND) appliqués à des opérandes booléens A et B, mais elles diffèrent fondamentalement par leur comportement d’évaluation.
L’opérateur && est l’opérateur AND logique à court-circuit. Il évalue d’abord A : si A est faux, l’expression entière retourne immédiatement faux sans évaluer B, ce qui optimise les performances et évite des calculs inutiles (ou potentiellement dangereux, comme une division par zéro dans B). Par exemple, dans if (x > 0 && 10 / x > 1), si x vaut zéro, B ne sera pas évalué, évitant une exception.
En revanche, l’opérateur & est un AND logique non court-circuit : il évalue toujours A et B, quel que soit le résultat de A, avant de retourner le résultat logique (vrai si les deux sont vrais, faux sinon). Cela peut être utile dans des contextes où les effets secondaires de B doivent toujours se produire, mais cela rend le code moins efficace et plus risqué si B dépend de A.
Notez que & peut aussi servir d’opérateur bit à bit pour des entiers, alors que && est exclusivement logique pour les booléens. En pratique, pour les conditions booléennes, && est préféré pour sa sémantique plus sûre.
La moyenne entière de deux entiers a et b est le résultat de (a + b) / 2 avec une division entière (tronquée vers
le bas). Écrivez une fonction en Java qui calcule la moyenne entière de deux int, sans causer de débordement
et sans utiliser un type autre que int.
Réponse
Voici une solution possible.
publicstaticintsafeAverageWithBranch(inta,intb){// Cas 1 : signes différents (un positif, un négatif ou l’un des deux est zéro)// → a + b ne peut pas déborder car la somme reste dans les limites d’un intif((a<0)!=(b<0)){return(a+b)/2;}// Cas 2 : même signe (les deux positifs ou les deux négatifs)// → on utilise la formule sans risque de débordement : a + (b - a)/2// La soustraction b - a ne déborde jamais quand a et b ont le même signereturna+(b-a)/2;}
Voici pourquoi cette fonction est correcte.
Quand les signes sont différents → la somme a + b est mathématiquement comprise entre Integer.MIN_VALUE et Integer.MAX_VALUE, donc aucun overflow possible en Java (même avec MIN_VALUE et MAX_VALUE).
Quand les signes sont identiques → b - a a une valeur absolue plus petite que chacun des deux nombres, donc la soustraction reste dans les limites d’un int, puis on divise par 2 et on ajoute à a : aucun débordement.