Collections-C 是 C 语言的通用数据结构库。
以void*
形式存储数据的结构。
容器 | 描述 |
---|---|
CC_Array | 随着元素添加而自动扩展的动态数组。 |
CC_List | 双向链表。 |
CC_SList | 单链表。 |
CC_Deque | 动态数组,支持两端分摊常数时间插入和删除以及常数时间访问。 |
CC_HashTable | 无序键值映射。支持最佳情况摊销常数时间插入、删除和查找值。 |
CC_TreeTable | 有序的键值映射。支持对数时间插入、删除和查找值。 |
CC_HashSet | 无序集合。查找、删除和插入在摊余常数时间内执行,在最坏的情况下以摊余线性时间执行。 |
CC_TreeSet | 有序集。查找、删除和插入都是以对数时间执行的。 |
CC_Queue | FIFO(先进先出)结构。支持常数时间插入、删除和查找。 |
CC_Stack | LIFO(后进先出)结构。支持常数时间插入、删除和查找。 |
CC_PQueue | 优先级队列。 |
CC_RingBuffer | 环形缓冲区。 |
CC_TSTTable | 三元搜索树表。支持插入、查找、迭代、删除。 |
int value = 20 ;
CC_Array * array ;
if ( cc_array_new ( & array ) != CC_OK ) { /*Create a new array.*/
// handle error
}
if ( cc_array_add ( & array , ( void * ) & value ) != CC_OK ) { /* Add the pointer to the value to the array */
// handle error
}
直接存储任意长度数据的结构。
容器 | 描述 |
---|---|
CC_ArraySized | 随着元素添加而自动扩展的动态数组。 |
int value = 20 ;
CC_SizedArray * array ;
if ( cc_sized_array_new ( sizeof ( int ), & array ) != CC_OK ) { /* Create a new array that stores values the size of an int*/
// handle error
}
if ( cc_sized_array_add ( & array , & value ) != CC_OK ) { /* Copy the value into the array */
// handle error
}
内存池是预先分配的连续内存块
容器 | 描述 |
---|---|
CC_DynamicPool | 在堆上,潜在可扩展的内存池 |
CC_StaticPool | 固定池 |
/* CC_StaticPool can enable the use of the structures on the stack */
#include "memory/cc_static_pool.h"
#include "cc_list.h"
CC_StaticPool * pool ;
// Alloc wrappers
void * pool_malloc ( size_t size ) { cc_static_pool_malloc ( size , pool );}
void * pool_calloc ( size_t count , size_t size ) { cc_static_pool_calloc ( count , size , pool );}
void pool_free ( void * ptr ) { cc_static_pool_free ( ptr , pool );}
int main ( int argc , char * * argv ) {
uint8_t buffer [ 2000 ]; /* Large enough buffer. */
cc_static_pool_new ( sizeof ( buffer ), 0 , buffer , buffer , & pool ); /* allocate the pool structure inside the buffer */
CC_ListConf conf ; /* Create a new list config */
cc_list_conf_init ( & conf );
conf . mem_alloc = pool_malloc ; /* Set list memory allocators to pool allocators */
conf . mem_calloc = pool_calloc ;
conf . mem_free = pool_free ;
CC_List * list ;
cc_list_new_conf ( & conf , & list ); /* The newly created list will be allocated inside the "buffer" array*/
// Use the list
return 0 ;
}
这些软件包通常可以通过您的发行版软件包管理器安装。
要构建项目,我们首先需要创建一个单独的构建目录(如果它尚不存在):
mkdir build
从这个目录中,我们可以运行cmake
命令并配置构建:
cmake ..
或cmake -DSHARED=True
使 Collections-C 构建为共享库cmake -DSHARED=False
构建静态库一旦cmake
生成了 makefile,我们就可以通过在构建目录中运行make
来构建库。
克隆和构建静态库的示例:
git clone https://github.com/Collections-C.git
cd Collections-C
mkdir build
cd build
cmake -DSHARED=False
make
运行测试(从build
目录):
make test
要运行单独的测试,只需运行适当的可执行文件即可。例如:
build/test/array_test
要安装库,请运行:
sudo make install
默认情况下,库和头文件将安装在/usr/local/lib/
和/usr/local/include
目录中。
您必须使系统的运行时知道新库的位置才能运行动态链接的应用程序。如果/etc/ld.so.conf
包含安装目录,这可能就像运行以下命令一样简单。
注意:macOS 不支持 ldconfig。
sudo ldconfig
如果我们已经构建并安装了该库,我们可以编写一个简单的 hello world 程序并将其保存到名为hello.c
的文件中:
#include <stdio.h>
#include <collectc/cc_array.h>
int main ( int argc , char * * argv ) {
// Create a new array
CC_Array * ar ;
cc_array_new ( & ar );
// Add a string to the array
cc_array_add ( ar , "Hello World!n" );
// Retreive the string and print it
char * str ;
cc_array_get_at ( ar , 0 , ( void * ) & str );
printf ( "%s" , str );
return 0 ;
}
现在我们需要编译并链接我们的程序。由于make
既构建了静态库又构建了动态库,因此我们可以选择要链接到程序中的库。
如果我们希望将库静态链接到我们的程序,我们可以将-static
标志传递给编译器
注意:在 macOS 上, -static
标志不是很友好(它要求所有库都是静态链接的)。因此我们可以将-static -lcollectc
替换为静态库的完整路径。默认情况下是/usr/local/lib/libcollectc.a
。
gcc hello.c -static -lcollectc -o hello
或使用 clang 编译时类似:
clang hello.c -static -lcollectc -o hello
这将通过将库复制到可执行文件中来链接该库。如果我们不希望将 Collections-C 作为运行时依赖项,则可以使用此选项,但这会以生成更大的可执行文件为代价。
我们还可以选择在运行时动态链接库。如果省略-static
编译器标志,这是默认行为:
gcc hello.c -lcollectc -o hello
或者用 clang:
clang hello.c -lcollectc -o hello
动态链接会生成较小的可执行文件,但要求要执行该程序的每个系统上都存在libcollectc.so
。
有时编译器可能无法找到库或头文件。这通常是因为它在错误的目录中查找它们,如果库或标头或两者安装在非标准目录中或根本没有安装,则可能会发生这种情况。
如果是这种情况,我们可以通过传递-I[path to headers]
和-L[path to libraries]
选项来显式告诉编译器在哪里查找它们:
gcc hello.c `pkg-config --cflags --libs collectionc` -o hello
如果编译一切顺利,我们可以运行可执行文件:
./hello
它应该打印Hello, World!
到控制台。
欢迎贡献。
如果您有功能请求或发现错误,请随时提出新问题。如果您想贡献代码,请参阅 CONTRIBUTING.md 了解更多详细信息。