qq_42010270 2022-03-06 01:09 采纳率: 100%
浏览 12
已结题

C语言hash表初始化和值修改为什么形参中使用一级指针接就可以了

如下hash表增删改查代码,为什么hash表的初始化InitHashTable函数和修改值modify直接传递他们的地址可以,不应该是 传递指针的地址也就是二级指针才能修改吗。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_TABLE_SIZE 100

/*hash 节点*/
typedef struct HashNode
{
    char *key;
    int value;
    struct HashNode *next;
}HashNode;

/*hash 整个表,有一个数组存放了每个由节点自称的链表的位置*/
typedef struct HashTable
{
    HashNode *hashNode[MAX_TABLE_SIZE];
    int currentIndex;
}HashTable;

/*初始化整个表*/
void InitHashTable(HashTable *hashTable)
{
    memset(hashTable->hashNode, 0, MAX_TABLE_SIZE * sizeof(HashNode *));
    hashTable->currentIndex = 0;
}

/*一个规则:key转换成一个long型数据,用于确定存放在表中的那个位置*/
unsigned long HashFun(const char *key)
{
    unsigned long hash = 0;
    int len = strlen(key);
    int i;
    for (i = 0; i < len; i++)
    {
        hash = hash * 33 + key[i];
    }

    return hash;
}

/*插入一个新的key:value数据*/
void Insert(HashTable *hashTable, char *key, int value)
{
    int pos = HashFun(key) % MAX_TABLE_SIZE;//通过计算的key转化的值与表的大小取余,来确定存储的位置
    /*下面是创建个新节点,把key和value都存在这个节点中*/
    HashNode *newNode = (HashNode *)malloc(sizeof(HashNode));
    newNode->next = NULL;
    newNode->key = (char *)malloc((strlen(key) + 1) * sizeof(char));
    strcpy(newNode->key, key);
    newNode->key[strlen(key)] = '\0';
    newNode->value = value;
    /*把新结点插入到表中去*/
    HashNode *p = hashTable->hashNode[pos];
    if (p == NULL)//
    {
        hashTable->hashNode[pos] = newNode;
        hashTable->currentIndex++;
        return ;
    }
    /*key的值已成存在,就覆盖写入value*/
    if (strcmp(p->key, key) == 0)
    {
        p->value = value;
        return;
    }

    /*通过下面,把节点查到第二个节点的位置(头插法),这里对节点的顺序没有要求*/
    newNode->next = p->next;
    p->next = newNode;

    return ;
}

 /*打印表中的信息*/
void PrintHashTable(HashTable *hashTable)
{
    int i;
    for (i = 0; i < MAX_TABLE_SIZE; i++)
    {
        HashNode *head = hashTable->hashNode[i];
        if (head == NULL)
        {
            continue;
        }
        printf("\n数组下标:%d ==>", i);
        printf("(%s:%d)", head->key, head->value);
        head = head->next;
        while (head)
        {
            printf("-->(%s:%d)", head->key, head->value);
            head = head->next;
        } 
    }
    printf("\n");
    return;
}

void clearHashTable(HashTable *hashTable)
{
    int i;
    for (i = 0; i < MAX_TABLE_SIZE; i++)
    {
        HashNode *head = hashTable->hashNode[i];
        while (head)
        {
            HashNode *temp = head->next;
            free(head->key);
            head->key = NULL;
            free(head);
            head = NULL;
            head = temp;
        }
    }
    return;
}

int modify(HashTable *hashTable, char *key, int value)
{
    int pos = HashFun(key) % MAX_TABLE_SIZE;
    HashNode *head = hashTable->hashNode[pos];
    if (head == NULL)
    {
        return 1;
    }
    else
    {
        HashNode *q = head;
        while (q)
        {
            if (strcmp(q->key, key) == 0)
            {
                q->value = value;
                return 0;
            }   
        }
        return 1;
    }
}

int main(int argc, char const *argv[])
{
    HashTable *hashTable = (HashTable *)malloc(sizeof(HashTable));
    InitHashTable(hashTable);
    Insert(hashTable, "tgb", 5);
    Insert(hashTable, "yhn", 6);
    Insert(hashTable, "ujm", 7);
    PrintHashTable(hashTable);
    modify(hashTable, "c", 8080);//为何 传递一级指针也可以修改
    // modify(&hashTable, "c", 8080);//
    PrintHashTable(hashTable);

    clearHashTable(hashTable);
    free(hashTable);
    return 0;
}


  • 写回答

1条回答 默认 最新

  • orange4reg 2022-03-06 09:30
    关注

    修改的是hashTable里面的东西,这种已经是二级指针了。只有当修改的是函数外面的变量的时候才需要用指针来修改。其实这些函数都可以不用指针,但为什么又使用了指针,因为这个表本身就是指针形式开始的,就像字符串,是char指针开始的。因此这种只是只能算是一种类型。但如果需要修改函数外面的变量hashTable的值,那才需要使用指针的指针,你要把第一个指针看作一种类型,第二个才是修改需要的。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 3月14日
  • 已采纳回答 3月6日
  • 创建了问题 3月6日

悬赏问题

  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏
  • ¥15 STM32串口接收问题
  • ¥15 腾讯IOA系统怎么在文件夹里修改办公网络的连接
  • ¥15 filenotfounderror:文件是存在的,权限也给了,但还一直报错
  • ¥15 MATLAB和mosek的求解问题
  • ¥20 修改中兴光猫sn的时候提示失败
  • ¥15 java大作业爬取网页
  • ¥15 怎么获取欧易的btc永续合约和交割合约的5m级的历史数据用来回测套利策略?
  • ¥15 有没有办法利用libusb读取usb设备数据