In informatica (principalmente nella programmazione), un tipo di dato si dice primitivo o atomico se definisce un insieme di valori atomici, che non possono essere ulteriormente suddivisi o decomposti in tipi di dati più semplici. Si tratta pertanto di un tipo di dato fondamentale, fornito nativamente da un linguaggio di programmazione come elemento costruttivo di base.

I tipi primitivi vengono spesso adoperati in opposizione ai tipi strutturati o composti che, al contrario, aggregano più tipi atomici per formare delle strutture dati più complesse (come gli array, i record o le classi).

A seconda dell'architettura hardware e del compilatore, i tipi primitivi corrispondono generalmente in modo diretto alle rappresentazioni dei dati native così come vengono salvati e manipolati dal processore in uso, garantendo pertanto la massima velocità possibile di elaborazione.

Tuttavia, questa corrispondenza non ha validità universale e rischia di generare confusione tra la classificazione strutturale (tipi primitivi e composti) e la modalità di gestione del dato in memoria (tipi valore e tipi riferimento).

La prima distinzione riguarda unicamente la struttura del dato, separando i tipi indivisibili (atomici) da quelli divisibili (composti). La seconda classificazione, al contrario, definisce come il dato viene gestito in memoria, distinguendo tra tipi valore (il cui contenuto è allocato direttamente all'interno della variabile) e tipi riferimento (quando la variabile memorizza solo l'indirizzo di memoria in cui risiede il dato reale). Non è sempre vero che un tipo primitivo sia anche un tipo valore, così come non è affatto detto che un tipo composto sia anche un tipo di riferimento.

Caratteristiche principali I tipi primitivi si distinguono nel panorama della programmazione per alcune proprietà architetturali e semantiche:

Atomicità: Un valore di tipo primitivo rappresenta una singola entità logica indivisibile. Ad esempio, un intero rappresenta unicamente un valore numerico fisso, a differenza di un tipo strutturato come una stringa o una lista, che può essere scomposto in singoli caratteri o elementi. Gestione come "Tipo Valore" (Value Type): Nella maggior parte dei linguaggi di programmazione tradizionali (come C++ o Java), i tipi primitivi sono trattati come tipi valore. Ciò significa che una variabile di tipo primitivo memorizza direttamente il valore effettivo al proprio interno (generalmente nell'area di memoria dello stack), anziché memorizzare un indirizzo o un riferimento a un oggetto allocato altrove (nell'area heap). Efficienza computazionale: Poiché hanno una corrispondenza diretta con i registri e le istruzioni della CPU, le operazioni fondamentali su di essi (come l'addizione aritmetica o i confronti logici) vengono solitamente tradotte in singole istruzioni macchina, minimizzando l'overhead computazionale.

Tipi primitivi comuni Benché ogni linguaggio di programmazione possa definire un proprio set specifico di primitivi, la maggior parte dei linguaggi moderni e di alto livello condivide un gruppo di tipi di dati standard:

Numeri interi Rappresentano i numeri appartenenti all'insieme dei numeri interi. Possono variare in base allo spazio di memoria allocato (ad esempio 8, 16, 32 o 64 bit) e alla possibilità di includere o meno il segno aritmetico (con segno o senza segno). Esempi tipici sono byte, short, int e long.

Numeri in virgola mobile (Floating-point) Rappresentano un'approssimazione dei numeri reali, dotati di parte frazionaria. La maggior parte dei sistemi moderni implementa questi tipi seguendo lo standard internazionale IEEE 754. I formati più diffusi sono a precisione singola (tipicamente indicati come float a 32 bit) e a doppia precisione (indicati come double a 64 bit).

Booleani Rappresentano una variabile logica a due stati, che può assumere unicamente i valori di vero (true) o falso (false). Vengono ampiamente impiegati per la valutazione di espressioni condizionali e per il controllo del flusso logico dei programmi.

Caratteri Rappresentano un singolo simbolo grafico o di controllo. Solitamente identificati con la parola chiave char, la loro codifica è storicamente basata sullo standard ASCII (a 8 bit) o, nei linguaggi più recenti, sullo standard Unicode (a 16 o 32 bit, come UTF-16) per consentire la rappresentazione di alfabeti internazionali.

(Nota: Le stringhe di testo, sebbene fornite nativamente in quasi tutti i linguaggi, sono spesso considerate tipi derivati o composti poiché strutturate internamente come sequenze o array di caratteri).

Differenze nei linguaggi di programmazione L'implementazione e i dettagli di allocazione dei tipi primitivi differiscono sensibilmente a seconda del paradigma del linguaggio di programmazione:

C e C++ In C e C++, le dimensioni fisiche in bit dei tipi primitivi fondamentali (come int o char) non sono definite in modo rigido dallo standard del linguaggio, ma dipendono strettamente dall'architettura del processore di destinazione e dal compilatore utilizzato. Per superare questa variabilità, standard più recenti (come C99 e C++11) hanno introdotto librerie di tipi interi a dimensione fissa definita, quali int32_t o uint64_t.

Java Java è un linguaggio orientato agli oggetti, ma per ragioni di velocità e prestazioni ha mantenuto anche i tipi primitivi, che non sono oggetti ma semplici valori salvati direttamente in memoria. Nella definizione di questi tipi, adotta una classificazione rigida e indipendente dall'architettura hardware sottostante. Definisce esattamente otto tipi primitivi, le cui specifiche e dimensioni sono immutabili su qualunque piattaforma di esecuzione (Java Virtual Machine):

byte (8 bit, con segno) short (16 bit, con segno) int (32 bit, con segno) long (64 bit, con segno) float (32 bit, virgola mobile) double (64 bit, virgola mobile) char (16 bit, carattere Unicode) boolean (valore logico)

Tuttavia, ci sono situazioni in cui Java pretende assolutamente un oggetto e non accetta un tipo primitivo. Per evitare problemi di compatibilità, per ciascuno di questi tipi il linguaggio fornisce una classe "wrapper" corrispondente (come Integer per il tipo int) che consente di trattare i primitivi come oggetti qualora sia richiesto dall'architettura orientata agli oggetti del software. Queste classi forniscono inoltre ulteriori vantaggi e flessibilità, permettendo ad esempio di definire valori null e sfruttare metodi standard. La conversione tra tipo primitivo e classe wrapper (o viceversa) viene infine gestita automaticamente dal linguaggio attraverso un processo denominato autoboxing.

JavaScript In JavaScript, i tipi primitivi sono predefiniti a livello di runtime e i loro valori sono immutabili (ossia non modificabili dopo la creazione). Il linguaggio individua i seguenti primitivi:

Undefined (variabile dichiarata ma priva di valore assegnato) Null (assenza intenzionale di un valore) Boolean (vero o falso) Number (rappresentazione a 64 bit in virgola mobile per tutti i numeri) BigInt (per rappresentare numeri interi arbitrariamente grandi) String (in questo linguaggio, le stringhe di caratteri sono considerate valori primitivi) Symbol (identificatori univoci e immutabili)

Python Python si discosta dall'approccio classico orientato ai tipi valore: nel linguaggio "tutto è un oggetto". Ne consegue che anche i tipi fondamentali come int, float e bool sono istanze di classi specifiche con metodi integrati, benché l'interprete esegua ottimizzazioni interne trasparenti per garantire l'efficienza tipica dei tipi primitivi tradizionali.

Voci correlate

Tipo di dato Struttura dati Tipo valore e tipo riferimento Variabile (informatica) Controllo dei tipi

Categoria:Programmazione orientata agli oggetti

es:Tipo primitivo