Collections-C es una biblioteca de estructuras de datos genéricas para el lenguaje C.
Estructuras que almacenan datos en forma de void*
.
Recipiente | descripción |
---|---|
CC_Array | Una matriz dinámica que se expande automáticamente a medida que se agregan elementos. |
CC_List | Lista doblemente enlazada. |
CC_SList | Lista enlazada individualmente. |
CC_Deque | Una matriz dinámica que admite la inserción y eliminación de tiempo constante amortizado en ambos extremos y el acceso en tiempo constante. |
CC_HashTable | Un mapa de valores clave desordenado. Admite la inserción, eliminación y búsqueda de valores en tiempo constante amortizado en el mejor de los casos. |
CC_TreeTable | Un mapa de valores clave ordenado. Admite la inserción, eliminación y búsqueda de valores en tiempo logarítmico. |
CC_HashSet | Un conjunto desordenado. La búsqueda, el borrado y la inserción se realizan en tiempo constante amortizado y en el peor de los casos en tiempo lineal amortizado. |
CC_TreeSet | Un conjunto ordenado. La búsqueda, eliminación e inserción se realizan en tiempo logarítmico. |
CC_Queue | Una estructura FIFO (primero en entrar, primero en salir). Admite inserción, eliminación y búsqueda en tiempo constante. |
CC_Stack | Una estructura LIFO (último en entrar, primero en salir). Admite inserción, eliminación y búsqueda en tiempo constante. |
CC_PQueue | Una cola prioritaria. |
CC_RingBuffer | Un búfer en anillo. |
CC_TSTTable | Una tabla de árbol de búsqueda ternaria. Admite inserción, búsqueda, iteración y eliminación. |
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
}
Estructuras que almacenan datos de longitud arbitraria directamente.
Recipiente | descripción |
---|---|
CC_ArraySized | Una matriz dinámica que se expande automáticamente a medida que se agregan elementos. |
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
}
Los grupos de memoria son bloques preasignados de memoria contigua
Recipiente | descripción |
---|---|
CC_DynamicPool | En el montón, grupo de memoria potencialmente ampliable |
CC_StaticPool | piscina fija |
/* 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 ;
}
Estos paquetes generalmente se pueden instalar a través del administrador de paquetes de distribución.
Para construir el proyecto, primero necesitamos crear un directorio de compilación separado (si aún no existe):
mkdir build
Desde este directorio podemos ejecutar el comando cmake
y configurar la compilación:
cmake ..
o cmake -DSHARED=True
para hacer que Collections-C se construya como una biblioteca compartidacmake -DSHARED=False
para construir una biblioteca estática Una vez que cmake
haya terminado de generar archivos MAKE, podemos construir la biblioteca ejecutando make
dentro de nuestro directorio de compilación.
Un ejemplo de clonación y construcción de una biblioteca estática:
git clone https://github.com/Collections-C.git
cd Collections-C
mkdir build
cd build
cmake -DSHARED=False
make
Para ejecutar pruebas (desde el directorio build
):
make test
Para ejecutar pruebas individuales, simplemente ejecute el ejecutable apropiado. Por ejemplo:
build/test/array_test
Para instalar la biblioteca ejecute:
sudo make install
De forma predeterminada, las bibliotecas y los encabezados se instalarán en los directorios /usr/local/lib/
y /usr/local/include
.
Debe hacer que el tiempo de ejecución del sistema sea consciente de la ubicación de la nueva biblioteca para poder ejecutar aplicaciones vinculadas dinámicamente. Esto podría ser tan simple como ejecutar el siguiente comando si su /etc/ld.so.conf
contiene el directorio de instalación.
Nota: macOS no es compatible con ldconfig.
sudo ldconfig
Si ya creamos e instalamos la biblioteca, podemos escribir un programa simple de hola mundo y guardarlo en un archivo llamado 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 ;
}
Ahora necesitamos compilar y vincular nuestro programa. Dado que make
construye tanto la biblioteca estática como la dinámica, podemos elegir cuál deseamos vincular a nuestro programa.
Si deseamos vincular estáticamente la biblioteca a nuestro programa, podemos pasar el indicador -static
al compilador.
Nota: En macOS, el indicador -static
no es muy amigable (requiere que todas las bibliotecas estén vinculadas estáticamente). Entonces podemos reemplazar -static -lcollectc
con la ruta completa a la biblioteca estática. Que es /usr/local/lib/libcollectc.a
por defecto.
gcc hello.c -static -lcollectc -o hello
o de manera similar al compilar con clang:
clang hello.c -static -lcollectc -o hello
Esto vinculará la biblioteca copiándola en el ejecutable. Podemos usar esta opción si no deseamos tener Collections-C como dependencia de tiempo de ejecución ; sin embargo, esto tiene el costo de generar un ejecutable más grande.
También podemos optar por vincularnos dinámicamente con la biblioteca en tiempo de ejecución. Este es el comportamiento predeterminado si se omite el indicador del compilador -static
:
gcc hello.c -lcollectc -o hello
o con sonido metálico:
clang hello.c -lcollectc -o hello
La vinculación dinámica produce un ejecutable más pequeño, pero requiere que libcollectc.so
esté presente en todos los sistemas en los que se ejecutará el programa.
A veces el compilador puede tener problemas para encontrar la biblioteca o los encabezados. Esto generalmente se debe a que los busca en el directorio incorrecto, lo que puede suceder si la biblioteca, los encabezados o ambos están instalados en un directorio no estándar o no están instalados en absoluto.
Si este es el caso, podemos decirle explícitamente al compilador dónde buscarlos pasando las opciones -I[path to headers]
y -L[path to libraries]
:
gcc hello.c `pkg-config --cflags --libs collectionc` -o hello
Si todo ha ido bien con la compilación podemos ejecutar el ejecutable:
./hello
y debería imprimir Hello, World!
a la consola.
Las contribuciones son bienvenidas.
Si tiene una solicitud de función o ha encontrado un error, no dude en abrir una nueva edición. Si desea contribuir con código, consulte CONTRIBUTING.md para obtener más detalles.