#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "klib/khash.h"
KHASH_SET_INIT_INT64(bin_value);
int counter = 1;
int main() {
khash_t(bin_value) *bin_value_pointer = kh_init(bin_value);
FILE *file = fopen("read.txt", "r");
char line[20];
while (fgets(line, sizeof(line), file)) {
int64_t value;
int ret;
if (sscanf(line, "%ld", &value) == 1) {
kh_put(bin_value, bin_value_pointer, value, &ret);
}
}
fclose(file);
FILE *file1 = fopen("check.txt", "r");
while (fgets(line, sizeof(line), file1)) {
int64_t input;
int ret;
if (sscanf(line, "%ld", &input) == 1) {
if (kh_get(bin_value, bin_value_pointer, input) != kh_end(bin_value_pointer)) {
printf("matched counter= %d\n", counter++);
}
}
}
kh_destroy(bin_value, bin_value_pointer);
fclose(file1);
return 0;
}
我正在尝试使用 khash 实现 hashSet 我可以使用负值作为键,因为我在头文件中看到它使用 unsigned long int (uint64_t).. 而且如果我使用负值作为键它会导致任何问题.. 抱歉问这些类型的问题,但我是 C 新手。
我在头文件中看到它使用 unsigned long int
您可能使用的是旧版本:
#if ULONG_MAX == ULLONG_MAX
typedef unsigned long khint64_t;
#else
typedef unsigned long long khint64_t;
#endif
在现代版本中
khint64_t
定义为:
typedef uint64_t khint64_t;
如果我使用负值作为键,它会导致任何问题
您的代码是安全的,因为从
signed
到 unsigned
类型的转换具有明确定义的行为,但从标准来看,相反的情况则不然:
C11 6.3.1.3
6.3.1.3 有符号和无符号整数
当一个整数类型的值转换为另一种整数类型时 除_Bool外,如果该值可以用新类型表示,则 没有变化。
否则,如果新类型是无符号的,则该值将通过以下方式转换 反复加或减 1 比最大值 可以用新类型表示,直到该值在以下范围内 新类型。
否则,新类型是有符号的,并且该值不能被 其中所代表的;结果要么是实现定义的,要么是 引发实现定义的信号。
结果:
int64_t input;
...
if (kh_get(bin_value, bin_value_pointer, input)
正确,不正确的是:
int64_t ouput = kh_key(bin_value, bin_value_pointer);