C/Enumerazioni, strutture e unioni/Unioni

Indice del libro

Un'unione è un tipo di dato i cui membri condividono lo stesso spazio di memoria. In altre parole, una unione permette di accedere ad una stessa zona di memoria tramite più di un alias. I vantaggi delle unioni sono:

  1. Si risparmia memoria;
  2. Si possono interpretare dati in modi diversi.

Sintassi modifica

 union lamiaunione
 {
  tipo membro1;
  tipo membro2;
  ...
  tipo membroN;
 } variabili;

L'istruzione union dichiara una struttura lamiaunione con dei membri e definisce delle variabili di tipo lamiaunione. Le variabili sono opzionali. È importante ricordare che essendo la memoria in comune tra più variabili, non possono essere presenti due dati contemporaneamente. L'esempio che segue infatti mostra una semplice modalità per capire il tipo di dato attualmente presente nella union e quindi come interpretarlo.

La sintassi per specificare ulteriori variabili di tipo lamiaunione dopo la dichiarazione dell'unione è questa:

 union lamiaunione lamiavariabile;

Con le unioni si possono eseguire l'operazione di assegnamento di un'unione ad un'altra unione dello stesso tipo, accedendo ai membri dell'unione utilizzando l'operatore punto '.'. Non sono ammessi i confronti tra unioni con gli operatori == e !=.

Esempio 1 modifica

Una unione può essere utilizzata per memorizzare dei dati di tipo differente all'interno della stessa struttura. Con una struttura definita nel seguente modo potremmo ad esempio memorizzare una serie di risultati, interi o stringa, ottenuti in un'elaborazione. Un esempio banale potrebbe essere:

#include <stdio.h>
#include <stdlib.h>
#define N 3

int main(void)
{
    struct miastruttura{
        char tipo; // il tipo di valore
        union miaunione{
            int intero;
            char* stringa;
        } valore;
    } risultati[N];
    
    int a[3] = {1,2,3};
    int b[3] = {56, 98, 33};
    int i;
    char errstr[] = "Errore";
    
    for(i = 0; i < N; i++)
    if (a[i]) {
        risultati[i].tipo = 'I';
        risultati[i].valore.intero = b[i] / a[i];
    } else {
        risultati[i].tipo = 'C';
        risultati[i].valore.stringa = errstr;
    }
    return 0;
}

che memorizza il quoziente di una divisione nel caso questa sia possibile, altrimenti memorizza la stringa "Errore".

Esempio 2 modifica

/* Inizializza e utilizza un'unione */
#include <stdio.h>

union numero{
    int valX;
    int valY;
};

int main(){
    union numero Punto; /* Definisce la variabile Punto di tipo union numero */
    Punto.valX=50; /* Inizializza il membro valX dell'unione al valore 50 */
    Punto.valY=100; /* Inizializza il membro valY dell'unione al valore 100 */

    /* Stampa sullo schermo i membri dell'unione */
    printf("Il valore di X vale %d mentre il valore di Y vale %d\n", Punto.valX, Punto.valY);

    return 0;
}

Dal momento che i membri valY e valX occupano lo stesso spazio di memoria, la seconda assegnazione sovrascrive il valore di valX, e l'output del codice di esempio sarà:

Il valore di X vale 100 mentre il valore di Y vale 100

Vantaggi e svantaggi modifica

Le union si rivelano molto utili nei casi in cui un programma fa uso di una variabile di un certo tipo, piuttosto che di un altro, a seconda di una condizione determinata a tempo di esecuzione: infatti la union permette di mettere insieme le variabili in una stessa zona di memoria, riducendo l'occupazione di memoria.