优化 C 中的标记联合
Optimizing tagged unions in C
我在个人项目中使用 tagged unions。例如,这是我使用的代码类型:
struct data_unit {
enum {
d_A, d_B, d_C
} dtype;
union {
char a;
int b;
double c;
} data;
};
void print_data(data_unit du) {
switch (du.dtype) {
case d_A: {
printf("%c", du.data.a);
break;
}
case d_B: {
printf("%d", du.data.b);
break;
}
case d_C: {
printf("%lf", du.data.c);
break;
}
default:
break;
}
return;
};
是否有更有效的方法来实现 print_data
,无需手动检查 dtype
的每个案例?如果 C 允许类型列表,我将只使用 enum
遍历它,但这不是一个可用的实用程序。我需要一种通用的方法来执行此操作,因为我计划向联合添加大量数据类型。
这可以吗?如果不是,在这种情况下对我来说更好的策略是什么?
您可以利用这样一个事实,即指向 struct-object 的指针可能被视为指向其第一个成员的指针。因此,在交换 dtype
和 data
时,您可以通过某种通用方式访问所有成员:
struct data_unit {
union {
char a;
int b;
double c;
} data;
enum {
d_A, d_B, d_C
} dtype;
};
typedef void (print_data_unit) (struct data_unit *du);
void print_data_unit_char(struct data_unit *du) {
printf("%c\n", *((char*)(du)));
}
void print_data_unit_double(struct data_unit *du) {
printf("%lf\n", *((double*)(du)));
}
void print_data_unit_int(struct data_unit *du) {
printf("%d\n", *((int*)(du)));
}
static print_data_unit* functions[3] = { print_data_unit_char, print_data_unit_int, print_data_unit_double };
void print_data(struct data_unit du) {
functions[du.dtype](&du);
}
int main() {
struct data_unit du;
du.dtype = 0;
du.data.a = 'c';
print_data(du);
du.dtype = 1;
du.data.b = 100;
print_data(du);
du.dtype = 2;
du.data.c = 200.55;
print_data(du);
}
我在个人项目中使用 tagged unions。例如,这是我使用的代码类型:
struct data_unit {
enum {
d_A, d_B, d_C
} dtype;
union {
char a;
int b;
double c;
} data;
};
void print_data(data_unit du) {
switch (du.dtype) {
case d_A: {
printf("%c", du.data.a);
break;
}
case d_B: {
printf("%d", du.data.b);
break;
}
case d_C: {
printf("%lf", du.data.c);
break;
}
default:
break;
}
return;
};
是否有更有效的方法来实现 print_data
,无需手动检查 dtype
的每个案例?如果 C 允许类型列表,我将只使用 enum
遍历它,但这不是一个可用的实用程序。我需要一种通用的方法来执行此操作,因为我计划向联合添加大量数据类型。
这可以吗?如果不是,在这种情况下对我来说更好的策略是什么?
您可以利用这样一个事实,即指向 struct-object 的指针可能被视为指向其第一个成员的指针。因此,在交换 dtype
和 data
时,您可以通过某种通用方式访问所有成员:
struct data_unit {
union {
char a;
int b;
double c;
} data;
enum {
d_A, d_B, d_C
} dtype;
};
typedef void (print_data_unit) (struct data_unit *du);
void print_data_unit_char(struct data_unit *du) {
printf("%c\n", *((char*)(du)));
}
void print_data_unit_double(struct data_unit *du) {
printf("%lf\n", *((double*)(du)));
}
void print_data_unit_int(struct data_unit *du) {
printf("%d\n", *((int*)(du)));
}
static print_data_unit* functions[3] = { print_data_unit_char, print_data_unit_int, print_data_unit_double };
void print_data(struct data_unit du) {
functions[du.dtype](&du);
}
int main() {
struct data_unit du;
du.dtype = 0;
du.data.a = 'c';
print_data(du);
du.dtype = 1;
du.data.b = 100;
print_data(du);
du.dtype = 2;
du.data.c = 200.55;
print_data(du);
}