Collections-C é uma biblioteca de estruturas de dados genéricas para a linguagem C.
Estruturas que armazenam dados na forma de void*
.
Recipiente | descrição |
---|---|
CC_Array | Uma matriz dinâmica que se expande automaticamente à medida que os elementos são adicionados. |
CC_List | Lista duplamente vinculada. |
CC_SList | Lista vinculada individualmente. |
CC_Deque | Uma matriz dinâmica que suporta inserção e remoção em tempo constante amortizado em ambas as extremidades e acesso em tempo constante. |
CC_HashTable | Um mapa de valores-chave não ordenado. Suporta inserção, remoção e pesquisa de valores em tempo constante amortizado no melhor caso. |
CC_TreeTable | Um mapa de valores-chave ordenado. Suporta inserção, remoção e pesquisa de valores em tempo logarítmico. |
CC_HashSet | Um conjunto não ordenado. A consulta, exclusão e inserção são realizadas em tempo constante amortizado e, no pior caso, em tempo linear amortizado. |
CC_TreeSet | Um conjunto ordenado. A pesquisa, exclusão e inserção são realizadas em tempo logarítmico. |
CC_Queue | Uma estrutura FIFO (primeiro a entrar, primeiro a sair). Suporta inserção, remoção e pesquisa em tempo constante. |
CC_Stack | Uma estrutura LIFO (último a entrar, primeiro a sair). Suporta inserção, remoção e pesquisa em tempo constante. |
CC_PQueue | Uma fila prioritária. |
CC_RingBuffer | Um buffer de anel. |
CC_TSTTable | Uma tabela de árvore de pesquisa ternária. Suporta inserção, pesquisa, iteração e exclusão. |
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
}
Estruturas que armazenam dados de comprimento arbitrário diretamente.
Recipiente | descrição |
---|---|
CC_ArraySized | Uma matriz dinâmica que se expande automaticamente à medida que os elementos são adicionados. |
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
}
Pools de memória são blocos pré-alocados de memória contígua
Recipiente | descrição |
---|---|
CC_DynamicPool | Na pilha, pool de memória potencialmente expansível |
CC_StaticPool | Conjunto fixo |
/* 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 ;
}
Esses pacotes geralmente podem ser instalados através do gerenciador de pacotes de sua distribuição.
Para construir o projeto, primeiro precisamos criar um diretório de construção separado (se ainda não existir):
mkdir build
Neste diretório podemos executar o comando cmake
e configurar a compilação:
cmake ..
ou cmake -DSHARED=True
para fazer o Collections-C ser construído como uma biblioteca compartilhadacmake -DSHARED=False
para construir uma biblioteca estática Depois que cmake
terminar de gerar makefiles, podemos construir a biblioteca executando make
dentro de nosso diretório de construção.
Um exemplo de clonagem e construção de uma biblioteca estática:
git clone https://github.com/Collections-C.git
cd Collections-C
mkdir build
cd build
cmake -DSHARED=False
make
Para executar testes (do diretório build
):
make test
Para executar testes individuais, basta executar o executável apropriado. Por exemplo:
build/test/array_test
Para instalar a biblioteca execute:
sudo make install
Por padrão, as bibliotecas e cabeçalhos serão instalados nos diretórios /usr/local/lib/
e /usr/local/include
.
Você deve informar o tempo de execução do sistema sobre a localização da nova biblioteca para poder executar aplicativos vinculados dinamicamente. Isso pode ser tão simples quanto executar o seguinte comando se seu /etc/ld.so.conf
contiver o diretório de instalação.
Nota: o macOS não oferece suporte a ldconfig.
sudo ldconfig
Se já construímos e instalamos a biblioteca, podemos escrever um programa simples hello world e salvá-lo em um arquivo chamado 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 ;
}
Agora precisamos compilar e vincular nosso programa. Como make
constrói a biblioteca estática e a dinâmica, podemos escolher qual delas desejamos vincular ao nosso programa.
Se desejarmos vincular estaticamente a biblioteca ao nosso programa, podemos passar o sinalizador -static
para o compilador
Nota: No macOS, o sinalizador -static
não é muito amigável (requer que todas as bibliotecas estejam vinculadas estaticamente). Portanto, podemos substituir -static -lcollectc
pelo caminho completo para a biblioteca estática. Qual é /usr/local/lib/libcollectc.a
por padrão.
gcc hello.c -static -lcollectc -o hello
ou similarmente ao compilar com clang:
clang hello.c -static -lcollectc -o hello
Isso vinculará a biblioteca, copiando-a para o executável. Podemos usar esta opção se não desejarmos ter Collections-C como uma dependência de tempo de execução , porém isso custará a geração de um executável maior.
Também podemos optar por vincular-se à biblioteca dinamicamente em tempo de execução. Este é o comportamento padrão se omitir o sinalizador do compilador -static
:
gcc hello.c -lcollectc -o hello
ou com clang:
clang hello.c -lcollectc -o hello
A vinculação produz dinamicamente um executável menor, mas requer que libcollectc.so
esteja presente em todos os sistemas nos quais o programa será executado.
Às vezes, o compilador pode ter problemas para encontrar a biblioteca ou os cabeçalhos. Geralmente, isso ocorre porque ele os procura no diretório errado, o que pode acontecer se a biblioteca, os cabeçalhos ou ambos estiverem instalados em um diretório não padrão ou não estiverem instalados.
Se for esse o caso, podemos dizer explicitamente ao compilador onde procurá-los, passando as opções -I[path to headers]
e -L[path to libraries]
:
gcc hello.c `pkg-config --cflags --libs collectionc` -o hello
Se tudo correu bem com a compilação podemos executar o executável:
./hello
e deve imprimir Hello, World!
para o console.
Contribuições são bem-vindas.
Se você tiver uma solicitação de recurso ou encontrar um bug, sinta-se à vontade para abrir um novo problema. Se você deseja contribuir com código, consulte CONTRIBUTING.md para obter mais detalhes.