我正在使用klib库我可以使用(khash)KHASH_SET_INIT_INT64()负值作为键。因为我在头文件中看到它使用 unsigned long int

问题描述 投票:0回答:1
#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 新手。

c hashset
1个回答
0
投票

我在头文件中看到它使用 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);
© www.soinside.com 2019 - 2024. All rights reserved.