Résumé
Cette leçon ouvre la deuxième unité du cours, consacrée aux données et à leurs types. Elle explique à quoi sert l’unité : enseigner que toute donnée d’un programme vit en mémoire avec un type qui fixe les valeurs qu’elle peut prendre, la place qu’elle occupe et les opérations qu’elle admet, et que ces limites ont des conséquences observables ; elle présente ses quatre leçons et le fil qui les relie, de la variable comme case dotée d’un nom et d’une valeur jusqu’aux conversions entre types et aux constantes ; elle rappelle ce que l’unité tient pour acquis de la première, à savoir écrire, compiler et exécuter un programme qui lit et écrit ; elle formule le problème que l’unité résout, celui d’un programme correct en apparence dont les calculs ne coïncident pas avec ceux des mathématiques, à commencer par la somme , qui sur un ordinateur ne donne pas exactement ; et elle montre où elle mène, dans les unités suivantes et dans le cours Programmation en C++ II.
Objectifs d’apprentissage
- Décrire la séquence des contenus de l’unité et expliquer ce que chaque leçon apporte à la suivante.
- Se rappeler le nécessaire de l’unité 1 (le cycle compiler et exécuter, la sortie formatée, la lecture avec
std::cinet la lecture des messages du compilateur) et le réviser si besoin. - Expliquer, sur un exemple, pourquoi un nombre d’un programme n’est pas un nombre des mathématiques, et anticiper pourquoi ne vaut pas exactement sur un ordinateur.
- Reconnaître ce que l’on attend de savoir faire à la fin de l’unité, et le distinguer de ce que l’on apprendra dans les unités suivantes.
Évaluation d’entrée
Avant de parcourir l’unité, il convient de mesurer le point de départ. Cette évaluation est une autoévaluation : elle n’est pas notée, et son seul but est d’orienter l’étude. Les quatre premières questions vérifient ce que l’unité tient pour acquis de la première : le suivi d’une procédure étape par étape, l’écriture d’un nombre avec deux décimales, l’arrondi et la lecture d’un message d’erreur. Les six suivantes touchent, dans l’ordre des leçons, aux idées centrales de l’unité. Personne n’est tenu de les réussir déjà, et pour l’une d’elles « je ne le sais pas encore » est une réponse honnête : chaque réponse, juste ou non, explique le point et nomme la leçon qui le traite. Les mêmes compétences sont mesurées de nouveau à la fin, dans la leçon de synthèse.
Avant de commencer l’unité, mesurez votre point de départ. C’est une autoévaluation brève : elle n’est pas notée et son résultat n’est conservé que dans votre navigateur.
Question 1Des unités précédentesUne procédure dit : « 1. prend la valeur 17. 2. prend la valeur . 3. prend la valeur ». Que vaut à la fin ?
Suppose que chaque étape part de la valeur initiale ; la deuxième part de la valeur laissée par la première.Lit « prend la valeur » comme une égalité mathématique ; c’est un ordre qui remplace la valeur de .Confond une variable avec une constante : la valeur d’une variable change chaque fois qu’on lui en affecte une autre.Chaque étape part de la valeur que a à ce moment-là, non de la valeur initiale. Suivre la procédure à la main, avec la valeur de chaque variable après chaque étape, c’est le tableau de suivi de l’unité 1, et la leçon 2.1 en fait l’instrument pour raisonner sur l’état d’un programme.À revoir : Du problème à l’algorithme
Question 2Des unités précédentesQu’écrit l’instruction
std::println("{:.2f}", 2.0 / 3);?Croit que la spécification de format tronque ; elle arrondit à la décimale la plus proche.Ignore la spécification de format : c’est l’écriture sans.2f.Croit que la division est entière ; avec2.0, qui a des décimales, la division est réelle.La spécification.2fécrit le nombre avec deux décimales, en arrondissant : s’écrit0.67. La valeur conservée ne change pas ; seule son écriture change.À revoir : Entrée, sortie et erreurs
Question 3Des unités précédentesOn veut écrire avec deux décimales, en arrondissant. Qu’obtient-on ?
Tronque au lieu d’arrondir : écarte la troisième décimale sans la regarder.Arrondit à une décimale, non à deux.Augmente la deuxième décimale plus qu’il ne faut : est compris entre et , et l’arrondi choisit l’un de ces deux nombres.Arrondir à deux décimales, c’est choisir le nombre à deux décimales le plus proche : est plus près de que de . La leçon 2.3 montrera que l’ordinateur arrondit de la même manière, mais en base 2, et que c’est pourquoi presque aucun nombre à décimales n’est conservé exactement.À revoir : Entrée, sortie et erreurs
Question 4Des unités précédentesUn programme contient à la ligne 5
const int pages{12}et à la ligne 6std::println("{}", pages);. Le compilateur écrit6:5: error: expected ',' or ';' before 'std'. Où est le défaut ?La ligne 6 est correcte ; le compilateur la signale parce que c’est là qu’il a remarqué le manque.stdest reconnu ; le message dit qu’il attendait un point-virgule avant lui.Le message diterror, nonwarning: il n’y a pas d’exécutable.Le compilateur découvre le manque quand il rencontre quelque chose qui ne peut pas suivre la déclaration, au début de la ligne 6, et il signale cet endroit. Si la ligne signalée est correcte, le défaut se trouve d’ordinaire à la fin de la précédente.À revoir : Anatomie d’un programme
Question 5Un programme déclare
int a{2};etint b{7};, puis exécutea = b;etb = 10;. Que vautaà la fin ?Croit que l’affectation lie les deux variables, comme siaétait un autre nom deb; elle ne fait que copier la valeur.Lita = bà l’envers, comme si elle copiaitadansb; la valeur va de droite à gauche.Additionne les deux valeurs ; l’affectation remplace, elle n’accumule pas.L’affectationa = bcopie dansala valeur queba à ce moment-là ; ensuite,aetbsont des cases indépendantes, et changerbne change pasa.À revoir : Variables et mémoire
Question 6Comment s’écrit le nombre 13 en base 2 ?
C’est une réponse honnête : la leçon 2.2 enseigne à écrire un nombre en base 2 et à le lire, et l’évaluation de sortie reposera la question.Lit les restes des divisions successives dans l’ordre où ils apparaissent ; on les lit du dernier au premier.Additionne mal les poids : .En base 2 chaque position pèse le double de celle qui est à sa droite, et les seuls chiffres sont 0 et 1. La leçon 2.2 l’enseigne, parce que tout entier d’un programme est conservé ainsi.À revoir : Les entiers et leur représentation
Question 7Un
intde 4 octets contient , sa valeur maximale, et le programme lui ajoute 1. Que peut-on affirmer ?Ignore la limite de la représentation : ce nombre ne tient pas dans unintde 4 octets.C’est ainsi que se comportent les entiers non signés, dont l’arithmétique est modulaire ; pour les entiers signés, la norme ne le garantit pas.Le compilateur ne connaît pas les valeurs que le programme aura à l’exécution, sauf si ce sont des constantes ; presque toujours, il compile sans rien dire.Un entier d’un programme a un nombre fixe de bits et, avec eux, une plage finie. Sortir de la plage d’un entier signé viole la précondition de l’addition ; le détecteur du cours arrête le programme, et sans lui le programme peut écrire n’importe quoi. La leçon 2.2 l’étudie.À revoir : Les entiers et leur représentation
Question 8Le nombre a-t-il un développement décimal fini ?
est une approximation : , et non 1.Quel que soit le nombre de décimales écrites, il reste toujours un reste ; le développement est périodique, non fini.C’est une propriété du nombre et de la base, non de l’instrument ; la calculatrice ne montre qu’une approximation.Une fraction irréductible a un développement décimal fini si et seulement si son dénominateur n’a pas d’autres facteurs premiers que 2 et 5, ceux de la base 10. En base 2 la condition est plus exigeante : le dénominateur doit être une puissance de 2, et c’est pourquoi n’a pas de développement binaire fini. La leçon 2.3 en tire les conséquences.À revoir : Les nombres à virgule flottante
Question 9Qu’écrit
std::println("{}", 0.1 + 0.2);?Suppose que l’ordinateur additionne des décimaux exacts ; il additionne des approximations binaires.Confond l’écriture par défaut avec la spécification{:.2f}, qui arrondit à deux décimales.La somme de deuxdoubleest légitime ; ce qui surprend, c’est son résultat, non son écriture.Ni ni ne sont conservés exactement en binaire, et la somme de leurs approximations n’est pas l’approximation de .std::printlnécrit la représentation décimale la plus courte qui identifie la valeur conservée, et cette représentation révèle la différence. La leçon 2.3 explique chiffre par chiffre d’où elle vient.À revoir : Les nombres à virgule flottante
Question 10Un programme déclare
const double ratio{7 / 2};et écritratio. Qu’est-ce qui s’affiche ?Croit que le type de la variable décide comment on divise ; c’est le type des opérandes qui le décide.Croit que la division entière arrondit ; elle écarte la partie décimale.La valeur 3 est constante et se représente exactement dans undouble: il n’y a pas de perte, et les accolades l’admettent.La division7 / 2a lieu entre entiers, et donne le quotient entier, 3 ; c’est seulement ensuite que ce 3 est converti endouble. La division effectuée se décide dans l’opération même, selon le type des opérandes, et non au moment de conserver le résultat. La leçon 2.4 enseigne où placer la conversion pour obtenir 3.5.
Chargement du contenu…