Programmazione

Tipi Interi Modificati

Qualificatori di Tipo e Suffissi per Costanti in Linguaggio C: short, long, long long, unsigned, suffissi numerici (F, L, U, LL), operatore sizeof() e la libreria stdint.h.

Durata

20 minuti

Software

Compiler C / GCC / Dev-C++ / VS Code

Linguaggio

Linguaggio C

Qualificatori di Tipo e Suffissi in Linguaggio C

Argomenti: modificatori di ampiezza e segno, operatore sizeof(), suffissi delle costanti, prevenzione dell'overflow, tipi stdint.h

I tipi di dato base del C (come int e double) non sempre bastano: a volte serve risparmiare RAM su sistemi embedded, oppure memorizzare numeri astronomici che supererebbero i 2 miliardi. Per controllare con precisione **memoria, segno e intervallo di valori**, il C mette a disposizione i qualificatori di tipo e i suffissi per le costanti.

1. I Qualificatori per Tipi Interi

Modificatori: Come variare la dimensione (short, long, long long) ed il segno (unsigned)

Tipo Modificato Descrizione e Intervallo Tipico Byte Tipici Spec. printf
short int (o solo short) Intero ridotto con segno. Range: da $-32.768$ a $+32.767$. Ideal per array grandi. 2 Byte (16 bit) %hd
int Intero standard con segno. Range: da $-2,1 imes 10^9$ a $+2,1 imes 10^9$. 4 Byte (32 bit) %d oppure %i
unsigned int (o solo unsigned) Intero senza segno (solo numeri $\ge 0$). Raddoppia il massimo positivo: da $0$ a $+4,2 imes 10^9$. 4 Byte (32 bit) %u
long int (o solo long) Intero lungo con segno. Garantito almeno 4 Byte (spesso 8 Byte su Linux 64 bit). 4 o 8 Byte %ld
unsigned long Intero lungo senza segno. Intervallo positivo esteso (fino a $1,8 imes 10^{19}$ su 64 bit). 4 o 8 Byte %lu
long long int (C99) Intero ultra-capiente a 64 bit. Range: da $-9 imes 10^{18}$ a $+9 imes 10^{18}$. Utile per timestamp o monete virtuali. 8 Byte (64 bit) %lld

L'importanza di unsigned

Un bit dei numeri standard viene riservato per memorizzare il segno (+ o -). Rimuovendo i numeri negativi con unsigned, quel bit viene usabile per il valore, raddoppiando l'intervallo positivo. È perfetto per contatori, indici, dimensioni e conteggi di oggetti fisici che non possono mai essere negativi.

La Catena di Garanzia delle Dimensioni

Lo standard C non impone la dimensione esatta in Byte, ma garantisce una gerarchia precisa:

sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long)

2. Suffissi per le Costanti Numeriche (Literals)

Tipi Espliciti: Forzare il tipo esatto dei numeri scritti a mano nel codice

I numeri scritti direttamente nel sorgente (es. 100 o 3.14) hanno un tipo implicito assegnato dal compilatore. Aggiungendo un suffisso in coda al numero, si indica in modo inequivocabile come allocarlo:

Suffissi per Numeri Decimali

  • f oppure F ➔ Forza il valore a float (4 Byte):
    float x = 3.14f; (evita warning da double).
  • l oppure L ➔ Forza il valore a long double (8, 10 o 16 Byte):
    long double p = 3.141592653589793238L;

Suffissi per Numeri Interi

  • u oppure U ➔ Intero senza segno (unsigned int): 4000000000U
  • l oppure L ➔ Intero lungo (long int): 3000000000L
  • ll oppure LL ➔ Intero a 64 bit (long long): 9000000000000LL
  • ul oppure UL ➔ Combinato senza segno lungo: 5000000000UL

3. Laboratorio Pratico: Misurare i Tipi con sizeof()

Strumenti: Operatore sizeof(), libreria <limits.h> e stampa dinamica

Sorgente C (misura_tipi.c):
1 #include <stdio.h>
2 #include <limits.h> // Contiene le costanti limite (es. INT_MAX)
3
4 int main(void) {
5     printf("=== ANALISI DEGLI INTERI === ");
6     printf("short: %zu byte | Max: %d ", sizeof(short), SHRT_MAX);
7     printf("int: %zu byte | Max: %d ", sizeof(int), INT_MAX);
8     printf("unsigned int: %zu byte | Max: %u ", sizeof(unsigned), UINT_MAX);
9     printf("long: %zu byte | Max: %ld ", sizeof(long), LONG_MAX);
10     printf("long long: %zu byte | Max: %lld ", sizeof(long long), LLONG_MAX);
11
12     // Esempio con costante con suffisso
13     unsigned long long popMondiale = 8000000000ULL;
14     printf("Popolazione: %llu persone ", popMondiale);
15
16     return 0;
17 }
Dettagli da Notare:
  • Specificatore %zu: L'operatore sizeof() restituisce un tipo speciale chiamato size_t. Il suo specificatore di stampa corretto in printf è %zu.
  • Libreria <limits.h>: Fornisce le costanti che indicano i limiti del tuo compilatore (es. INT_MAX, SHRT_MAX, LLONG_MAX).
  • Suffisso ULL (riga 13): Indica che la costante `8000000000` è un `unsigned long long` a 64 bit, prevenendo errori di troncamento durante la compilazione.

4. Integer Overflow e i Tipi Moderni (<stdint.h>)

Sicurezza del Codice: Cosa succede se si supera il limite e come scrivere codice portabile

Che cos'è l'Integer Overflow?

Se aggiungi 1 a una variabile che ha già raggiunto il suo valore massimo gestibile, si verifica un overflow. Nei tipi unsigned, il valore fa un "giro completo" e torna a 0.

unsigned short x = 65535;
x = x + 1; // x diventa 0!

I Tipi a Dimensione Fissa (<stdint.h>)

Poiché la dimensione di int e long può variare tra PC, Linux ed Embedded, dallo standard C99 esiste la libreria <stdint.h> con tipi a bit garantiti:

  • int8_t / uint8_t (Esattamente 1 Byte / 8 bit)
  • int16_t / uint16_t (Esattamente 2 Byte / 16 bit)
  • int32_t / uint32_t (Esattamente 4 Byte / 32 bit)
  • int64_t / uint64_t (Esattamente 8 Byte / 64 bit)

Come orientarsi nella scelta quotidiana?

• Per la stragrande maggioranza dei numeri interi quotidiani, usa int.
• Se stai lavorando con indici di array, contatori o dimensioni di memoria, usa unsigned o size_t.
• Se devi gestire timestamp, ID di database o quantità monetarie in centesimi, usa long long o int64_t.


In sintesi

Argomenti: concetti principali, riepilogo, competenze

  1. I qualificatori (short, long, long long, unsigned) modificano l'intervallo di valori e l'occupazione di memoria dei tipi interi.
  2. L'uso di unsigned elimina i numeri negativi raddoppiando il valore massimo positivo gestibile.
  3. I suffissi (F, L, U, LL) comunicano al compilatore il tipo esatto delle costanti letterali scritte nel codice.
  4. L'operatore sizeof() restituisce la dimensione reale in Byte dei tipi di dato sul sistema in uso.

Cosa hai imparato
  1. Distinguere l'uso e i limiti di short, int, long, long long ed unsigned.
  2. Utilizzare lo specificatore di formato corretto in printf/scanf (%d, %u, %ld, %lld, %zu).
  3. Applicare i suffissi alle costanti letterali per evitare troncamenti o conversioni indesiderate.
  4. Comprendere il fenomeno dell'Integer Overflow e l'uso pratico di <stdint.h> (int32_t, uint64_t).


Linguaggio C, Qualificatori, short, long, unsigned, sizeof, Suffissi, stdint.h, Overflow,