将’union’与’enum’结合使用的好例子?

我试图了解以下内容:

‘Union’就像变量一样,我可以在不同类型中存储价值。 如果在它的类型’float’的存储值,但我把它读作’短’怎么办?

有什么方法可以确定我将从工会中检索的价值类型?

我该如何处理案件?

我在某个地方看到了一个音符,他谈到对这样的情况使用“枚举”,但对于为什么没有足够好的解释?

你能解释为什么使用’enions’和’enums’有用/安全吗? 或者展示一些例子。

提前谢谢,尼克。

我相信这是实现标记联合或总和类型的一种方式。 例如在C99中使用匿名联合

enum kind_en { knothing, kint, kfloat, kstring }; struct value_st { enum kind_en kind; union { int n; // when kint float f; // when kfloat char* s; // when kstring }; }; 

然后,例如

 void print_value (struct value_st* v) { if (!v) {puts("nil"); return; }; switch (v->kind) { case knothing: puts("nothing"); return; case kint: printf("int#%d", v->n); return; case kfloat: printf("float#%g", v->f); return; case kstring: printf("string'%s'", v->s); return; default: abort(); } } struct value_st* make_int_value(int i) { struct value_st* val = malloc(sizeof(struct value_st)); if (!val) { perror("malloc int value"); exit(EXIT_FAILURE); }; val->kind = kint; val->n = i; return val; } 

上个世纪的一个更老的例子是XEvent类型的Xlib

请注意,某些编程语言有一种更简单的方式来支持和类型。 在Ocaml你需要

 type val_t = Knothing | Kint of int | Kfloat of float | Kstring of string;; 

最重要的是你有模式匹配

您的问题的答案:

  1. 是的,将类型编码为包含联合的结构:

     union { float f; int i; } my_union; enum { its_a_float, its_an_int } flavor; struct { flavor x; my_union u; } data_blob; 
  2. 我不确定我的问题,是什么类型的案例?

  3. 往上看

  4. 当您在编译时不知道您拥有/需要的确切数据并且需要处理多种相同逻辑数据时,它非常有用。

添加enum类型的新字段并保留有关当前类型的信息

 #include  #include  #include  typedef enum types_tag { CHAR, INT, FLOAT } types_t; typedef union value_tag { char c; int i; float f; } value_t; typedef struct store_tag { types_t type; value_t value; } store_t; void printValue(const store_t *o) { switch (o->type) { case CHAR: printf("%c\n", o->value.c); break; case INT: printf("%d\n", o->value.i); break; case FLOAT: printf("%.3f", o->value.f); break; default: exit(EXIT_FAILURE); } return; } void main() { store_t a; a.type = CHAR; a.value.c = 'A'; printValue(&a); a.type = FLOAT; a.value.f = 10.45; printValue(&a); _getch(); } 

除此之外,您可以将信息保存在一堆内存中并使用void *

 #include  #include  #include  typedef enum types_tag { CHAR, INT, FLOAT } types_t; typedef struct store_tag { types_t type; void* value; } store_t; void printValue(const store_t *o) { switch (o->type) { case CHAR: printf("%c\n", *(char*)(o->value)); break; case INT: printf("%d\n", *(int*)(o->value)); break; case FLOAT: printf("%.3f", *(float*)(o->value)); break; default: exit(EXIT_FAILURE); } return; } void main() { store_t a; a.type = CHAR; a.value = malloc(1); *((char*) a.value) = 'A'; printValue(&a); free(a.value); a.type = FLOAT; a.value = malloc(sizeof(float)); *((float*) a.value) = 34.7; printValue(&a); free(a.value); _getch(); } 

并添加一些函数来隐藏创建和删除变量。