3

我有两个不同的结构,类型字段定义(请参见下文)。

struct A {
int type;
char type_a[8];
char random[8];
};


struct B {
int type;
char type_b[16];
char random[16];
};

现在我想根据类型区分这两种结构,例如

if (type == A)
struct A *a = (struct A *)buff;
if (type == B)
struct B *b = (struct B *)buff;

我不知道事先在 buff 中传递给我的是什么类型的结构。那么如何从buff中提取类型。类型字段保证是两个结构中的第一个字段。

4

3 回答 3

3

你可以用 C 语言中的 OOP 设计模式来做这种事情。

这里的想法是一个Base结构有一个type成员。结构AB“扩展” Base。由于该Base结构是两者的第一个成员AB,任何一个都可以转换为Base并照此使用。

当您只Base需要A使用.BBase

typedef struct Base {
    int type;
} Base;

typedef struct A {
    Base base;
} A;

typedef struct B {
    Base base;
} B;

int ATYPE = 1;
int BTYPE = 2;

int getType(Base *base) {
    return base->type;
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    B b;
    B *bptr;
    Base *base;
    int baseType;

    a.base.type = ATYPE;
    b.base.type = BTYPE;

    base = (Base*)&b;

    baseType = getType(base);

    // something like this is reasonable,
    // since you know that base is an
    // instance of B.
    if (baseType == BTYPE) {
        bptr = (B*)base;
    }

    if (baseType != BTYPE) return -1;
    return 0;
}
于 2013-03-08T20:36:31.610 回答
1

C 具有这种数据结构的联合功能。联合在外观上类似于结构,但联合中的每个成员占用相同的内存位置。然后在下面的示例中使用另一个字段,type以便您知道如何解释该结构。

使用它,您可以解决您的问题而无需任何转换,并保持编译时类型安全。

这是一个完整的例子:

#include <stdio.h>
#include <string.h>

#define TYPE_A 1
#define TYPE_B 2

struct A
{
    char member1[8];
    char member2[8];
};

struct B
{
    char member1[16];
    char member2[16];
};

struct base
{
    int type;
    union
    {
        struct A a;
        struct B b;
    } data;
};

char *get_member2(struct base *buff)
{
    if (buff->type == TYPE_A)
        return buff->data.a.member2;

    if (buff->type == TYPE_B)
        return buff->data.b.member2;

    return NULL;
}

int main(void)
{
    struct base b1;
    struct base b2;

    /* Set up test structs. */

    b1.type = TYPE_A;
    strcpy(b1.data.a.member2, "Hello");

    b2.type = TYPE_B;
    strcpy(b2.data.b.member2, "World");

    /* Print member2 from each struct. */

    printf("%s\n", get_member2(&b1));
    printf("%s\n", get_member2(&b2));

    return 0;
}

输出:

Hello
World

代码:键盘

于 2013-03-08T22:15:22.613 回答
0

假设您不想/不能更改 A 和 B:

#define TYPE_A 0
#define TYPE_B 1

...

struct *B create_B()
{  struct *B= malloc(sizeof B);
   B->type=TYPE_B;
   return B;
}

...

void *buff=create_B();

...

struct A a;
a.type=TYPE_A;
void *buff=&a;

...

struct A *a=NULL;
struct B *b=NULL;
int type = *((int *)buff);
if (type == TYPE_A)
 a = (struct A *)buff;
else if (type == TYPE_B)
   b = (struct B *)buff;

您的代码的问题是 a 和 b 的范围仅在 if 内,并且可能您更需要它。

于 2013-03-08T20:28:14.080 回答