web-dev-qa-db-ja.com

Cで構造体の結合を操作する

次のタイプがあるとします。

typedef struct TYPEA
{
    int type;
    char[12] id;
} TYPEA;

typedef struct TYPEB
{
    int type;
    int value;
} TYPEB;

これらの型と「int」の和集合を作成して、TYPEAとTYPEBのどちらが和集合に格納されているかを知らなくても「type」intにアクセスできるようにします(intの値により、実際に格納されているものを判別できます)そこ)。しかし、正しい構文を取得できません。

私の組合:

typedef union MEMBER
{
    int type;
    struct TYPEA a;
    struct TYPEB b;
} MEMBER;

ユニオンには、次の方法でアクセスします。

typedef struct WRAPPER
{
    union MEMBER* member;
    struct WRAPPER* next;
} WRAPPER;

質問:

  1. (割り当てられたWRAPPER構造体へのポインターとして「w」を使用)w->member->a.idを使用してアクセスすると、構造体または共用体ではないもので「メンバー 'id'の要求」が返されます。
  2. すでにmallocされたTYPEA/Bへのポインタをw-> memberに直接割り当てることはできますか?それとも、組合は特別にマロックする必要がありますか?

ありがとう。

6
rikkit
  1. 使用する w->member->type
  2. unionを具体的に割り当てる必要があります。

誤解のポイントとなる可能性がある1つの注意点は、unionintTYPEA、またはTYPEBのいずれかを保持するため、特に信頼できないことです。あなたのint type;組合で、組合が保持しているstructを教えてください。

コメントの質問に回答するために編集:

あなたはおそらくこのようなものが欲しいでしょう:

struct TYPEA {
  char data[30]; // or whatever
};

struct TYPEB {
  double x, y; // or whatever
};

struct some_info {
  int type; // set accordingly
  union {
    struct TYPEA a;
    struct TYPEB b;
  } data; // access with some_info_object.data.a or some_info_object.data.b
};
11
  1. memberフィールドをポインタとして定義したので、w->member->typeの代わりにw->member.typeを使用する必要があります。
  2. 共用体型をmallocする必要があります。ユニオンを割り当てると、ユニオンの最大要素に等しいsizeofを持つ構造体が得られます。構造体をユニオンポインタにコピーしようとすると、配置が台無しになります。
1
Zach Rattner

w->member.typeはポインタであるため、w->member->typew->memberである必要があります。

CがTYPEA*またはTYPEB*MEMBER*に割り当てることができるかどうかは頭の中でわかりません-どういうわけか私はそれを疑っています。いつでも(MEMBER*)できますが、structsを再構成してintタグを削除し、代わりにタグとstructunionTYPEAを含む1つのTYPEBを宣言することを検討します。 structsは、理想的には、それらがunionにあるという事実を考慮する必要はありません。

0
sqykly

あなたは私の質問のコードをチェックしたいかもしれません:

共通の最初のメンバーを持つ構造体の結合

基本的に、私はあなたがやりたいことをしますが、2つのタイプに共通の内部構造体(例ではcontained)を使用しています。次に、この構造体をキャストして、両方のタイプの共通要素にアクセスできます。

0
backscattered