2012-01-25 7 views
0

ジェネリックスタックを作成します。私は、リンクされたリストでそれを実装したい。新しいをコピーするために、構造物の2番目のフィールドは、関数へのポインタであるCでリンクリストを使用して実装されたジェネリックスタックを作成


  • :私はいくつかの質問を持っている

    typedef struct stack 
    { 
        void * data; 
    
        void (*copy)(void *o); 
    
        struct stack *next; 
    
    } stack_l; 
    

    私はこの構造stack_lを作成しましたデータ(関数Pushの引数で渡す)。機能プッシュの プロトタイプは:

stack_l *プッシュ(stack_l *ヘッド、ボイド* D)。私は、関数のコピーへのポインタを渡す方法

  1. それは正しいですか?
  2. 私はそれを関数Pushで実装する必要がありますか?
は、それが必要な、構造体のフィールドをinizializeする(例えば)関数NewStackを作成するか、それとも、より良いが、スタックが空の場合、第一の要素を作成するだけでプッシュ機能を持っており、少なくとも1つの要素がある場合、上に新しい要素を追加しますか?
  • *ボイドがmalloc関数で割り当てられる必要がありますか?
+0

明らかに、要素を削除するPop関数も作成しました。 – Kyrol

答えて

1

まず、stackstack_lに異なる識別子を必要としません。さて、あなたの質問に:

Pushの機能は、copyフィールドのタイプと互換性がありません。stack_lです。 structに(member-)関数へのポインタを含めてC++のようにしたい場合は、オブジェクトをこれらの関数に渡す必要があります。

はい、どこかで機能を実装する必要があります。その定義はstruct stackの範囲内にはできません。これは、何らかの種類のコンストラクタ関数が必要であることを意味します(あなたが好きな場合はnewStackと呼ぶことができます)。あなたのコンストラクタは少なくともあなたの関数ポインタを初期化しなければなりません(もしあなたがそれらを保持したいなら)。あなたが明示的に空のスタックが何であるかを述べる必要はあり

stack_l* stackPush(stack_l* head, void* content) { 
    // head might be NULL, meaning the stack is "empty" or it might be an actual pointer 
    // we don't care 
    stack_l* const front = malloc(sizeof(stack_l)); 
    *front = (stack_l){.data = content, .next = head}; 
    return front; 
} 

注:これらの関数ポインタを維持しない選択した場合、あなたが示唆したように、あなたは、あなたのpushルーチンでも初期化コードを置くことができます。だから、わかりやすくするためにコンストラクタを実装することもできます。

stack_l* stackCreateEmpty() { 
    retun NULL; 
} 

多分デストラクタ:

void stackDestroyEmpty(stack_l* s) { 
    assert(s == NULL && "Tried to destroy non-empty stack."); 
} 

あなたの最後の質問:あなたは上記を参照として、あなたはにスペースを取得するためにmallocを使用する必要がありますstack_lオブジェクトを保持している場合は、void*メンバーに余分なスペースを割り当てる必要はありません。その一部はstack_lの一部です。

+0

コメントありがとうございます。 void *コンテンツを.data = contentのデータに割り当てると、私の関数コピーが必要かどうか分かりません。 おそらく私はうまくうまくいきません。 – Kyrol

+0

なぜ私はJavaのようなコンストラクタを作成する必要がありますか? – Kyrol

+2

@Kyrol:あなたはする必要はありません!私が言ったように、それは分かりやすくするために、あなたのスタック実装のユーザーは、保持するためのいくつかのインターフェイスを持っています。 'copy'について:あなたのスタックには' void'ポインタしか格納されていないので(ポインターのリテラル値を格納します)、コピー機能を実装する必要はありません。ポインタをそのままコピーするだけです。 **ただし、**あなたが**ポインタを指しているものをコピーしたいのであれば、あなたのスタックに格納されているものをスタックが不可能に知ることができるので、カスタムコピーパラメータをpush関数に与える必要があります。これがあなたを助けてくれることを願ってください。 – bitmask

関連する問題