繁体   English   中英

与结构一起使用时,calloc的初始值

[英]Initial value of calloc, when using with a struct

我试图通过使用以下代码编写一个非常简单的哈希表:

#include <stdio.h>
#include <string.h>
#define SIZE 10

typedef struct {
    char *first_name;
    char *last_name;
} Employee;

typedef struct {
    Employee *table;
} Hashtable;

void initHashtable(Hashtable *ht) {
    ht->table = (Employee *)calloc(SIZE, sizeof(Employee));
}

int hashKey(char *key) {
    int length = strlen(key);
    return length % SIZE;
}

void put(Hashtable *ht, Employee emp, char *key) {
    int hashedKey = hashKey(key);
    ht->table[hashedKey] = emp;
}

我可以通过以下方式插入元素:

int main(int argc, char const *argv[]) {

    Employee e1;
    e1.first_name = "John";
    e1.last_name = "Doe";

    Hashtable ht;

    initHashtable(&ht);
    put(&ht, e1, "Doe");

    return 0;
}

但是我想修改“ put”函数,因此当我尝试插入某些内容时,它将检查该索引是否为空。 如果为空,则返回一些消息,如果不是,则在该索引上插入。 如同:

void put(Hashtable *ht, Employee emp, char *key) {
    int hashedKey = hashKey(key);

    if (ht->table[hashedKey] != 0) {
        printf("Employee is in that index!\n");
    } else {
        ht->table[hashedKey] = emp;
    }
}

但是这个“如果声明”是行不通的。 因此,我尝试使用0和NULL。 然后,我尝试像这样进行转换:

if(ht->table[hashedKey] != (Employee *)0)

if(ht->table[hashedKey] != (Employee)0)

什么都没用。 我的问题是我知道calloc初始化为0,零。 那么在struct的情况下,calloc用什么初始化?

我的问题是我知道calloc初始化为0,零。 那么在struct的情况下,calloc用什么初始化?

calloc完全不知道如何使用内存。 它只是在所有位都设置为零的情况下为您提供所需的数量。 查看它的原型:

void * calloc(size_t num, size_t size)

参数numsizecalloc 仅有的信息。

但是这个“如果声明”是行不通的。

我认为“不起作用”是指“不编译”。

因此,我尝试使用0和NULL。 然后,我尝试像这样进行转换:

 if(ht->table[hashedKey] != (Employee *)0) 

 if(ht->table[hashedKey] != (Employee)0) 

什么都没用。

你的编译器将发射解释为何拒绝你的代码的诊断消息。 这样的诊断有时可能是含糊的,但是对于数据类型的抱怨肯定会使您问自己一个问题:“这里涉及什么类型?”。 不过,我们可以提供帮助:

  • ht->table[hashedKey]类型为Employee (一种结构,而不是一个指针)。 对于您的目的,这可能是最重要的一个,但让我们继续...。

  • 0int类型的常量,它也用作空指针常量(尽管其类型)。

  • (Employee *) 0Employee *类型的空指针。

  • (Employee) 0是无效表达式。 它没有类型,因为将int转换为诸如Employee的结构类型是无效的。

诸如Employee类的结构类型不是!=运算符(或==运算符或大多数其他运算符)的有效操作数。 这是您的主要问题。 即使您生成了一个全为零的Employee表示形式(可以通过多种方式完成),您仍然无法通过C的任何运算符直接将其与ht->table[hashedKey]进行ht->table[hashedKey] )比较。 但是,即使结构可比较的,将结构与任何类型的指针进行比较也是没有意义的,如您的第一个示例所尝试的。

我的问题是我知道calloc初始化为0,零。 那么在struct的情况下,calloc用什么初始化?

这似乎与您的问题无关,但自从您提出要求以来, calloc其分配给所有位的空间初始化为零。 对于整数类型(包括结构的成员),这是0的表示形式。对于其他类型,包括指针类型,该语言未指定此表示形式所表示的含义。

要检查两个结构是否相等,您需要逐个成员比较它们。 但是,在您的特定情况下,您实际上不需要比较结构,只需要检查一个结构的成员即可。 但是,由于全为零的指针值不一定是空指针,而且可能也没有指向任何东西,因此将通过calloc分配的指针值与任何东西进行比较都是不安全的。 在这种情况下,并且您的Employee结构没有任何非指针成员, calloc的内存初始化不会为您带来任何帮助。

相反,您应该手动初始化每个哈希表元素:

void initHashtable(Hashtable *ht) {
    ht->table = malloc(SIZE, sizeof(Employee));
    for (int i = 0; i < SIZE; i++) {
        ht->table[i].first_name = NULL;
        ht->table[i].last_name = NULL;
    }
}

完成此操作后,您可以通过检查成员来检查表中是否已分配给定插槽:

if (ht->table[hashedKey].first_name != NULL || ht->table[hashedKey].last_name != NULL) // ...

因为在布尔上下文中空指针的计算结果为false,而非空指针(甚至无效的指针)的计算结果为true,所以可以将其缩写为

if (ht->table[hashedKey].first_name || ht->table[hashedKey].last_name) // ...

... 如果你更喜欢。 两种版本都告诉您已经分配了表格元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM