c语言可以存放任何类型容器,极简主义者的C语言容器库

极简主义

“The more code you have in a project, the more you have to worry about.”

“More code, more problems!”

越多的代码意味着你需要担忧的也越多。你的代码将会更难理解。除此之外,你还要更多地考虑优化、重构、文档、调试等等。

“We also try to minimize the use of external libraries.”

尽量减少使用外部库。理由如下:

1. 你没法对外部库的表现做出任何保证,如软件大小、性能、编译时间、平台支持等。只有当开发者的目标非常明确,且正好与外部库的目标完全吻合时,才能避免陷入各种问题(罕见情况)。如果你不只是想让你的软件“仅仅能工作”,那么请慎重使用外部库。

2. 外部库会为你的项目引入大量代码(源码或二进制形式)。而更多的代码,意味着你更难弄明白这些代码究竟在做什么。控制代码量的最终目的是使代码易于修改。显然,外部库的代码是很难修改的。

我们也不能因噎废食。原作者鼓励使用single-file source libraries。因为这些文件都是简洁的,且有很明确的目的。不推荐使用类似boost这样的“怀有巨大野心”的big sprawling libraries.

容器类型

容器通常指如队列、列表、栈、数组等用来容纳和索引对象的数据结构。它们通常也被称为Abstract data type(ADT),即抽象数据类型。

容器类型作为项目的基石会给剩余的代码带来巨大的影响,如算法的选择。改变容器类型通常需要重写大部分代码,对于大型项目来说就是一场灾难。因此,我们有必要仔细思考如何选择容器类型。

在原作者以前的项目中,存在着大量的特化容器类型。它们通常只出现一到两次,而且大多情况并没有带来多少益处,完全可以使用更通用的容器来替代来减少代码量。

因此,依极简主义精神,他们只定义了两种容器类型:

Arrays( or "stretchy buffers")

Hash tables

No lists, no trees, no strings, no queues, no sets, etc

使用Arrays数组进行通用数据存储,Hash Table哈希表实现快速查找。使用这两种基础类型,我们可以处理平常我们使用的如string,lis等类型。

Array("stretchy buffers")

由于C不支持模板方法,所以我们必须借助宏。

基本思想是使用普通的C指针来表示数组。

my_type_t* a = NULL;

与C原生数组不同的是,我们在数组头指针前存储额外的信息来记录数组的大小和容量。

56e79fc438bd

Memory layout of a stretchy buffer

struct array_header_t

{

uint32_t size;

uint32_t capacity;

};

利用内存偏移,我们可以容易得到这个结构体:

#define array_header(a) \

((array_header_t *)((char *)(a) - sizeof(array_header_t)))

缺点:许多函数需要宏实现,不易于debug。无法区别普通指针和stretchy buffer指针。

Hashes

STL的hash表实现为std::unordered_map。在C中我们可以借用上面实现的strechy buffer:

key_t *keys;

value_t *values;

但这样会遇到一些问题。如果key类型本身是变长的,如字符串,那么会涉及到大量的内存分配和指针跟踪。为解决这个问题,我们可以事先将key做一次哈希:hash(key)->k,然后用k值做索引。同样的,value值也不一定要存在hash表中,我们可以用stretchy buffer来存储,再将数组索引放到hash表中作为值即可。

使用这种方案,我们就不再需要处理通用类型的问题了。哈希表即可定义为:

struct hash_t

{

uint32_t num_buckets; //没弄明白其作用,有可能是指key buffer的容量

uint64_t *keys;

uint64_t *values;

};

注意:我们仍需要考虑hash函数的碰撞问题。如果要根据值得到键值,则还要再建一张索引表。

更多内容请阅读原文和原作者的其他博文。

由于涉及太底层的东西,我暂时就没有深入学习了。对Engine programming感兴趣的同学一定不要错过。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值