[英]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)
參數num
和size
是calloc
僅有的信息。
但是這個“如果聲明”是行不通的。
我認為“不起作用”是指“不編譯”。
因此,我嘗試使用0和NULL。 然后,我嘗試像這樣進行轉換:
if(ht->table[hashedKey] != (Employee *)0)
和
if(ht->table[hashedKey] != (Employee)0)
什么都沒用。
你的編譯器將發射解釋為何拒絕你的代碼的診斷消息。 這樣的診斷有時可能是含糊的,但是對於數據類型的抱怨肯定會使您問自己一個問題:“這里涉及什么類型?”。 不過,我們可以提供幫助:
ht->table[hashedKey]
類型為Employee
(一種結構,而不是一個指針)。 對於您的目的,這可能是最重要的一個,但讓我們繼續...。
0
是int
類型的常量,它也用作空指針常量(盡管其類型)。
(Employee *) 0
是Employee *
類型的空指針。
(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.