2011-10-18 9 views
2

私は*がポインタを定義していることを知っています... **はポインタへのポインタを定義しますか?この単純なハッシュ実装で**は何をしていますか?

もしそうなら、なぜですか?

ポインターへのポインターは参照と呼ばれることがありますか?次の非常に単純なハッシュの明確化が必要です。

一般的には、内容全体を渡すにはコストがかかりすぎるため、より大きな構造の場所を渡すためにポインタが使用されます。

私は、各「オブザーバー」が実行時に変更される「用語構造」ポインターへのポインターを保持するので、「ハンドル」を作成するためにquantlibプロジェクトで使用されるポインターを見てきました。別のポインタの。

ここでは相関関係はありませんか?

class hash_entry 
{ 
private: 
    int key; 
    int value; 
public: 
    hash_entry(int key, int value) 
    { 
     this->key = key; 
     this->value = value; 
    } 
    int getKey() 
    { 
     return key; 
    } 
    int getValue() 
    { 
     return value; 
    } 
}; 

class hash_map 
{ 
private: 
    hash_entry **table; 
    static const int TABLE_SIZE = 128; 
public: 
    hash_map() 
    { 
     table = new hash_entry*[TABLE_SIZE]; 
     for (int i = 0; i < TABLE_SIZE; i++) 
      table[i] = NULL; 
    } 
    int get(int key) 
    { 
     int hash = (key % TABLE_SIZE); 
     while (table[hash] != NULL && table[hash]->getKey() != key) 
      hash = (hash + 1) % TABLE_SIZE; 
     if (table[hash] == NULL) 
      return -1; 
     else 
      return table[hash]->getValue(); 
    } 
    void put(int key, int value) 
    { 
     int hash = (key % TABLE_SIZE); 
     while (table[hash] != NULL && table[hash]->getKey() != key) 
      hash = (hash + 1) % TABLE_SIZE; 
     if (table[hash] != NULL) 
      delete table[hash]; 
     table[hash] = new hash_entry(key, value); 
    } 
    ~hash_map() 
    { 
     for (int i = 0; i < TABLE_SIZE; i++) 
      if (table[i] != NULL) 
       delete table[i]; 
     delete[] table; 
    } 
}; 
+0

宣言することができました。あなたはどこでこれにつまずいたのですか? – Nate

+0

これは私が見つけることができる最も簡単なハッシュです。ちょうど値のセットを再配分するために%を使用します... algolist.net次のステップは、配列要素からリンクリストを追加することです。 – user1001776

+0

これはあなたがコントロールしていないコードであるかどうかはわかりませんでした。私は間違いなく、このトピックの@ JerryCoffinからの提案に従い、あなたが投稿したものを正確に使用しません。 – Nate

答えて

5

はい、**はポインタへのポインタを定義しています(仕様ではそうだと言います)。いいえ、私は誰も参照を呼んでいるとは想像できません。

hash_entry **table; 

[ ... ] 

hash_map() { 
    table = new hash_entry*[TABLE_SIZE]; 

は大体です:

彼らはこのような場合には、それを使用している理由として、彼らは動的にこのコードをXにポインタの配列を割り当てるために(非常にCのような)コードを書いています

std::vector<hash_entry *> table(TABLE_SIZE); 

(あなたはクラスのメンバーのために必要があると思いとして一瞬、私はそれを分割していないが):に相当

+0

そして 'vector'バージョンはもっと安全で使いやすいです! –

3

はい、**はポインタへのポインタですが、参照と同じではありません。ここでは、動的に割り当てられたhash_entryの2次元配列を作成するために使用されています。

ところで、このコードをコンパイルしてもよろしいですか?構文エラーと思われるものがいくつか見られます。

+0

私はそれが二次元配列であるとは思わない。 'hash_entry'へのポインタの配列です。 – Nate

+0

@ネイト:理由の1つは、Cスタイルの配列がそのようなPITAである理由の1つです。構文だけでは、どのようなものが使用されているかを正確に伝えることはできません。初期化と使用法を見なければなりません。 – Xeo

2

**は、ポインタへのポインタを指しています(これは参照ではありませんが、参照はアンパサンドで示されます)。たとえば、int & fooです。この場合、それはあなたが(「ハンドル」のように)説明してきた方法ではない使用されている

が、ポインタの配列としてhash_entry

にライン:

table = new hash_entry*[TABLE_SIZE]; 

手段「サイズTABLE_SIZE * sizeof(hash_entry*)の、hash_entryポインタを保持するためのメモリのブロックを割り当てる。そこから、配列は、必要に応じてあなたは、ポインタと配列内の各エントリを埋めることができた後、NULLに初期化されます。

0

はい、 **はポインタへのポインタを表します。

余分なレベルのインダイレクションを追加する理由の1つは、新しいアドレスを直接通知する必要があるコードを指すコードなしで物理メモリ内で最終的に指し示されているものを移動できるようにすることです。

メモリマネージャがメモリ内の何かを移動したい場合(ヒープの穴を減らすなど)、新しいメモリを割り当てたり、オブジェクトを移動したり、ポインタポインタがポイントするアドレスを指すように更新することができますその新しいアドレス。

は、具体的にあなたがTABLE_SIZEよりも多くのハッシュエントリを持っている場合は、この場合には、コードがメモリの大きなブロックでhash_entryを再割り当て可能性があり、hash_entryの新しいアドレスとtableを更新します。コードの残りの部分は、再割り当てには無知である可能性があります。

0

私は知っている*ポインタを定義しますか?**ポインタへのポインタを定義しますか?

はい。

なぜならば?

ここでは、誰かがそのタイプをどのように動作させるのかということを意味していると思います。私が見て使用した場所がいくつかあります:

  1. ポインタの動的配列。 (これはここにあります)
  2. ダイナミック2次元配列。引数(*arg = ptr_to_return)として渡されたポインタを介してポインタを「戻る」
  3. (これは実際には1のサブセット、別のダイナミックアレイの各要素点動的配列です)。例えば、 getline()

参照として知られているいくつかの倍のポインタへのポインタですか?次の非常に単純なハッシュの明確化が必要です。

いいえ、参照は本質的には参照渡しですが、コンパイラにはポインタが記録されます。

一般的には、内容全体を渡すにはコストがかかるので、大きな構造の場所を渡すためにポインタが使用されます。

はい、排他的ではありません。構造体のメンバを変更するメソッドを考えてみましょう。値渡しの場合はローカルコピーではなく、構造体のコピーを変更する必要があります。

ここでの例では、hash_entry **table;は、hash_entryへのポインタの(動的にサイズ変更された)配列として使用されています。それは、おそらくより明確に、これはアルゴリズムの悪魔であるhash_entry *table[];

+0

ありがとうございます...あなたの最後のメモは、hash_entry *テーブル[]は**テーブルと同等です私の主な混乱をクリア – user1001776

関連する問題