【发布时间】:2022-06-14 06:47:14
【问题描述】:
我有一个头文件和 C 文件放在同一个目录中......头文件显然只是声明了一些东西,而 C 文件定义了它们。据我了解,这是正确的方法。链接器似乎看不到它。 (我目前正在试验线性探测,所以我知道代码在发生碰撞时可能无法工作,但它是有效代码,因此应该编译。)
这是标题:
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct Header {
/* key will always be present */
char* key;
/* value can be blank / null */
char* value;
/* RFC conforming; index of the header so we can use a hashmap */
int index;
};
struct HashTable {
struct Header** headerArr;
uint16_t size;
/* this will start at the size of the static table then be used to fill the index field of the Header struct before being placed within the array */
int currentDynamicIndex;
};
/* init the hash table to a given size */
uint8_t initHashTable(struct HashTable* hashTable);
/* maps a struct to a value within the hashmap */
uint32_t hash(struct HashTable* hashTable, struct Header* header);
/* add a header pair to the hash table */
uint8_t add(struct HashTable* hashTable, struct Header* header);
/* find index given a value */
int lookup(struct HashTable* hashTable, struct Header* header);
/* delete an element from the hashmap */
uint8_t delete(struct HashTable* hashTable, struct Header* header);
C 文件包含头文件,然后开始定义函数:
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "hash.h"
uint32_t hash(struct HashTable* hashTable, struct Header* header) {
/* loop over both values in the header struct and add their ascii values to get a different number each time */
uint32_t finalNumb = 0;
size_t strLen = strlen(header->key);
for (size_t x = 0; x < strLen; ++x) {
finalNumb += (int)header->key;
finalNumb = (finalNumb * (int)header->value) % hashTable->size;
}
/* if the header value struct is not empty, add it too */
if (header->value != NULL) {
strLen = strlen(header->value);
for (size_t x = 0; x < strLen; ++x) {
finalNumb += (int)header->value;
finalNumb = (finalNumb * (int)header->value) % hashTable->size;
}
}
return finalNumb;
}
uint8_t initHashTable(struct HashTable* hashTable) {
/* this needs to be set to the size of the static table + 1 (since the 0th index is not a thing in the RFC) */
hashTable->currentDynamicIndex = 62;
hashTable->headerArr = calloc(hashTable->size, sizeof(struct Header));
if (hashTable->headerArr == NULL) {
/* calloc error */
return 0;
}
return 1;
}
uint8_t add(struct HashTable* hashTable, struct Header* header) {
uint32_t index = hash(hashTable, header);
/* check if the index is occupied first */
if (hashTable->headerArr[index] != NULL) {
/* its occupied so use linear probing which is just +1 */
uint32_t newIndex = index += 1;
while (hashTable->headerArr[newIndex] != NULL) {
newIndex += 1;
if (hashTable->size <= newIndex) {
newIndex = 0;
}
}
return hashTable->headerArr[newIndex];
}
hashTable->headerArr[index] = header;
}
int lookup(struct HashTable* hashTable, struct Header* header) {
/* the structs that are provided wont have an index field that isnt NULL but the ones in the array will */
uint32_t index = hash(hashTable, header);
if (hashTable->headerArr[index] != NULL && strcmp(header->key, hashTable->headerArr[index]->key) == 0 && strcmp(header->value, hashTable->headerArr[index]->value) == 0) {
return hashTable->headerArr[index]->index;
}
return -1;
}
uint8_t delete(struct HashTable* hashTable, struct Header* header) {
uint32_t index = hash(hashTable, header);
/* check if the index is occupied first */
if (hashTable->headerArr[index] != NULL) {
hashTable->headerArr[index] = NULL;
return 1;
}
return 0;
}
int main(int argc, char* argv[]) {
printf("ok\n");
return 1;
}
这可能是什么原因?之前所有与此相关的堆栈溢出答案似乎都是因为结构位于函数声明之后。
hash.c:96:19: warning: 'struct HashTable' declared inside parameter list will not be visible outside of this definition or declaration
int lookup(struct HashTable* hashTable, struct Header* header) {
hash.c: At top level:
hash.c:96:48: warning: 'struct Header' declared inside parameter list will not be visible outside of this definition or declaration
int lookup(struct HashTable* hashTable, struct Header* header) {
-H 的输出
... C:/Strawberry/c/lib/gcc/x86_64-w64-mingw32/8.3.0/include/stddef.h
.... C:/Strawberry/c/x86_64-w64-mingw32/include/stddef.h
. C:/Strawberry/c/x86_64-w64-mingw32/include/string.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/sec_api/string_s.h
... C:/Strawberry/c/x86_64-w64-mingw32/include/string.h
. C:/Strawberry/c/x86_64-w64-mingw32/include/stdio.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_print_push.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_off_t.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/swprintf.inl
.. C:/Strawberry/c/x86_64-w64-mingw32/include/sec_api/stdio_s.h
... C:/Strawberry/c/x86_64-w64-mingw32/include/stdio.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_print_pop.h
. hash.h
重命名文件似乎确实有效。我现在只收到一些演员表错误。 @Jonathan Leffler 建议的解决方案。不确定在 c 标准库中哪个文件会被命名为 hash.h/.c,因为没有实现这样的数据结构
【问题讨论】:
-
如何调用链接器?
-
gcc -c hash.c 和 hash.c 是 c 文件的名称 & hash.h 是 .h 文件的名称
-
gcc -c是编译器调用。你怎么称呼链接器? -
不确定你的意思,gcc -c 是我所能得到的,在它给我这些警告/错误之前
-
查看更新的问题
标签: c