Riepilogo
Questa lezione chiude la seconda unità del corso, dedicata ai dati e ai loro tipi. Ricostruisce la catena dei concetti che va dalla variabile alla costante che il compilatore sorveglia, passando per la rappresentazione binaria degli interi e i loro due overflow, i reali approssimati e la tolleranza, i caratteri come codici e le conversioni che perdono informazione; separa ciò che di tutto questo vale in qualsiasi linguaggio da ciò che è proprio di C++; raccoglie il comportamento indefinito dell’unità, con ciò che rileva il compilatore, ciò che rileva il sanitizer e ciò che non rileva nessuno; ripete nella sua valutazione d’uscita le abilità della valutazione d’ingresso; e termina con sei sfide che combinano l’intera unità.
Obiettivi di apprendimento
- Scegliere e giustificare il tipo di ciascun dato di un problema secondo i valori che può assumere, l’esattezza che richiede e le operazioni che si faranno con esso.
- Prevedere gli effetti dei limiti di rappresentazione in un programma dato: l’overflow degli interi, l’arrotondamento della virgola mobile e la perdita di informazione di una conversione.
- Usare costanti con nome e conversioni esplicite, e spiegare che cosa verifica il compilatore in ciascun caso.
- Riconoscere il comportamento indefinito dell’unità e dire, per ciascun caso, che cosa lo rileva e come si previene.
- Separare, in ciò che si è appreso nell’unità, ciò che vale in qualsiasi linguaggio da ciò che è proprio di C++.
Ciò che l’unità ha ottenuto
L’unità si era proposta di insegnare che ogni dato vive in memoria con un tipo che stabilisce quali valori può assumere, quanto spazio occupa e quali operazioni ammette, e che questi limiti hanno conseguenze osservabili. Lo scopo è stato raggiunto appoggiandosi solo su ciò che l’introduzione ha dato per scontato: il ciclo di compilare ed eseguire con le opzioni del corso, l’output formattato, la lettura con std::cin e la lettura dei messaggi del compilatore. Il programma dei quattro conti con cui l’introduzione ha posto il problema può ora essere spiegato riga per riga, e corretto.
Variabili e memoria
La lezione Variabili e memoria ha stabilito che una variabile è una cella di memoria con un nome, un tipo fisso e un valore che cambia, e che il tipo ne fissa la dimensione, che sizeof misura. Ha distinto l’inizializzazione dall’assegnamento, ha mostrato che le graffe rifiutano una conversione con perdita, e ha insegnato che l’assegnamento copia e non lega, e che il valore sostituito si perde, da cui segue la variabile ausiliaria dello scambio. Ha definito lo stato di un programma come l’insieme dei valori delle sue variabili e ha insegnato a seguirlo con una tabella di traccia. Ha fissato le convenzioni dei nomi e si è chiusa con il primo comportamento indefinito dell’unità: la lettura di una variabile che non ha mai ricevuto un valore.
Gli interi e la loro rappresentazione
La lezione Gli interi e la loro rappresentazione ha insegnato la notazione posizionale nelle basi 10, 2 e 16. Dal fatto che un tipo abbia bit ha dedotto il suo intervallo: configurazioni, che senza segno rappresentano da a e con segno, in complemento a due, da a , con un negativo in più dei positivi. Ha distinto i due overflow: quello degli interi senza segno, che è aritmetica modulo ed è definito (0u - 1 vale ), e quello degli interi con segno, che è comportamento indefinito e che il sanitizer arresta. Ha mostrato che confrontare un intero con segno con uno senza segno converte il primo, sicché è falso, e ha terminato con un criterio per scegliere il tipo intero secondo l’intervallo prevedibile del dato.
I numeri in virgola mobile
La lezione I numeri in virgola mobile ha mostrato che un reale si conserva come segno, esponente e mantissa binaria, sicché i valori rappresentabili sono un insieme finito di razionali con denominatore potenza di 2. Ne è seguito che non esiste nella macchina: al suo posto si conserva il double più vicino, e 0.1 + 0.2 si scrive 0.30000000000000004. La lezione ha limitato l’errore di ciascun arrotondamento, ha mostrato che gli errori si accumulano e che la somma smette di essere associativa; da cui ha dedotto che due reali calcolati non si confrontano con ==, ma mediante la loro distanza, con una tolleranza giustificata. Ha fissato double come tipo reale predefinito, e ha presentato l’infinito e il valore non numerico, NaN.
Caratteri, booleani, conversioni e costanti
La lezione Caratteri, booleani, conversioni e costanti ha mostrato che un tipo è una regola per leggere i bit: un char conserva un byte il cui valore è il codice ASCII del carattere, e siccome le cifre e le lettere hanno codici consecutivi, '7' - '0' vale 7; un bool è vero o falso, e qualsiasi numero diverso da zero si converte in vero. Ha studiato le conversioni implicite e ha stabilito che la conversione avviene dentro l’operazione, secondo il tipo degli operandi, e non quando si conserva il risultato: double r{7 / 2} vale 3. Ha insegnato a scrivere la conversione voluta con static_cast, che non evita la perdita, ma la dichiara; ha precisato che le graffe rifiutano il restringimento, e ha mostrato il terzo comportamento indefinito dell’unità, la conversione a intero di un reale che non ci sta. Si è chiusa con le costanti (const, constexpr e static_assert), il tipo dei letterali e auto.
Caricamento del contenuto…