我試圖瞭解以下內容:使用'union'和'enum'的好例子?
'聯盟'的行爲就像一個變量,我可以存儲不同類型的值。 如果在'float'類型的存儲值中,但是我將其讀作'short'會怎麼樣?
有沒有什麼方法可以確定我將從工會中檢索的價值類型?
我該如何處理這種情況?
我在某處看到一個音符,他談到了使用'enum'這樣的例子,但是沒有足夠好的解釋爲什麼?
您能否解釋爲什麼使用'union'和'enums'有用/安全?或者顯示一些例子。
在此先感謝,尼克。
我試圖瞭解以下內容:使用'union'和'enum'的好例子?
'聯盟'的行爲就像一個變量,我可以存儲不同類型的值。 如果在'float'類型的存儲值中,但是我將其讀作'short'會怎麼樣?
有沒有什麼方法可以確定我將從工會中檢索的價值類型?
我該如何處理這種情況?
我在某處看到一個音符,他談到了使用'enum'這樣的例子,但是沒有足夠好的解釋爲什麼?
您能否解釋爲什麼使用'union'和'enums'有用/安全?或者顯示一些例子。
在此先感謝,尼克。
我相信這是一種執行3210或總和類型的方法。 例如在C99使用anonymous union
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;;
,最重要的是你有pattern matching
問題的答案:
是,編碼類型到包含聯合的結構:
union {
float f;
int i;
} my_union;
enum {
its_a_float,
its_an_int
} flavor;
struct {
flavor x;
my_union u;
} data_blob;
不確定我饒有興趣地回答你的問題,是什麼情況?
見上
這是非常有用的,當你不知道在編譯時,你有確切的數據/需求和需要處理相同的邏輯數據的多種口味。
添加新的申請ENUM類型,並保持約電流型
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
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 <stdio.h>
#include <conio.h>
#include <stdlib.h>
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();
}
並添加一些功能來隱藏創建和刪除變量。
是不是完全像我的答案(除非不使用匿名聯合,在這種情況下很方便)? – 2014-09-19 05:35:36
也許,剛剛寫了很長時間,發佈後看到它。 – 2014-09-19 05:37:07
一直髮生在我身上......一點,'main'是'int'類型並返回一個值。僅僅因爲你的編譯器會讓你擺脫「空白」 - 不要。 :) – 2014-09-19 05:42:37
即使沒有成員在邊聯合中,對於只有一個成員,聯合會分配基於哪個成員大小較大的內存。使用此內存可以訪問該聯合中的任何成員。因爲它基於member.and分配高內存在同一時間,只有一個可以訪問的地方是可能的。所以沒有問題。 「 – 2014-09-19 05:26:07
」如果在'float'類型的存儲值中,但是我將它讀作'short'?「 - 未定義的行爲。 「有什麼方法可以確定我將從工會中取回哪些類型的價值?」 - 電腦有記憶;用它來表示聯合中的什麼類型的值。枚舉是表示存儲哪種類型的一種方法。 – 2014-09-19 05:52:00