2017-05-17 11 views
0

のアイデアは、BaseStructタイプのポインタでStruct_A又は
のインスタンスStruct_Bのインスタンスへのポインタを作ることが可能であるということです。Cプログラミング - ベース構造体型「派生」タイプ

コンパイラで以下のようにCで "base struct-type"を作成できますか?
あなたの質問に答えるために、まず

#include <stdio.h> 

typedef enum { 
StructType_A, 
StructType_B 
} StructType; 

// >>> base type <<< 
typedef struct { 
StructType type; 
} BaseStruct; 

// >>> type A <<< 
typedef struct { 
StructType type; 
int xyz; 
char blabliblub; 
} Struct_A; 

// >>> type B <<< 
typedef struct { 
StructType type; 
long int abc; 
} Struct_B; 

int main() { 
Struct_A a; 
BaseStruct* ptr; 

a.type = StructType_A; 
a.xyz = 7853; 
a.blabliblub = 'z'; 

ptr = (BaseStruct*) &a; 

if (ptr->type == StructType_A) printf ("YAY :3\n"); 
} 
+3

をあなたの質問はC程度であれば、しないクロスタグC++(C++ Cに関連するものがある場合を除き! = C++)。 – crashmstr

+0

より一般的な属性で後で終了する可能性があるため、派生型の最初の属性として基本構造体を持つ方が良い –

+0

基本型は、データを格納するために使用されません。タイプAまたはタイプBにしかアクセスできない – ikkowy

答えて

1

...私はGCCでそれをテストし、それが働いていたが、私はそれがどこでもうまくいくかどうかわからないよ、でStruct_Bタイプを指すように許可されていませんBaseStructタイプのポインタ、これら2つのタイプが異なる配向の要件を持っている場合(参照C standard):

6.3.2.3ポインタ

(7)オブジェクトまたは不完全型へのポインタ別のオブジェクトまたは不完全な型へのポインタに変換することができます。結果の ポインタが指差しの型に対して正しく整列されていない場合、動作 は未定義です。

しかし、あなたは簡単に適切な組合を構築することにより、このような状況を克服することができます

typedef enum { 
    StructType_A, 
    StructType_B 
} StructType; 

// >>> type A <<< 
typedef struct { 
    int xyz; 
    char blabliblub; 
} Struct_A; 

// >>> type B <<< 
typedef struct { 
    long int abc; 
} Struct_B; 

// >>> composite type <<< 
typedef struct { 
    StructType type; 
    union { 
     Struct_A a; 
     Struct_B b; 
    } content; 
} Union_AB; 


int main() { 
    Struct_A a; 
    a.xyz = 7853; 
    a.blabliblub = 'z'; 

    Union_AB anA; 
    anA.type = StructType_A; 
    anA.content.a.xyz = 7853; 
    anA.content.a.blabliblub = 'Z'; 

    Union_AB someB; 
    someB.type = StructType_B; 
    someB.content.b.abc = 5653L; 

    Union_AB* ptr = (&anA); 
    if (ptr->type == StructType_A) printf ("YAY :3\n"); 

    ptr = (&someB); 
    if (ptr->type == StructType_A) printf ("YAY :3\n"); 

    return 0; 
}