随机访问联合数组的成员
Random access to members of array of unions
简化示例:
typedef union {
int foo;
char* bar;
} int_or_str;
void baz() {
int_or_str* bogus = malloc(sizeof(int_or_str) * 43);
bogus[42].bar = "test";
printf("%s\n", bogus[42].bar);
}
- 如果这可行,编译器会假定
bogus
的所有 42 个成员都是字符指针吗? (显然,我可以尝试这个,但强调 "should")。
- 是否定义了以这种方式访问联合数组时会发生什么?
- 假设,我想要一个实际上包含不同大小值的联合数组,这合法吗? (如果我确定联合成员在内存中的布局方式,我可以单独存储布局并计算偏移量)。
如果您想知道这个问题的动机:基本上,我正在尝试为 运行 时间定义的结构提出一个解决方案。我的想法是用一个联合数组来表示结构字段,再加上一些记录如何访问这些字段的元数据。
广告 1:是的,它会起作用。
ad 2:是的,定义的很完美。
广告 3:是的,这是合法的。
union
的整体思想是它可以容纳不同类型的元素。联合的大小将是联合中最大元素的大小。在 64 位系统上,这可能是 char *
.
的大小
所以不,编译器不会假定所有元素都是字符指针。这就是为什么您必须在语句中使用点符号来告诉编译器您要访问哪种类型的元素,编译器将生成访问权限。
但是正如Tom所说,你无法知道当前存储的是什么类型的元素;必须有一个外部原因(信息)使您知道这一点。如果知道它很重要,则应该将信息存储在数据结构中,例如:
typedef struct {
int whatisthis;
union {
int foo;
char *bar;
} u;
} int_or_str;
并将其设置为:
int_or_str example;
example.whatisthis= 1;
example.u.foo= 1;
example.whatisthis= 2;
example.u.bar= "test";
并像这样访问:
if (example.whatisthis==1) printf("%d\n", example.u.foo);
if (example.whatisthis==2) printf("%s\n", example.u.bar);
简化示例:
typedef union {
int foo;
char* bar;
} int_or_str;
void baz() {
int_or_str* bogus = malloc(sizeof(int_or_str) * 43);
bogus[42].bar = "test";
printf("%s\n", bogus[42].bar);
}
- 如果这可行,编译器会假定
bogus
的所有 42 个成员都是字符指针吗? (显然,我可以尝试这个,但强调 "should")。 - 是否定义了以这种方式访问联合数组时会发生什么?
- 假设,我想要一个实际上包含不同大小值的联合数组,这合法吗? (如果我确定联合成员在内存中的布局方式,我可以单独存储布局并计算偏移量)。
如果您想知道这个问题的动机:基本上,我正在尝试为 运行 时间定义的结构提出一个解决方案。我的想法是用一个联合数组来表示结构字段,再加上一些记录如何访问这些字段的元数据。
广告 1:是的,它会起作用。
ad 2:是的,定义的很完美。
广告 3:是的,这是合法的。
union
的整体思想是它可以容纳不同类型的元素。联合的大小将是联合中最大元素的大小。在 64 位系统上,这可能是 char *
.
所以不,编译器不会假定所有元素都是字符指针。这就是为什么您必须在语句中使用点符号来告诉编译器您要访问哪种类型的元素,编译器将生成访问权限。
但是正如Tom所说,你无法知道当前存储的是什么类型的元素;必须有一个外部原因(信息)使您知道这一点。如果知道它很重要,则应该将信息存储在数据结构中,例如:
typedef struct {
int whatisthis;
union {
int foo;
char *bar;
} u;
} int_or_str;
并将其设置为:
int_or_str example;
example.whatisthis= 1;
example.u.foo= 1;
example.whatisthis= 2;
example.u.bar= "test";
并像这样访问:
if (example.whatisthis==1) printf("%d\n", example.u.foo);
if (example.whatisthis==2) printf("%s\n", example.u.bar);