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 以了解更多詳細資訊。