Zum Inhalt springen
Topos Uranos

Zusammenfassung

Diese Lektion schließt die zweite Einheit des Kurses ab, die den Daten und ihren Typen gewidmet ist. Sie rekonstruiert die Kette der Begriffe, die von der Variablen bis zu der Konstanten reicht, über die der Compiler wacht, und dabei über die binäre Darstellung der ganzen Zahlen und ihre zwei Überläufe, die angenäherten reellen Zahlen und die Toleranz, die Zeichen als Codes und die Konvertierungen führt, die Information verlieren; sie trennt, was davon in jeder Sprache gilt, von dem, was C++ eigen ist; sie fasst das undefinierte Verhalten der Einheit zusammen, mit dem, was der Compiler erkennt, was der Sanitizer erkennt und was niemand erkennt; sie wiederholt in ihrem Abschlusstest die Fertigkeiten des Eingangstests; und sie endet mit sechs Herausforderungen, die die ganze Einheit verbinden.

Lernziele

  1. Den Typ jedes Datums eines Problems nach den Werten, die es annehmen kann, der Genauigkeit, die es verlangt, und den Operationen, die damit ausgeführt werden, wählen und begründen.
  2. Die Folgen der Darstellungsgrenzen in einem gegebenen Programm vorhersagen: den Überlauf der ganzen Zahlen, die Rundung der Gleitkommazahlen und den Informationsverlust einer Konvertierung.
  3. Benannte Konstanten und explizite Konvertierungen verwenden und erklären, was der Compiler in jedem Fall prüft.
  4. Das undefinierte Verhalten der Einheit erkennen und für jeden Fall sagen, was es erkennt und wie man ihm vorbeugt.
  5. Im Gelernten der Einheit trennen, was in jeder Sprache gilt, von dem, was C++ eigen ist.

Was die Einheit erreicht hat

Die Einheit hatte sich vorgenommen zu lehren, dass jedes Datum im Speicher mit einem Typ lebt, der festlegt, welche Werte es annehmen kann, wie viel Platz es belegt und welche Operationen es zulässt, und dass diese Grenzen beobachtbare Folgen haben. Dieses Ziel wurde erreicht, gestützt nur auf das, was die Einführung als bekannt vorausgesetzt hat: den Zyklus aus Kompilieren und Ausführen mit den Optionen des Kurses, die formatierte Ausgabe, das Einlesen mit std::cin und das Lesen der Meldungen des Compilers. Das Programm der vier Rechnungen, mit dem die Einführung das Problem gestellt hat, lässt sich jetzt Zeile für Zeile erklären und korrigieren.

Variablen und Speicher

Die Lektion Variablen und Speicher hat festgestellt, dass eine Variable eine Speicherzelle mit einem Namen, einem festen Typ und einem sich ändernden Wert ist und dass der Typ ihre Größe festlegt, die sizeof misst. Sie hat die Initialisierung von der Zuweisung unterschieden, gezeigt, dass geschweifte Klammern eine Konvertierung mit Verlust zurückweisen, und gelehrt, dass die Zuweisung kopiert und nicht bindet und dass der ersetzte Wert verloren geht, woraus die Hilfsvariable des Tauschs folgt. Sie hat den Zustand eines Programms als die Menge der Werte seiner Variablen definiert und gelehrt, ihn mit einer Ablauftabelle zu verfolgen. Sie hat die Namenskonventionen festgelegt und mit dem ersten undefinierten Verhalten der Einheit geschlossen: dem Lesen einer Variablen, die nie einen Wert erhalten hat.

Ganze Zahlen und ihre Darstellung

Die Lektion Ganze Zahlen und ihre Darstellung hat die Stellenwertschreibweise in den Basen 10, 2 und 16 gelehrt. Daraus, dass ein Typ nn Bits hat, hat sie seinen Wertebereich abgeleitet: 2n2^n Muster, die ohne Vorzeichen die Zahlen von 00 bis 2n−12^n - 1 darstellen und mit Vorzeichen, im Zweierkomplement, die von −2n−1-2^{n-1} bis 2n−1−12^{n-1} - 1, mit einer negativen Zahl mehr als positiven. Sie hat die beiden Überläufe unterschieden: den der vorzeichenlosen ganzen Zahlen, der Arithmetik modulo 2n2^n und definiert ist (0u - 1 ergibt 4 294 967 2954\,294\,967\,295), und den der vorzeichenbehafteten, der undefiniertes Verhalten ist und den der Sanitizer stoppt. Sie hat gezeigt, dass der Vergleich einer vorzeichenbehafteten mit einer vorzeichenlosen ganzen Zahl die erste konvertiert, sodass −1<0u-1 < 0u falsch ist, und mit einem Kriterium geendet, nach dem man den ganzzahligen Typ gemäß dem absehbaren Wertebereich des Datums wählt.

Gleitkommazahlen

Die Lektion Gleitkommazahlen hat gezeigt, dass eine reelle Zahl als Vorzeichen, Exponent und binäre Mantisse gespeichert wird, sodass die darstellbaren Werte eine endliche Menge rationaler Zahlen sind, deren Nenner eine Zweierpotenz ist. Daraus folgte, dass es 0.10.1 in der Maschine nicht gibt: An seiner Stelle wird der nächstgelegene double-Wert gespeichert, und 0.1 + 0.2 wird als 0.30000000000000004 ausgegeben. Die Lektion hat den Fehler jeder Rundung abgeschätzt und gezeigt, dass sich die Fehler anhäufen und dass die Addition nicht mehr assoziativ ist; daraus hat sie abgeleitet, dass zwei berechnete reelle Zahlen nicht mit == verglichen werden, sondern über ihren Abstand, mit einer begründeten Toleranz. Sie hat double als reellen Standardtyp festgelegt und das Unendliche und den Nicht-Zahl-Wert, NaN, vorgestellt.

Zeichen, boolesche Werte, Umwandlungen und Konstanten

Die Lektion Zeichen, boolesche Werte, Umwandlungen und Konstanten hat gezeigt, dass ein Typ eine Regel zum Lesen der Bits ist: Ein char speichert ein Byte, dessen Wert der ASCII-Code des Zeichens ist, und da Ziffern und Buchstaben aufeinanderfolgende Codes haben, ergibt '7' - '0' den Wert 7; ein bool ist wahr oder falsch, und jede von null verschiedene Zahl wird zu wahr konvertiert. Sie hat die impliziten Konvertierungen untersucht und festgestellt, dass die Konvertierung innerhalb der Operation geschieht, nach dem Typ der Operanden, und nicht beim Speichern des Ergebnisses: double r{7 / 2} hat den Wert 3. Sie hat gelehrt, die gewollte Konvertierung mit static_cast zu schreiben, das den Verlust nicht verhindert, sondern erklärt; sie hat präzisiert, dass geschweifte Klammern die Einschränkung zurückweisen, und das dritte undefinierte Verhalten der Einheit gezeigt, die Konvertierung einer reellen Zahl, die nicht hineinpasst, in eine ganze Zahl. Sie hat mit den Konstanten (const, constexpr und static_assert), dem Typ der Literale und auto geschlossen.