• ベストアンサー

条件によって構造体のリスト構造を変えたい

こんにちは。 C(C++)で構造体を使っているのですが、まだまだ未熟で使い方が良く分かりません。以下のことを実施したいのですが、やり方をどなたかご教授頂けませんでしょうか。よろしくお願いします。 条件によって構造体のリスト構造を変えたいのです。 例えば、 条件1の場合は 構造体a→構造体b 条件2の場合は、 構造体a→構造体c 上記のようにです。そして構造体のルートから参照先をたどっていくことで、配下の構造体の値を取得したいのです。 文法上許されないようですが、イメージとしては、 struct a aa; aa.c->b.aa ということをしたいのです。よろしくお願いします。 struct a{ char a; char b; struct c; : }; struct b{ char aa; : }; struct c{ : : };

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

一番手っ取り早いのは、構造体aの中に、構造体bと構造体cの両方のポインタを持たせておいて、使わない側にはNULLを入れるといった方法でしょうか。 struct a {  /* .bまたは.cのNULLではない方が有効 */  struct b *b;  struct c *c; }; 他には、構造体aと構造体bの最初のフィールドの型を同じにしておいて、そこにaかbかを判別できる値を格納するようにし、構造体aと構造体bの共用体へのポインタを構造体aに持たせるといった方法です。 struct b {  char tag; /* 'b'を格納 */  ... }; struct c {  char tag; /* 'c'を格納 */  ... }; struct a {  union  {   struct b;   struct c;  } *p; /* .p->b.tagが'b'なら構造体b, 'c'なら構造体c */ }; 好みかもしれませんが、私なら多分前者を使います。

kerberos_001
質問者

お礼

ご回答ありがとうございます。 返信が遅くなり申し訳ありません。 どうもありがとうございました。

その他の回答 (3)

  • ency
  • ベストアンサー率39% (93/238)
回答No.4

No2 jacta さん、No3 Tacosan さんが回答されているやり方が、おそらくわかりやすい方法でしょうけど、もうちょっと汎用的にしてみました。 # 汎用ポインタ (void*) とキャストの嵐なので、マクロを使うことに # しました。 ------------------------------------------------ /* 判定用 ENUM 値 */ enum tag_e { A_STRUCT, B_STRUCT, C_STRUCT }; /* 構造体の定義 */ struct link_s { enum tag_e tag; void *link_ptr; }; struct a_s { struct link_s link; char aa; }; struct b_s { struct link_s link; char bb; }; struct c_s { struct link_s link; char cc; }; /* 変数定義 */ struct a_s a = { A_STRUCT }; struct b_s b = { B_STRUCT }; struct c_s c = { C_STRUCT }; /* s->t のリンクを参照するためのマクロ */ #define link( s, t ) ((struct t##_s*)(s.link.link_ptr)) /* s からリンクしている先の構造体を判定するためのマクロ */ #define link_tag( s ) (((struct link_s*)(s.link.link_ptr))->tag) ------------------------------------------------ たとえば、次のようにすることになります。 ------------------------------------------------ /* 構造体の値設定およびリンク処理 */ a.aa = 'A'; if ( 条件1 ) { b.bb = 'B'; link( a, b ) = &b; } else if ( 条件2 ) { c.cc = 'C'; link( a, c ) = &c; } /* リンク先構造体の確認 */ if ( link_tag( a ) == B_STRUCT ) { printf( "a->b.bb=%c\n", link( a, b )->bb ); } else if ( link_tag( a ) == C_STRUCT ) { printf( "a->c.cc=%c\n", link( a, c )->cc ); } ------------------------------------------------ これでうまくいく理由は、ちょっと考えてみてください。 # わからないまま使うと、あとでメンテナンスとかをするときに # 大変なことになると思いますので。。。

kerberos_001
質問者

お礼

ご回答ありがとうございます。 返信が遅くなり申し訳ありません。 どうもありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

#2 とほぼ同じですが, 自分の好みだと struct a { enum { as_b, as_c } tag; union { struct b *b; struct c *c; }; }; くらいですかね.

kerberos_001
質問者

お礼

ご回答ありがとうございます。 返信が遅くなり申し訳ありません。 どうもありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

何がやりたいのか、いまいち分かりません。 条件というのは、構造体の中に持っているのでしょうか? 構造体bや構造体cから先のつながり方も分かりません。

kerberos_001
質問者

補足

ご回答ありがとうございます。 説明不足で申し訳ありません。 やりたいことは、構造体のメンバ変数の中に、 別の構造体のポインタを設定したいです。 >条件というのは、構造体の中に持っているのでしょうか? 構造体の外で条件判定しています。例えば、 <処理開始>  構造体aへの値の設定 if 条件1の場合  構造体bへ値の設定  (構造体aと構造体bにリンクを貼りたいので   構造体aのメンバ変数に構造体bのポインタを   設定したい) else if 条件2の場合  構造体cへの値の設定  (構造体aと構造体cにリンクを貼りたいので   構造体aのメンバ変数に構造体cのポインタを   設定したい) <構造体から値を取り出す> ・まず無条件に値が設定されている構造体aの値を取り出す。 ・次の値を取り出したいが、値は構造体bと構造体cのどちらに入っているか分からない。  そこで構造体aのメンバ変数の参照先から値を取り出す。  構造体bと構造体cのメンバ変数はそれぞれ異なっているため、設定処理と取り出し処理も条件によって異なります。 ※条件1と条件2の判定結果を、構造体ではなく、例えばグローバル変数などに退避しておいて、<構造体から値を取り出す>処理の中で、参照する構造体をbかcか判定すれば、構造体をリストする必要はないのかもしれませんが… 以上、まだ説明不足かもしれませんが、よろしくお願いいたします。

関連するQ&A

  • 構造体から他の構造体への代入

    現在C言語で簡単なプログラミングを書いているのですが、 構造体(1)(下記参照)から、構造体(2)(下記参照)への代入の方法がわからず悩んでいます。もしよければ手を貸してください!! 標準関数などがないということはわかったので、 地道に代入を行いたいです。 イメージ・・・(data[n].b = moji[n].d;) (1)struct list_kouzou{ int a; char b[30]; char c[8]; }data[100]; (2)struct list_tai{ char d[30]; }moji[15];

  • 構造体を取得するには

    publicにcは指定してあるとしまして mainの中に構造体を引っ張り込むにはどうしたらいいのでしょうか? 形式上おかしいところもあると思いますが 宜しくお願いいたします main() { X x; } X::c() { struct a { char b[10]; char c[20]; } return ? }

  • 構造体について

    以下のような構造体の宣言が合ったとき struct list { int a; char b[20]; struct list *next; }; struct list *add_list( int a, char *str, struct list *head );・・・1 struct list *del_list( int a, struct list *head );・・・2 1は引数の数が同じため問題ないのですが、2はどういう意味になるのでしょう?

  • 入れ子の構造体について

    例えば、入れ子の構造体を1つ使いたい場合、 struct bbb{ int b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; と書くと、「dt.a.b = 10」とやれば、値等を設定できると思いますが、 入れ子の構造体を2つ使いたい場合も、同じように書けるのでしょうか? struct ccc{ int c; }; struct bbb{ struct ccc b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; dt.a.b.c = 10; と書けるのでしょうか?こんがらがってしまって、どう書いていいのか・・。 2つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 構造体で・・・・

    構造体は配列を使用せずメモリ領域を獲得する関数を使用すること、 *構造体内部のメンバ名には配列を用いて良い。  という、条件があるのですが場合はどのようにすればよろしいでしょうか? どなたか教えてください。 構造体は以下のようになってます。 /*構造体の定義*/ struct seiseki{   char name[20];   int eig;   int suu;   int kok;   char rank[3]; };

  • 構造体 プログラム解説 C言語

    struct tag{ char str[6]; }aa; aa = *(struct tag *)"HELLO"; //5行目 printf("%s\n",aa.str); } 上記のプログラムの5行目の仕組みはどうなってるんですか? ここでのポインタの意味があまりよくわからないんですが、、 一番先頭の * はtag型の構造体変数aaを参照してるんでしょうか? そして、()内の * は何を指してるんでしょうか? いまいち理解しにくいです。どなたか解説お願いします!  

  • C++言語で、構造体のコピーは可能(しても良い)のでしょうか?

    C++言語で、構造体のコピーは可能(しても良い)のでしょうか? 問題がある場合は、なぜだめなのか知りたいです。 構造体は可変長ではありません。 typedef struct kumi { char namae[10]; int ten; }Kumi; Kumi a, b; strcpy(a.namae, "AAA"); a.ten = 50; b = a;

  • C言語の構造体のサイズについて

    いつもお世話になっていります。 早速ですが、C言語の構造体のサイズについて教えてください。 typedef struct B { short code; char name; float price; } B; typedef struct A { B bbb[10]; double sougaku; } A; A aaa; といった構造体があった場合に、 sizeof(aaa.bbb.code) + sizeof(aaa.bbb.name) + … + sizeof(aaa.sougaku) という風に一つ一つサイズを取得し、合計して構造体のサイズを取得した場合と sizeof(aaa) という風に構造体のサイズを取得した場合のサイズの値が異なるといった現象が起きます。 その原因が分からなくて困っております。 そこで考えられる要因をお教えください。 因みに実際の構造体はサイズで言えば2500バイトくらいあります。 froat/char/double/short 型を使用しております。 よろしくお願いします。

  • C言語 リスト構造

    --(装置A)--(装置B)---(装置C)---            |            ---(装置E)--- 上の例のように途中で分岐があるリスト構造を あらわすために、C言語でどのような構造体をもつべきでしょうか? (装置A),(装置B),(装置C)のつながりだけをリスト構造で持つ場合は、 struct device { int no; char name[NAME_SIZE]; device_t *next; //次の device 構造体へのポインタ }; のような構造体を使いリスト構造にできましたが、 (装置A),(装置B),(装置C)のつながりと (装置A),(装置B),(装置E)のつながりの両方に対応する(分岐のある構造にも対応する) ためには、どのようなつくりにすればよいでしょうか? できれば、サンプルなどでおしえていただけますとありがたいです。 よろしくお願い致します。

  • 構造体の中の構造体

    typedef struct number{ int x; struct number *next; }Num; 初心者な質問で申し訳ないんですが、構造体の中に構造体があるのはどう解釈していいんでしょうか? typedef struct number{ int x; int y; }Num; の場合はNum a,b;がint a.x,a.y,b.x,b.yとなるのは分かるんですが・・・

専門家に質問してみよう