sindacati soffre di un problema che non esiste un modo semplice per sapere quale membro di un sindacato dell'ultima modifica. Per tenere traccia di queste informazioni, è possibile incorporare union
all'interno di una struttura che ha un altro membro (chiamato "campo tag" o "discriminante"). Lo scopo del campo tag è ricordare quale membro viene modificato/aggiornato. Si può provare questo:
typedef struct{
int payType; // Tag field
union{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
}OptimizeOptions;
}Options;
Ma, non c'è bisogno di scrivere sei membri separati per l'unione nel tuo caso, come tutti sono di int
tipo. Di conseguenza può essere ridotto a
typedef struct{
enum{BASIC_PAY, LUMSUM_PAY, MONTHLU_PAY, WEEKLY_PAY, DAILY_PAY, ANNUAL_PAY} payType;
int pay;
}Options;
Consente capire l'uso di campo tag con un semplice esempio. Supponiamo di volere un array in grado di memorizzare i dati di tipo int
e double
. Ciò sarebbe possibile utilizzando union
. Quindi, per prima cosa definire un tipo di unione che memorizzerà int
o double
.
typedef union {
int i;
double d;
} Num;
Ora dobbiamo creare un array i cui elementi sono Num
tipo
Num num_arr[100];
Ora, supponiamo di voler assegnare elemento 0
del num_arr
per memorizzare 25
, mentre l'elemento 1
negozi 3.147
. Questo può essere fatto come
num_arr[0].i = 25;
num_arr[1].d = 3.147;
Supponiamo ora che dobbiamo scrivere una funzione che stamperà i num_arr
elementi. La funzione sarebbe così:
void print_num(Num n)
{
if(n contains integer)
printf("%d", n.i);
else
printf("%f", n.d);
}
Attendere! Come potrebbe print_num
decidere se n
contiene un numero intero o double
?
Questo sarà fatto utilizzando il campo tag:
typedef struct{
enum{INT, DOUBLE} kind; //Tag field
union{
int i;
double d;
}u;
}Num;
Così, ogni volta che un valore viene assegnato a un membro di u
, kind
must essere impostato sia INT
o DOUBLE
per ricordare che tipo abbiamo effettivamente memorizzato.Per esempio:
n.u.i = 100;
n.kind = INT;
La funzione print_num
sarebbe stato così:
void print_num(Num n)
{
if(n.kind == INT)
printf("%d", n.i);
else
printf("%f", n.d);
}
: È responsabilità del programmatore per aggiornare il campo tag con ogni incarico al membro del union
. Dimenticare di farlo porterà a bug, come indicato in comment da @ j_random_hacker.
@ user3121023 ha ragione: l'unica volta che hai bisogno di un sindacato è quando uno o più membri hanno tipi diversi. Anche ortografia: 'lumpsumPay',' monthlyPay' e 'annualPay'. –