Résumé
Cette leçon clôt la deuxième unité du cours, consacrée aux données et à leurs types. Elle reconstruit la chaîne des concepts qui va de la variable à la constante que le compilateur surveille, en passant par la représentation binaire des entiers et leurs deux dépassements, les réels approchés et la tolérance, les caractères comme codes et les conversions qui perdent de l’information ; elle sépare ce qui, dans tout cela, vaut dans tout langage de ce qui est propre à C++ ; elle rassemble le comportement indéfini de l’unité, avec ce que détecte le compilateur, ce que détecte le détecteur et ce que personne ne détecte ; elle reprend dans son évaluation de sortie les savoir-faire de l’évaluation d’entrée ; et elle se termine par six défis qui combinent l’unité entière.
Objectifs d’apprentissage
- Choisir et justifier le type de chaque donnée d’un problème selon les valeurs qu’elle peut prendre, l’exactitude qu’elle exige et les opérations qu’on effectuera sur elle.
- Prévoir les effets des limites de représentation dans un programme donné : le dépassement des entiers, l’arrondi de la virgule flottante et la perte d’information d’une conversion.
- Utiliser des constantes nommées et des conversions explicites, et expliquer ce que vérifie le compilateur dans chaque cas.
- Reconnaître le comportement indéfini de l’unité et dire, pour chaque cas, ce qui le détecte et comment on le prévient.
- Séparer, dans ce qui a été appris dans l’unité, ce qui vaut dans tout langage de ce qui est propre à C++.
L’acquis de l’unité
L’unité s’est proposé d’enseigner que toute donnée vit en mémoire avec un type qui fixe quelles valeurs elle peut prendre, combien de place elle occupe et quelles opérations elle admet, et que ces limites ont des conséquences observables. Le but a été atteint en s’appuyant seulement sur ce que l’introduction a déclaré acquis : le cycle compiler et exécuter avec les options du cours, la sortie formatée, la lecture avec std::cin et la lecture des messages du compilateur. Le programme des quatre calculs par lequel l’introduction a posé le problème peut maintenant être expliqué ligne par ligne, et corrigé.
Variables et mémoire
La leçon Variables et mémoire a établi qu’une variable est une case mémoire dotée d’un nom, d’un type fixe et d’une valeur qui change, et que le type fixe sa taille, que sizeof mesure. Elle a distingué l’initialisation de l’affectation, montré que les accolades refusent une conversion avec perte, et enseigné que l’affectation copie et ne lie pas, et que la valeur remplacée est perdue, d’où découle la variable auxiliaire de l’échange. Elle a défini l’état d’un programme comme l’ensemble des valeurs de ses variables et appris à le suivre avec un tableau de suivi. Elle a fixé les conventions de nommage et s’est terminée sur le premier comportement indéfini de l’unité : la lecture d’une variable qui n’a jamais reçu de valeur.
Les entiers et leur représentation
La leçon Les entiers et leur représentation a enseigné la notation positionnelle en bases 10, 2 et 16. Du fait qu’un type a bits, elle a déduit sa plage : motifs, qui représentent, sans signe, de à et, avec signe, en complément à deux, de à , avec un nombre strictement négatif de plus que de strictement positifs. Elle a distingué les deux dépassements : celui des entiers non signés, qui est une arithmétique modulo et est défini (0u - 1 vaut ), et celui des entiers signés, qui est un comportement indéfini et que le détecteur arrête. Elle a montré que comparer un entier signé avec un entier non signé convertit le premier, de sorte que est faux, et s’est terminée par un critère pour choisir le type entier selon la plage prévisible de la donnée.
Les nombres à virgule flottante
La leçon Les nombres à virgule flottante a montré qu’un réel est stocké comme un signe, un exposant et une mantisse binaire, de sorte que les valeurs représentables forment un ensemble fini de rationnels dont le dénominateur est une puissance de 2. Il en a découlé que n’existe pas dans la machine : à sa place on stocke le double le plus proche, et 0.1 + 0.2 s’écrit 0.30000000000000004. La leçon a borné l’erreur de chaque arrondi, montré que les erreurs s’accumulent et que l’addition cesse d’être associative ; d’où elle a déduit que deux réels calculés ne se comparent pas avec ==, mais par leur distance, avec une tolérance justifiée. Elle a fixé double comme type réel par défaut, et présenté l’infini et la valeur non numérique, NaN.
Caractères, booléens, conversions et constantes
La leçon Caractères, booléens, conversions et constantes a montré qu’un type est une règle pour lire les bits : un char stocke un octet dont la valeur est le code ASCII du caractère, et comme les chiffres et les lettres ont des codes consécutifs, '7' - '0' vaut 7 ; un bool est vrai ou faux, et tout nombre non nul se convertit en vrai. Elle a étudié les conversions implicites et établi que la conversion a lieu dans l’opération, selon le type des opérandes, et non au moment de stocker le résultat : double r{7 / 2} vaut 3. Elle a appris à écrire la conversion voulue avec static_cast, qui n’évite pas la perte, mais la déclare ; elle a précisé que les accolades refusent le rétrécissement, et montré le troisième comportement indéfini de l’unité, la conversion en entier d’un réel qui ne tient pas. Elle s’est terminée par les constantes (const, constexpr et static_assert), le type des littéraux et auto.
Chargement du contenu…