2016-12-04 15 views
3

の可変長異種シーケンスを実装するためにどのように異なるサイズの2つの構造体をあります。構造体

手書きの例は次のようになります。だから、

Struct A a0 = { ... }; 
Struct A a1 = { ... }; 
Struct B b0 = { ... }; 
Struct A a2 = { ... }; 
Struct B b1 = { ... }; 
Struct B b2 = { ... }; 

、この場合には、「配列」a0, a1, b0, a2, b1, b2です。

私はこのシーケンスをいくつかのデータ構造に "置きたい"と思います。 (完全なシーケンスの長さは、実行時にのみ認識され、各インスタンスの出現順序はstruct Astruct Bです)

これを行う最も簡単な方法は何ですか?

Pythonでは、例えば、私のような何かをしたい:

Class A: 
    def __init__(self, x, y, z): 
     self.x, self.y, self.z = x, y, z 

Class B: 
    def __init__(self, x, y): 
     self.x, self.y = x, y 

# Manual example 
a0 = A(...) 
a1 = A(...) 
b0 = B(...) 
a2 = A(...) 
b1 = B(...) 
b2 = B(...) 

my_list = [] 

# The list gets updated as the program runs 
my_list.append(a0) 
my_list.append(a1) 
my_list.append(b0) 
my_list.append(a2) 
my_list.append(b1) 
my_list.append(b2) 
# etc., etc. 

どのように私はCの等価を行うことができますか?

+3

AとBとのラッパー構造体とユニオン。 – BLUEPIXY

+0

幅広く/意見があります。しかし、標準的なPython実装がC言語で書かれていることを暗示するものではありません。 – Olaf

+1

あまりにも幅広くはありませんが、underspecified:配列にO(1)検索時間があります。これは、OPケースでは、追加のスペースを使用して(ユニオンまたはインデックスを介して)行うことができます。または、構造体に必要な領域のみをO(n)ルックアップすることができます。スピード/スペースの条件で要件を記述できますか? – danh

答えて

4

私は1つで両方の構造体をラップするために、ここでは労働組合を使用することをお勧めします:

union Data { 
     struct A A; 
     struct B B; 
}; 

また、あなたは現在、この組合に格納内容を指定する列挙型または任意の他の変数の型を使用することができます。

enum DataType { 
     TYPE_A = 0, 
     TYPE_B 
}; 

そして最後に、あなたは構造体でそれらの両方をラップ:

struct DataHolder { 
     union Data Data; 
     enum DataType DataType; 
}; 

次にyとそれを作るためにあなたはDataHolderへのポインタを使用するか、配列として使用してリストを内部に入れることができます。 Appendは、動的再割り当て(realloc)を使用している可能性があります。しかし、それを追加する機能は、アクセスする必要があります、あなたのリストの中に現在いくつのアイテムがあり、あなたのリストに追加したいデータのタイプです。

+0

これに関する私の唯一の懸念は、 'DataHolder'の_every_インスタンスが' A'と 'B'の最大値と同じくらい大きいということです。 ?)。 'A'は' B'よりもはるかに大きいとします。 「B」の大部分「インスタンス」を含む「DataHolder」インスタンスのシーケンスは、空間的に非常に無駄になる。しかし、このソリューションは非常に便利です。私は、あなたが言うように、 'DataHolder'オブジェクトの配列を使って、私が望むものを正確に行うことができます。 –

+0

はい、すべてのDataHolderがユニオンの「可能な限り」可能な部分です。しかし、違うようにすることもできます。つまり、DataHolder void *に組合を入れずに、構造体を指すことができます。 構造体DataHolder { void *データ; enum DataType DataType; };このようにすれば、安全なスペースが得られますが、DataHolderとDataを別々に割り当てる必要があり、DataTypeに基づいたコードで構造体にキャストする必要があります。私の下の答えのように。 – koper89

1

ポインタを使用すると、異種配列が可能になります。

typedef struct A { 
    int x; 
    int y; 
    int z; 
}*PA; 

typedef struct B { 
    float x; 
    float y; 
}*PB; 

void main() { 
    void * Instance[2]; 
    A a; 
    B b; 

    Instance[0] = &a; 
    Instance[1] = &b; 

    ((PA)(Instance[0]))->x = 2; 
} 

しかし、今、あなたは任意の指定されたインデックスに期待するどのようなタイプを知ることになっているかだけの問題を提起する任意の型を持つことができますか?許容できるカタログ型を開始することを決めた場合、なぜユニオンを使用しないのですか?

+0

私はPythonに慣れていませんが、あなたの例ではクラスの格納を示していますが、リストの要素をどのように使用するのかは分かっていますか? –

+0

各構造体には、型を指定するヘッダが含まれています!また、なぜユニオンを使用しないのですか?知らない –