我正在努力优化项目。它包含一个选项结构,用户可以在其中一次选择一个选项。除了该选项之外,我们还使用标志变量来检查为此记录设置的选项值。 为了使内存有效,我想将struct转换为union。但是,我如何知道联合中设置了哪个变量值。因为联合中没有限制来获取变量的值,即使没有设置它也是如此。
struct options{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
int payType; // Flag variable to check which option is selected
};
union OptimizeOptions{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
int payType; // Confuse at here
};
答案 0 :(得分:17)
工会遇到的问题是,没有简单的方法可以知道工会的哪个成员最后一次更改。为了跟踪此信息,您可以将union
嵌入到具有另一个成员的结构中(称为“标记字段”或“判别”) 。标记字段的目的是提醒更改/更新哪个成员。你可以试试这个:
typedef struct{
int payType; // Tag field
union{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
}OptimizeOptions;
}Options;
但是,在你的情况下,没有必要为联盟写六个单独的成员,因为它们都是int
类型。因此可以减少到
typedef struct{
enum{BASIC_PAY, LUMSUM_PAY, MONTHLU_PAY, WEEKLY_PAY, DAILY_PAY, ANNUAL_PAY} payType;
int pay;
}Options;
让我们通过一个简单的例子来理解使用标记字段。假设我们想要一个可以存储int
和double
类型数据的数组。使用union
可以实现这一点。因此,首先定义一个将存储int
或double
的联合类型。
typedef union {
int i;
double d;
} Num;
接下来,我们必须创建一个元素为Num
type
Num num_arr[100];
现在,假设我们要将0
的元素num_arr
分配给商店25
,而元素1
则存储3.147
。这可以作为
num_arr[0].i = 25;
num_arr[1].d = 3.147;
现在假设我们必须编写一个打印num_arr
元素的函数。功能如下:
void print_num(Num n)
{
if(n contains integer)
printf("%d", n.i);
else
printf("%f", n.d);
}
等待! print_num
如何决定n
是否包含整数或double
?
这将通过使用标记字段来完成:
typedef struct{
enum{INT, DOUBLE} kind; //Tag field
union{
int i;
double d;
}u;
}Num;
因此,每次将值分配给u
的成员时,kind
必须 1 为设置为INT
或DOUBLE
以提醒我们实际存储的类型。例如:
n.u.i = 100;
n.kind = INT;
print_num
函数将是这样的:
void print_num(Num n)
{
if(n.kind == INT)
printf("%d", n.i);
else
printf("%f", n.d);
}
1 :程序员有责任使用union
成员的每个作业更新标记字段。忘记这样做会导致错误,正如@ comment在 j_random_hacker中指出的那样。
答案 1 :(得分:15)
您是否在union
内尝试了struct
?让我们看看以下示例等效:
union options{
int basicPay;
int lumsumPay;
int mothlyPay;
int weeklyPay;
int dailyPay;
int anualPay;
};
struct record{
union options op; // Options union
int payType; // Flag variable to check which option is selected
}
union(options
)将为其最大变量保留内存,您可以设置其值,您的结构(记录)将跟踪该联合内存块,并且payType
标志值可能是设置将告诉你的程序获取联合的特定变量。
答案 2 :(得分:0)
现在 std::variant
包含了这个通用功能。
std::variant<int, float> x;
x = 42;
bool is_x_an_int = std::holds_alternative<int>(x); // YES
bool is_x_a_float = std::holds_alternative<float>(x); // NO
int value_of_x = std::get<int>(x); // 42
int an_error = std::get<float>(x); // exception