I Tipi Fondamentali e gli Interi
“Per avere successo, la pianificazione da sola non è sufficiente. Bisogna anche saper improvvisare.”
— Isaac Asimov, Fondazione
Come anticipato nel primo capitolo, il tipo di un oggetto dichiara al compilatore in che modo quell’oggetto verrà interpretato e utilizzato. Ogni oggetto in un programma C++ deve possedere un tipo.
Questo capitolo esplorerà i tipi fondamentali (noti anche come tipi primitivi o built-in), ovvero i mattoni base del linguaggio disponibili su ogni piattaforma.
I Tipi Interi (Integer Types)
Section titled “I Tipi Interi (Integer Types)”I tipi interi memorizzano numeri interi (senza componente frazionaria). In C++ esistono quattro dimensioni principali per gli interi:
short(abbreviazione dishort int)intlong(abbreviazione dilong int)long long(abbreviazione dilong long int)
Ciascuno di questi può essere con segno (signed, che ammette numeri positivi, negativi e zero) oppure senza segno (unsigned, solo positivi e zero). Di default, se non specificato, un intero è sempre signed.
Dimensioni, OS e Specificatori di Formato
Section titled “Dimensioni, OS e Specificatori di Formato”Le dimensioni in byte dei tipi interi variano a seconda del sistema operativo e dell’architettura. Un caso emblematico è il tipo long:
- Su architetture a 32-bit,
longoccupa 4 byte ovunque. - Su architetture a 64-bit,
longoccupa 4 byte su Windows, ma 8 byte su Linux e macOS. Questo scostamento storico è il motivo per cui non dovresti mai presumere la dimensione esatta di uninto di unlongquando scrivi codice cross-platform.
Ecco gli specificatori da usare con printf:
short➔%hd(unsigned:%hu)int➔%d(unsigned:%u)long➔%ld(unsigned:%lu)long long➔%lld(unsigned:%llu)- Esadecimale ➔
%xo%X - Ottale ➔
%o
I Letterali (Literals)
Section titled “I Letterali (Literals)”Un letterale è un valore fisso e hardcodato direttamente nel codice sorgente. Il C++ supporta quattro notazioni per scrivere i letterali interi:
- Decimale: la base standard (es.
42). - Binario: prefisso
0b(es.0b101010). - Esadecimale: prefisso
0x(es.0x2Ao0xFF). - Ottale: prefisso
0(es.052).
Per migliorare la leggibilità di numeri molto grandi, il C++ permette di usare l’apice singolo ' come separatore delle migliaia (es. 1'000'000), che verrà completamente ignorato dal compilatore.
I Suffissi dei Letterali
Section titled “I Suffissi dei Letterali”Di default, un letterale intero (come 42) viene interpretato dal compilatore come int, a meno che non sia troppo grande, nel qual caso passa a long o long long.
Per forzare esplicitamente il tipo di un letterale, puoi aggiungere dei suffissi:
uoUperunsignedloLperlonglloLLperlong long(Es:42ULLforza il valore a essere ununsigned long long).
Dimensione in Memoria: sizeof e size_t
Section titled “Dimensione in Memoria: sizeof e size_t”Come facciamo a sapere quanti byte occupa un tipo di dato sulla nostra macchina? Il C++ ci mette a disposizione l’operatore unario sizeof().
L’operatore sizeof non restituisce un int generico, ma un tipo speciale chiamato size_t (disponibile nell’header <cstddef>). size_t è un intero senza segno garantito dal compilatore per essere sufficientemente grande da contenere la dimensione massima in byte di qualsiasi oggetto in memoria.
Per stampare un size_t tramite printf, lo specificatore corretto è %zd.