You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用klib的khash库:KHASH_SET_INIT_INT64能否支持负数键?

问题与解答

代码示例

#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),发现头文件中KHASH_SET_INIT_INT64使用的是unsigned long int(uint64_t),请问是否可以将负数作为键?使用负数键是否会引发问题?我是C语言新手,抱歉提出这类问题。


解答

1. 能否用负数作为键?

语法上可以编译通过,但本质是C语言的隐式类型转换在起作用:当你把int64_t类型的负数传入为uint64_t设计的哈希集合时,负数会被转换成对应的无符号64位整数(比如-1会变成0xFFFFFFFFFFFFFFFF)。

由于补码系统中int64_t和uint64_t的内存表示是一一对应的,每个负数都会对应唯一的无符号值,不会和正数的键冲突,所以实际运行时可以正常存储和匹配负数键。

2. 可能引发的问题

  • 语义混淆:哈希表实际存储的是无符号值,调试时如果查看哈希表内部数据,会看到负数对应的无符号形式,容易造成理解上的混乱。
  • 逻辑风险:如果后续代码中不小心将uint64_t类型的正数与int64_t负数混用,可能出现意外的匹配(比如某个正数刚好等于负数转换后的无符号值),不过这种情况只要业务逻辑清晰就可以避免。

3. 更合适的解决方案

如果你明确需要存储int64_t类型(包含负数),建议直接使用针对有符号64位整数的哈希集合定义,避免类型转换的问题:
将原代码中的KHASH_SET_INIT_INT64(bin_value);替换为:

KHASH_SET_INIT2(bin_value, int64_t, kh_int64_hash, kh_int64_equal);

这个宏直接指定键类型为int64_t,并使用对应的哈希函数和比较函数,负数处理完全符合预期,不需要担心类型转换带来的问题。


内容的提问来源于stack exchange,提问作者Frozen_Blood

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:57:46