2011-08-26 18 views
10

Recentemente sto lavorando su Windows e ho trovato che molte strutture dati sono definite come struct con union come variabili membro. Esempio di questo sarebbe EVT_VARIANT in Windows.Cos'è un sindacato?

Non sono riuscito a capire qual è lo scopo alla base di questo.

+0

Beh, cosa ha portato alla tua domanda? Lo scopo dei sindacati è condividere il tempo un'area di memoria, cioè per memorizzare i diversi tipi di dati in momenti diversi nella stessa regione di memoria.Questo può funzionare ovunque, vale a dire un sindacato può essere usato da solo o può essere usato come membro di una struttura.Non c'è assolutamente nulla di speciale o strano in unione viene utilizzato all'interno di una struttura.Per questo motivo, non è chiaro il motivo per cui lo stai chiedendo. – AnT

risposta

16

Quando uno struct contiene union membri viene generalmente eseguito come meccanismo di risparmio di spazio. Se lo struct può essere di determinati sottotipi per cui solo alcuni membri sono validi, allora uno union è un buon modo per non sprecare spazio.

Ad esempio

enum NumberKind { 
    Integer, 
    FloatingPoint 
}; 

struct Number { 
    NumberKind kind; 
    union { 
    int integerValue; 
    float floatValue; 
    }; 
}; 

In questo scenario ho definito un numero struct che può avere tipi tipo di valori numerici: virgola mobile e intero. Non è valido avere entrambi allo stesso tempo quindi piuttosto che sprecare spazio avendo entrambi i membri sempre definiti ho creato uno union che rende l'archiviazione di entrambi uguale alla dimensione del più grande.

Esempio L'utilizzo di Sopra come richiesto

void PrintNumber(Number value) { 
    if (value.kind == Integer) { 
    printf("%d\n", value.integerValue); 
    } else { 
    printf("%f\n", value.floatValue); 
    } 
} 
+1

@downvoter, ti interessa spiegare? – JaredPar

+0

grazie per la spiegazione, ma potresti per favore approfondire l'uso dello stesso. – Avinash

+1

@Avinash ha aggiunto un caso d'uso di esempio – JaredPar

1

L'unione in una tecnica struct viene generalmente utilizzata quando si desidera una struttura in stile variante. In genere è accompagnato da un identificatore di tipo, che viene utilizzato per determinare quale elemento nell'unione controllare. È anche visto in modo opposto, come in Xlib su * NIX, dove è un'unione con le strutture, con il primo membro identico tra tutte le strutture, che definisce quale struttura ha i dati necessari.

0

unione significa che puoi avere uno dei suoi membri come il suo possibile valore. Nell'esempio seguente, vengono visualizzati i valori per ognuno di essi. Ma questa unione può essere un membro di qualche altra struttura, in cui è sufficiente specificare un solo valore: float o intero non entrambi. Spero che questo aiuti.

union { 
      float u_f; 
      int u_i; 
    }var; 

    var.u_f = 23.5; 
    printf("value is %f\n", var.u_f); 
    var.u_i = 5; 
    printf("value is %d\n", var.u_i) 
3

Immagina di avere una struttura che contiene un pacchetto di dati. I dati nel pacchetto possono essere di diversi tipi, quindi è possibile memorizzare il tipo in un membro chiamato type. Quindi, per leggere i dati in questo pacchetto, prima si controlla il tipo, quindi si legge il membro dati corrispondente, che dovrebbe contenere i dati nel pacchetto.

Senza sindacati struct dati sarebbe simile a questa:

struct data { 
    type_t type; 

    int number; 
    char * string; 
    double fraction; 
    long long big_number; 
} 

Questo sarebbe un piuttosto grande struttura di dati. Usa abbastanza spazio per memorizzare uno di tutti i tipi di dati possibili. Questo è un po 'inutile quando avrai sicuramente solo uno di quei membri che contiene informazioni utili in qualsiasi momento.

se usiamo i sindacati:

struct data { 
    type_t type; 

    union payload { 
     int number; 
     char * string; 
     double fraction; 
     long long big_number; 
    } 
} 

Poi la struct contiene un'unica spazio sufficiente per memorizzare il tipo più uno dei membri del carico utile (cioè si avrà assegnata una quantità di memoria pari alla dimensione di type_t più la dimensione del più grande membro del payload possibile). Ciò consente di risparmiare un sacco di spazio ed è molto più efficiente.

Si deve fare attenzione tuttavia, perché se il carico utile contiene un int, è ancora possibile leggerlo come un doppio.Probabilmente otterrai numeri estremamente strani mentre il tuo programma cerca di interpretare i dati in modo errato

3

Come una reliquia dei giorni in cui 64 KB era un bel po 'di memoria, hai una funzione in C++ che consente a più di una variabile di condividere lo stesso ricordo (ma, ovviamente, non allo stesso tempo). Questo si chiama un sindacato, e ci sono quattro modi di base in cui è possibile utilizzare uno:

  • Si può usare in modo che una variabile A occupa un blocco di memoria a un certo punto in un programma, che è tardi occupato da un'altra variabile B di un tipo diverso, poiché A non è più necessario. Ti raccomando di non farlo. Non vale il rischio di errore implicito in un simile accordo. È possibile ottenere lo stesso effetto allocando memoria in modo dinamico.

  • In alternativa, è possibile avere una situazione in un programma in cui è richiesta una vasta gamma di dati, ma non si conosce prima dell'esecuzione quale sarà il tipo di dati - sarà determinato dai dati di input . Raccomando anche di non utilizzare i sindacati in questo caso, poiché è possibile ottenere lo stesso risultato utilizzando un paio di puntatori di tipi diversi e, di nuovo, allocando la memoria in modo dinamico.

  • Un terzo utilizzo possibile per un sindacato è quello che potrebbe essere necessario di tanto in tanto - quando si desidera interpretare gli stessi dati in due o più modi diversi. Questo potrebbe accadere quando hai una variabile di tipo lungo e vuoi trattarla come due valori di tipo short. A volte Windows impacchetterà due brevi valori in un singolo parametro di tipo trasmesso a lungo a una funzione. Un'altra istanza si presenta quando si desidera trattare un blocco di memoria contenente dati numerici come una stringa di byte, solo per spostarlo.

  • È possibile utilizzare un'unione come mezzo per passare un oggetto o un valore di dati intorno a dove non si conosce in anticipo quale sarà il suo tipo. Il sindacato può provvedere a memorizzare uno qualsiasi dei possibili tipi di tipi che potresti avere.

Se pensi che io sono un genio nello spiegare ciò che un sindacato è e alcuni dei suoi possibili applicazioni, non posso prendere credito per questo. (: Questa informazione proviene da Beginning Visual C++ 2010 di Ivor Horton che mi è capitato di sedere qui sulla mia scrivania.Per quanto mi è stato utile

Problemi correlati