**在这个简单的哈希实现中做了什么?

What is ** doing in this simple hash implemtation?

本文关键字:什么 实现 哈希 简单      更新时间:2023-10-16

我知道*定义了一个指针…**定义指针指向指针吗?

如果是,为什么?

指向指针的指针有时被称为引用吗?只是需要澄清一下下面这个非常简单的散列。

一般情况下,指针用于传递较大结构体的位置,因为传递整个结构体的内容开销太大。

我见过在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;
    }
};

是的,**定义了指向指针的指针(因为规范这么说)。不,我无法想象有人会把它叫做参考。

至于为什么在这种情况下使用它,他们正在编写(非常像c)代码来动态分配指向x的指针数组。

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

是否大致相当于

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

是的,**是指向指针的指针,但不,这与引用不一样。在这个上下文中,它被用来创建一个动态分配的二维数组hash_entry

顺便问一下,你确定这段代码可以编译吗?我看到一些东西似乎是语法错误。

你是正确的,**是指针指向指针的指针(尽管这是一个引用是不正确的-引用用&符号表示-例如int & foo)。

在这种情况下,它不是以您描述的方式(作为"句柄")使用的,而是作为指向hash_entry s的指针数组

:

table = new hash_entry*[TABLE_SIZE];

表示"分配一个hash_entry指针的内存块,大小为TABLE_SIZE * sizeof(hash_entry*)"。从这里开始,数组初始化为NULL,之后可以根据需要用指针填充数组中的每个条目。

是的,**代表指向指针的指针。

添加额外的间接层的一个原因是,这样你就可以移动物理内存中最终指向的东西,而不需要直接通知指向something的代码的新地址。

如果内存管理器想要移动内存中的某个对象(例如,为了减少堆中的漏洞),它可以分配新的内存,移动对象,并更新指针指向的地址,使其指向新地址。

特别是在这种情况下,如果你有比TABLE_SIZE更多的哈希条目,代码可以用更大的内存块重新分配hash_entry,并用hash_entry的新地址更新table。其余的代码可以忽略重新分配

我知道*定义了一个指针…**定义指向指针的指针吗?

是的。

如果是,为什么?

我假设你在这里的意思是为什么有人会使用一个,而不是类型是如何工作的(请参阅任何c参考资料)。我在一些地方见过并使用过它们:

    指针的动态数组。(这就是我们这里的内容)
  1. 动态二维数组。(这实际上是1的一个子集,一个动态数组,其中每个元素指向另一个动态数组)
  2. 通过作为arg (*arg = ptr_to_return)传递的指针"返回"指针。参见,例如getline()

指向指针的指针有时被称为引用吗?只是需要澄清一下下面这个非常简单的散列。

不,引用本质上是通过引用传递,但让编译器为你跟踪指针。

一般情况下,指针用于传递较大结构体的位置,因为传递整个结构体的内容开销太大。

是的,但不是唯一的。考虑一个改变结构体成员的方法。你需要它来改变你的结构体副本,而不是如果你按值传递的话,它将拥有的本地副本。

在这里的示例中,hash_entry **table;被用作指向hash_entry s的指针数组(动态大小)。它可以更清楚地声明为hash_entry *table[];