0

私はCompSciペーパーの擬似コードスニペットをフォローしていて、それをCで実装しようとしています。このペーパーではstructs、sayAと。の2つがありBます。それらの1つは次のようになります。

struct A {
  B* next;
  int data;
}

のようにB見えますが

struct B {
  A* next;
}

さて、との特定のインスタンス化に対してa、ある時点で、アルゴリズムは2つのことを行うように指示します。AbB

  • そうaでない場合はB、何かをします
  • a = b

現在、Cでリフレクションを行うことはできず、2番目の要件に対して互換性のないポインター型を取得することは明らかです。構造体にを含めることを考えunionました。Aおそらくそれは役立つでしょうが、私が欠けている良いデザインがあるかどうか皆さんに聞いてみたいと思います。

4

3 に答える 3

3

あなたはここで危険な領域に足を踏み入れています。サポートが組み込まれていない言語でポリモーフィズムを実装しようとしているようです。

struct A*を含むメモリを実際に指すことができるようにするために使用できるいくつかのスキームがありますstruct B。組合はおそらく最も危険性が低いでしょう。しかし、あなたが指摘するように、反省はありません。どのポインタも、それがメモリのブロックを指していることと、逆参照されている場合にそのブロックを解釈する1つの方法を知っているだけです。 voidポインタはその最後の部分すら知りません。タイプの識別を行う唯一の方法は、構造のどこかにタイプを識別する値を挿入することです。

このようなもの:

struct generic {
   enum {ATYPE,BTYPE} type;
   union {
      struct A a;
      struct B b;
    };
};


function process(struct generic* a, struct generic* b)
{
   if (a.type != BTYPE)
   { //do stuff 
   }
   else 
   { 
      *a = *b;
   }
}

-編集-
一方、構造の内容が説明するほど単純な場合は、にisBメンバーを追加するstruct aだけで、1つのタイプのみを使用できます。

于 2012-12-20T18:15:02.600 に答える
0

これが何をするのかわかりませんが、コンパイルするために行うことは次のとおりです。

struct a a;
struct b b;

typedef struct a
{
  struct b* next;
  int data;
} A;

typedef struct b
{
  A* next;
} B;

int main()
{
  A a;
  B b;
}
于 2012-12-20T18:12:56.777 に答える
0

ここで、構造体が正しい方法で定義されている場合、アルゴリズムはそのように記述されている必要があります。

  • if(a!= b-> next)then何かをする
  • a = b-> next;

ただし、この場合、a = b-> nextの割り当ては、a!= b-> nextの場合にのみ意味があるため、「dostuff」に移動する必要があります。

コンパイル可能にするには、A定義の前のBに前方宣言を追加するだけです。

struct B;
struct A {
  B* next;
  int data;
};
struct B {
  A* next;
};
int main () {
  A *a=...;
  B *b=...;
  if (a!=b->next) {
    //do stuff
  }
  a = b->next;
}
于 2012-12-20T18:13:54.377 に答える