2013-03-08 28 views
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中提取类型。类型字段保证是两个结构中的第一个字段。

+1

你的意思的buff将是一个void * – deeiip 2013-03-08 20:31:24

+0

你能否更详细地解释一下什么是你的intented使用? – qPCR4vir 2013-03-08 22:56:22

+0

这是一个项目,以帮助http://www.cs.rit.edu/~ats/books/ooc.pdf – 2013-03-09 13:06:18

回答

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的范围仅仅是内部的,当且可能需要更多。

+0

这不是重点。问题是,如果指针buff被作为void传递给void * – deeiip 2013-03-08 20:34:09

+0

@ me.deeiip,那么指针buff可以被识别为struct A *或struct B *。我认为这个类型已经是知道了,例如第一次从文件中读取。 – qPCR4vir 2013-03-08 21:01:46

3

你可以做这种类型的事情与一个面向对象的设计模式下

的想法在这里是一个Base结构具有type成员。结构AB“延伸”Base。由于Base结构是AB的第一个成员,因此可以将其转换为Base并按照原样使用。

这会给你一个安全的方式来BaseAB之间浇铸同时给予编译时类型安全,当你只需要使用的Base一个实例。

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; 
} 
+1

值得一提的是,这是真的,因为标准保证在结构的第一个成员之前没有填充。 – 2013-03-08 20:50:33

+0

@ H2CO3它认为套接字地址结构工作的唯一方式就是每个东西都变成平台相关的。你给**非常重要的一点**。 – 2013-03-08 21:03:10

1

C对这样的数据结构具有union特征。联合在外观上与结构相似,但联合中的每个成员占用相同的内存位置。然后在下面的示例中使用另一个字段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 

code: Codepad

+0

Don好答案!你应该写一个例子来演示用户。你的回答是最好的 – 2013-03-09 08:13:41

+0

好的 - 我已经修改了我的答案,包括一个完整的例子。 – 2013-03-09 12:57:00

+0

非常好!..... \ – 2013-03-09 13:05:34