Unions suffers from a problem that there is no easy way to know which member of a union was last changed. In order to keep track of this information, you can embed union
inside a structure that has one another member (called "tag field" or "discriminant"). The purpose of tag field is to remind which member is changed/updated. You can try this:
typedef struct{
int payType; // Tag field
union{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
}OptimizeOptions;
}Options;
But, there is no need to write six separate members for union in your case as all are of int
type. Therefore it can be reduced to
typedef struct{
enum{BASIC_PAY, LUMSUM_PAY, MONTHLU_PAY, WEEKLY_PAY, DAILY_PAY, ANNUAL_PAY} payType;
int pay;
}Options;
Lets understand the use of tag field with a simple example. Suppose we want an array which can store int
and double
type data. This would become possible by using union
. So, first define a union type which will store either int
or double
.
typedef union {
int i;
double d;
} Num;
Next we have to create an array whose elements are Num
type
Num num_arr[100];
Now, suppose we want to assign element 0
of the num_arr
to store 25
, while element 1
stores 3.147
. This can be done as
num_arr[0].i = 25;
num_arr[1].d = 3.147;
Now suppose that we have to write a function which will print the num_arr
elements. The function would be like this:
void print_num(Num n)
{
if(n contains integer)
printf("%d", n.i);
else
printf("%f", n.d);
}
Wait! How could print_num
will decide whether n
contains an integer or double
?
This will be done by using the tag field:
typedef struct{
enum{INT, DOUBLE} kind; //Tag field
union{
int i;
double d;
}u;
}Num;
So, each time a value is assigned to a member of u
, kind
must1 be set to either INT
or DOUBLE
to remind that what type we actually stored. For example:
n.u.i = 100;
n.kind = INT;
The print_num
function would be like this:
void print_num(Num n)
{
if(n.kind == INT)
printf("%d", n.i);
else
printf("%f", n.d);
}
1: It is programmer's responsibility to update the tag field with each assignment to the member of union
. Forgetting to do so will lead to bug, as pointed in comment by @ j_random_hacker.
lumpsumPay
,monthlyPay
andannualPay
. – Impeach