Unions suffer from the problem that there is no easy way to find out which member of the union was last changed. To track this information, you can embed union inside a structure that has one other member (called a "tag field" or "discriminant"). The purpose of the tag field is to remind which item has been changed / updated. You can try the following:
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 to combine in your case, since all are of type int . 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;
Let's look at using a tag field with a simple example. Suppose we need an array that can store data of type int and double . This is made possible through the use of union . So, first determine the type of union that will store either int or double .
typedef union { int i; double d; } Num;
Next we need to create an array whose elements are Num type
Num num_arr[100];
Now suppose we want to assign element 0 to num_arr to store 25 , and element 1 stores 3.147 . It can be done as
num_arr[0].i = 25; num_arr[1].d = 3.147;
Now suppose we have to write a function that will print num_arr elements. The function will look like this:
void print_num(Num n) { if(n contains integer) printf("%d", ni); else printf("%f", nd); }
Wait! How can print_num decide if n an integer or double ?
This will be done using the tag field:
typedef struct{ enum{INT, DOUBLE} kind;
So, every time a value is assigned to the u member, kind must 1 be set to either int or double on Recall what type we actually saved. For example:
nui = 100; n.kind = INT;
The print_num function will look like this:
void print_num(Num n) { if(n.kind == INT) printf("%d", ni); else printf("%f", nd); }
1 . The responsibility of the programmer is to update the tag field with each assignment to the union member. Forgetting to do this will result in an error, as noted in comment @ j_random_hacker .