0

我正在遵循 CompSci 论文中的伪代码片段并尝试在 C 中实现它。在这篇论文中,我有两个structs,比如说AB。其中一个是这样的:

struct A {
  B* next;
  int data;
}

虽然B看起来像

struct B {
  A* next;
}

现在,对于 的和的给定实例化a,在某些时候算法告诉我做两件事:AbB

  • 如果a不是B,那么做一些事情
  • a = b

现在,我不能在 C 中进行反射,而且对于第二个要求,我显然会得到不兼容的指针类型。我考虑过unionA结构中加入 a ,也许这会有所帮助,但我想问你们是否有我遗漏的好设计。

4

3 回答 3

3

您正在冒险进入这里的危险领域。看来您正在尝试用一种没有内置支持的语言来实现多态性。

您可以使用几种方案,它们允许您struct A*实际指向包含struct B. 工会可能是最不危险的。但正如你所指出的,没有反思。任何指针都只知道它指向一个内存块,并且如果它被取消引用,则有一种解释该块的方法。 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;
   }
}

-edit-
另一方面,如果结构的内容像您描述的那样简单,您可以简单地添加一个isB成员到struct a,并且只使用一种类型。

于 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) 然后做事
  • a=b->下一个;

但是在这种情况下,a=b->next 的赋值只有在 a!=b->next 时才有意义,所以它应该被移到“do stuff”中

为了使其可编译,您只需在 A 定义前向 B 添加一个 forward-decl :

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 回答