为什么C标准库中没有哈希表?

Sha*_*aju 50 c hashtable

为什么标准C库中没有Hashtable支持?这有什么具体原因吗?

Die*_*Epp 47

按今天的标准来看,C似乎并不常见,因为没有定义有用的数据结构.没有.甚至不是字符串 - 如果你认为C字符串是一个数据结构,那么我们就不得不对"数据结构"的含义持不同意见.

如果您喜欢C,那么将其视为"空白板块"...您的整个应用程序由您编写的代码和您选择引入的库组成,还有一些相当原始的标准库函数,可能有一两个例外情况qsort.人们现在使用C来实现Python,Ruby,Apache或Linux内核之类的东西.这些项目无论如何都使用了他们自己的所有数据结构,他们不太可能使用类似STL的东西.

许多C库实现了通用哈希表.有权衡,你可以选择自己喜欢的.其中一些可以使用回调进行配置.

  • Glib有一个哈希表对象(文档)
  • Apache Portable Runtime有一个哈希表(文档)
  • Apple的Core Foundation库有一个哈希表(文档)注意:是的,您可以插入任何对象作为键或值.
  • UTHash是一个哈希表库(文档)
  • 另一个哈希表库(链接)

如果所有这些库都能满足您的需求,那么将哈希表添加到C标准中有什么意义呢?

  • 嗯,不确定我同意"C字符串不是数据结构"位(虽然不足以进行downvote) - 它们具有定义的结构和操作它们的功能.除了复杂性,我不确定与BTree或HashTable有什么不同.无论如何,我们也有`FILE*`:-) (4认同)

pax*_*blo 39

标准C库中没有哈希表,因为:

  • 没有人向工作组提交提案; 要么
  • 工作组认为没有必要.

这就是ISO的工作方式.提案被提出并被接受或拒绝.

您必须小心添加到标准库的内容,因为您有两个冲突的组.作为用户,您可能希望将太阳下的每个数据结构添加到标准中,以使该语言更有用.

但是,作为一个语言实现者(顺便说一下,这些可能是那些倾向于组成大多数工作组的人,因此他们的观点可能会产生更大的影响),你真的不想要必须实施的麻烦每个人都不会使用的东西.C89出现时所有的东西都与这样一个事实有关,即主要目的是编纂现有的做法,而不是引入新的做法.从那以后,标准的所有迭代都可以做得更自由,但向后兼容性仍然是一个重要问题.

我自己,我也有冲突.我很乐意在C语言中拥有Java,C++或Python库的所有功能.当然,这会让新手学习一切变得更加困难,而且正如一位评论者所说,可能会让它变得如此代码猴可以抽出有用的代码,减少我在这个过程中的价值:-)

而且我几乎拥有需要的所有数据结构,从我的长期和(大部分)辉煌的职业生涯中.你不仅限于这种东西的标准库.有很多第三方工具可以完成这项工作,(像我一样)你也可以自己动手.

如果您想知道为什么在每次迭代中做出某些决定,ISO(最初是ANSI,在ISO接管之前)通常会发布基本原理文档.可以在这里找到ANSI的C89 .它包含范围内的这个小美:

本基本原理主要侧重于基础文档中所述的语言的添加,说明和更改.这不是C语言整体的理由:委员会负责编纂现有语言,而不是设计新语言.在此基本原理中没有尝试保护语言的预先存在的语法,例如声明的语法或运算符的绑定.

我特别欣慰地承认,他们对任何可能早于标准化的邪恶混乱都不负责任.

但是,也许你的问题的真正答案在于这一点,指导原则之一:


保持C的精神.委员会将保持C的传统精神作为一个主要目标.C的精神有许多方面,但其实质是C语言所依据的基本原则的社区情感.C精神的一些方面可以概括为以下短语:

  • 相信程序员.
  • 不要阻止程序员做需要做的事情.
  • 保持语言小而简单.
  • 只提供一种方法来进行操作.
  • 即使不保证便携,也要快速.

第三个可能是图书馆没有通过最初的标准化努​​力大规模扩展的主要原因 - 而且,委员会的这种扩展可能导致ANSI C被标记为C2038而不是C89.

  • "保持语言小而简单.只提供一种方法来进行操作." 你还在谈论这个C吗?int或者signed或signed int,if-else或?:,if-else或switch,类似函数的宏或函数,continue或break或goto或return;,const int或int const,typedef struct or struct,enum或const或#define,malloc或calloc,NULL或0或'\ 0',*(ptr + n)或ptr [n].等等,这只是我整天可以进行的冰山一角,真的. (26认同)
  • 此外,该委员会确实做出了令人钦佩的努力,使语言变得不必要复杂.你最后一次使用以下标题是什么时候:complex.h,errno.h,fenv.h,float.h,inttypes.h,iso646.h,locale.h,signal.h,wctype.h.对我来说,包含哈希表的头文件似乎比这些有用大约一百倍. (12认同)
  • @Lundin:请参见包含“负责编纂一种现有语言,而不是设计一种新语言”的部分。大多数东西已经在ANSI之前出现了。在这些头文件中,我经常使用`errno`,`locale`和`signal`-我不认为我曾经使用过其他任何头文件,但是,我并不是唯一的C编码器planet :-)后来出现了诸如complex,fenv,inttypes,iso646和wctype之类的东西,因此与C89基本原理无关。您将必须查看特定迭代的原理。 (2认同)
  • 因此,如果C90委员会负责编纂现有语言,那么人们可能会想知道C99委员会的指控是什么."尽可能多地提出无意义的新功能,同时避免任何显着的语言改进",或者沿着这些方向做些什么.显然,他们每年仍会举行几次会议,谈到过去的美好时光. (2认同)
  • 尝试编写软件来设计或模拟电子元件,但没有良好的复杂算术库 (2认同)

caf*_*caf 11

标准C库不包含任何大型,持久的数据结构 - 既不是列表,也不是树,也不是堆栈,也不包括哈希表.

如果不向原始C库的作者询问,就不可能给出确定的答案.然而,一个可能的解释是这样的数据结构的实施涉及各种权衡,只有应用程序的作者是在正确的位置,以使这些权衡.

请注意,POSIX标准C库确实指定了通用哈希表函数:hcreate(),hsearch()hdestroy(); 并注意到它们的"一刀切"性质往往使它们不适合大多数现实世界的用例,支持上述论点.

  • 请参阅没有此限制的`hcreate_r`(但是非POSIX扩展名). (4认同)
  • 嗯,看起来像POSIX哈希表只允许你一次创建一个哈希表.这听起来非常有用. (3认同)
  • POSIX哈希表函数在实际代码中几乎没用. (3认同)