簡體   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