組合があるとしましょう:
typedef union someunion {
int a;
double b;
} myunion;
たとえば、設定した後、どのタイプが結合されているかを確認することはできますか? a = 123?私のアプローチは、この共用体をいくつかの構造体に追加し、intの場合はuniontypeを1に設定し、doubleの場合は2に設定することです。
typedef struct somestruct {
int uniontype
myunion numbers;
} mystruct;
より良い解決策はありますか?
より良い解決策はありますか?
いいえ、あなたが示した解決策は最良の(そして唯一の)解決策です。 union
sは非常に単純です。つまり、割り当てたものを「追跡」しません。彼らがしているのは、すべてのメンバーに同じメモリ範囲を再利用できるようにすることだけです。それらはそれ以上のものを提供しないので、それらをstruct
で囲み、追跡に「タイプ」フィールドを使用することは正確に正しいことです。
Cは、ユニオンのどのフィールドが現在使用されているかを自動的に追跡しません。 (実際、「間違った」フィールドから読み取ると、実装で定義された動作が発生すると思います。)そのため、現在使用/入力されているフィールドを追跡するのはコード次第です。
個別の「uniontype」変数を保持するためのアプローチは、これに対する非常に一般的なアプローチであり、うまく機能するはずです。
現在union
に格納されている型を直接クエリする方法はありません。
union
に格納されている型を知る唯一の方法は、(mystruct
の例のように)明示的なフラグを設定するか、次の場合に制御がコードの特定の部分にのみ流れるようにすることです。ユニオンには既知のアクティブな要素があります。
警告:以下は学習目的のためだけです:
これを行うには、いくつかの醜いトリックを使用できます(和集合のデータ型のサイズが異なる限り、これが現在のケースです)。
#include <stdio.h>
typedef union someunion {
int a;
double b;
} myunion;
typedef struct somestruct {
int uniontype;
myunion numbers;
} mystruct;
#define UPDATE_CONTENT(container, value) if ( \
((sizeof(value) == sizeof(double)) \
? (container.uniontype = ((container.numbers.b = value), 2)) \
: (container.uniontype = ((container.numbers.a = value), 1))))
int main()
{
mystruct my_container;
UPDATE_CONTENT(my_container, 42);
printf("%d\n", my_container.uniontype);
UPDATE_CONTENT(my_container, 37.1);
printf("%d\n", my_container.uniontype);
return (0);
}
しかし、私はあなたがこれを決してしないことを勧めます。
アプリケーションによっては、それが短命のオブジェクトである場合、制御フローでタイプをエンコードできる場合があります。両方の場合に別々のブロック/機能があります
struct value {
const char *name;
myunion u;
};
void throwBall(Ball* ball)
{
...
struct value v;
v.name = "Ball"; v.u.b = 1.2;
process_value_double(&v); //double
struct value v2;
v2.name = "Age";
v2.u.a = 19;
check_if_can_drive(&v2); //int
...
}
void countOranges()
{
struct value v;
v.name = "counter";
v.u.a = ORANGE;
count_objects(&v); //int
}
多分私の変種は助けています
struct Table
{
char mas[10];
int width;
int high;
union stat
{
int st;
char v;
} un;
};
Table tble[2];
strcpy(tble[0].mas, "box");
tble[0].high = 12;
tble[0].width = 14;
tble[0].un.v = 'S';
strcpy(tble[1].mas, "bag");
tble[1].high = 12;
tble[1].width = 14;
tble[1].un.st = 40;
//struct Table *ptbl = &tble[0];
//ptbl++;
for (int i = 0; i < 2; i++)
{
void *pt = &tble[i].un;
if(*((char*)pt) == 'S')
sort(put_on_bag_line);
else
sort(put_on_box_line);
}