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
завершит создание make-файлов, мы сможем собрать библиотеку, запустив 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 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 для получения более подробной информации.