2013-03-08 56 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