在 C 中,是否可以在另一个联合中定义一个联合?如果不是,为什么不可能?或者如果是,它可以在哪里使用?
5 回答
假设您要定义:
union myun {
int x;
sometype y;
};
sometype
您正在typedef
使用的库定义的位置在哪里。如果库碰巧将它实现为联合类型,那么这将是联合中的联合,这是有道理的,因为您不能(从良好的设计角度)违反库类型的封装。
是的,这是可能的,而且很有用。原因与 Y 中的 X 对 X 和 Y 的许多值有用的原因相同:组合性。程序是通过将微小的组件组装成小组件变成大的组件变成巨大的组件变成......有时一堆联合体碰巧组装成一个联合体,那又怎样?
R..'s answer显示了一个在幕后发生的示例:恰好其中一种联合成员类型是联合,但除非您查看库实现,否则您不知道这一点。
编辑但是,请注意,有区别的联合的通用习惯用法,其中联合的每个成员都是一个结构,其第一个字段是包含标记的整数类型,不会扩展到嵌套联合。也就是说,以下是 C 中可区分联合的常见、符合标准 ( N1256 §6.5.2.3.5) 的实现:
struct generic {
unsigned tag;
};
struct smallnum {
unsigned tag; /*always TAG_SMALLNUM*/
unsigned value;
};
struct bignum {
unsigned tag; /*always TAG_BIGNUM*/
size_t length;
unsigned *p;
};
struct string {
unsigned tag; /*always TAG_STRING*/
size_t length;
char *p;
};
union number {
struct bignum bignum;
struct smallnum smallnum;
};
union object {
struct generic generic;
struct bignum bignum;
struct smallnum smallnum;
struct string string;
};
如果您有一个union object
object ,无论实际分配给该对象的是什么x
,您都可以始终将其标签读取为x.generic.tag
(或任何其他标签)。x.bignum.tag
通过使用对象的唯一标签(鉴别器)。
下面的定义是合法的,但没有用,因为你不能只读取对象的第一个字段union level2
来获取标签:如果一个union level2
对象写成 a union number
,你必须通过number
成员读取它的标签,否则你必须读取它的标签通过generic
orstring
成员标记。如果通过错误的成员访问对每个现有的实现都有效,我不会感到惊讶,但它不符合标准。
union level2 {
struct generic generic;
union number number;
struct string string;
};
对的,这是可能的。但我倾向于坚持永远不要使用工会的建议。工会是正确答案的情况很少。我怀疑不存在包含工会的工会是一个好主意的情况。
对的,这是可能的。虽然想出一个人为的例子很容易,但我想不出如何很好地利用我的头顶。
是的,一个联合可能包含另一个联合:
union foo {
int x;
double y;
union bar {
char blah[10];
char *blurga;
} bletch;
};
不过,我想不出它会有用(甚至是可取的)的情况。