Collections-C est une bibliothèque de structures de données génériques pour le langage C.
Structures qui stockent les données sous forme de void*
.
Récipient | description |
---|---|
CC_Array | Un tableau dynamique qui se développe automatiquement à mesure que des éléments sont ajoutés. |
CC_List | Liste doublement liée. |
CC_SList | Liste à chaînage unique. |
CC_Deque | Un tableau dynamique qui prend en charge l'insertion et la suppression à temps constant amorti aux deux extrémités et l'accès à temps constant. |
CC_HashTable | Une carte clé-valeur non ordonnée. Prend en charge, dans le meilleur des cas, l'insertion, la suppression et la recherche de valeurs à temps constant amorti. |
CC_TreeTable | Une carte clé-valeur ordonnée. Prend en charge l'insertion, la suppression et la recherche de valeurs logarithmiques. |
CC_HashSet | Un ensemble non ordonné. La recherche, la suppression et l'insertion sont effectuées en temps constant amorti et dans le pire des cas en temps linéaire amorti. |
CC_TreeSet | Un ensemble ordonné. La recherche, la suppression et l'insertion sont effectuées en temps logarithmique. |
CC_Queue | Une structure FIFO (premier entré, premier sorti). Prend en charge l'insertion, la suppression et la recherche en temps constant. |
CC_Stack | Une structure LIFO (dernier entré, premier sorti). Prend en charge l'insertion, la suppression et la recherche en temps constant. |
CC_PQueue | Une file d'attente prioritaire. |
CC_RingBuffer | Un tampon annulaire. |
CC_TSTTable | Une table d'arbre de recherche ternaire. Prend en charge l'insertion, la recherche, l'itération et la suppression. |
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
}
Structures qui stockent directement des données de longueur arbitraire.
Récipient | description |
---|---|
CC_ArraySized | Un tableau dynamique qui se développe automatiquement à mesure que des éléments sont ajoutés. |
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
}
Les pools de mémoire sont des blocs pré-alloués de mémoire contiguë
Récipient | description |
---|---|
CC_DynamicPool | Sur le tas, pool de mémoire potentiellement extensible |
CC_StaticPool | Piscine fixe |
/* 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 ;
}
Ces packages peuvent généralement être installés via le gestionnaire de packages de votre distribution.
Pour construire le projet, nous devons d'abord créer un répertoire de construction distinct (s'il n'existe pas déjà) :
mkdir build
Depuis ce répertoire, nous pouvons exécuter la commande cmake
et configurer le build :
cmake ..
ou cmake -DSHARED=True
pour que Collections-C soit construit en tant que bibliothèque partagéecmake -DSHARED=False
pour construire une bibliothèque statique Une fois que cmake
a fini de générer des makefiles, nous pouvons construire la bibliothèque en exécutant make
dans notre répertoire de construction.
Un exemple de clonage et de création d'une bibliothèque statique :
git clone https://github.com/Collections-C.git
cd Collections-C
mkdir build
cd build
cmake -DSHARED=False
make
Pour exécuter des tests (à partir du répertoire build
) :
make test
Pour exécuter des tests individuels, exécutez simplement l'exécutable approprié. Par exemple:
build/test/array_test
Pour installer la bibliothèque, exécutez :
sudo make install
Par défaut, les bibliothèques et les en-têtes seront installés dans les répertoires /usr/local/lib/
et /usr/local/include
.
Vous devez informer le moteur d'exécution du système de l'emplacement de la nouvelle bibliothèque pour pouvoir exécuter des applications liées dynamiquement. Cela peut être aussi simple que d'exécuter la commande suivante si votre /etc/ld.so.conf
contient le répertoire d'installation.
Remarque : macOS ne prend pas en charge ldconfig.
sudo ldconfig
Si nous avons déjà construit et installé la bibliothèque, nous pouvons écrire un simple programme hello world et l'enregistrer dans un fichier nommé 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 ;
}
Nous devons maintenant compiler et lier notre programme. Puisque make
construit à la fois la bibliothèque statique et la bibliothèque dynamique, nous pouvons choisir celle que nous souhaitons lier à notre programme.
Si nous souhaitons lier statiquement la bibliothèque à notre programme, nous pouvons transmettre l'indicateur -static
au compilateur.
Remarque : Sur macOS, l'option -static
n'est pas très conviviale (elle nécessite que toutes les bibliothèques soient liées statiquement). Nous pouvons donc remplacer -static -lcollectc
par le chemin complet vers la bibliothèque statique. Qui est /usr/local/lib/libcollectc.a
par défaut.
gcc hello.c -static -lcollectc -o hello
ou de même lors de la compilation avec clang :
clang hello.c -static -lcollectc -o hello
Cela liera la bibliothèque en la copiant dans l'exécutable. Nous pouvons utiliser cette option si nous ne souhaitons pas avoir Collections-C comme dépendance d'exécution , mais cela se fait au détriment de la génération d'un exécutable plus volumineux.
Nous pouvons également choisir de créer un lien dynamique avec la bibliothèque au moment de l'exécution. Il s'agit du comportement par défaut si l'option -static
du compilateur est omise :
gcc hello.c -lcollectc -o hello
ou avec bruit :
clang hello.c -lcollectc -o hello
La liaison dynamique produit un exécutable plus petit, mais nécessite que libcollectc.so
soit présent sur chaque système sur lequel le programme va être exécuté.
Parfois, le compilateur peut avoir du mal à trouver la bibliothèque ou les en-têtes. Cela est généralement dû au fait qu'il les recherche dans le mauvais répertoire, ce qui peut arriver si la bibliothèque, les en-têtes ou les deux sont installés dans un répertoire non standard ou ne sont pas installés du tout.
Si tel est le cas, nous pouvons indiquer explicitement au compilateur où les rechercher en passant les options -I[path to headers]
et -L[path to libraries]
:
gcc hello.c `pkg-config --cflags --libs collectionc` -o hello
Si tout s'est bien passé avec la compilation nous pouvons lancer l'exécutable :
./hello
et il devrait imprimer Hello, World!
à la console.
Les contributions sont les bienvenues.
Si vous avez une demande de fonctionnalité ou si vous avez trouvé un bug, n'hésitez pas à ouvrir un nouveau numéro. Si vous souhaitez contribuer au code, voir CONTRIBUTING.md pour plus de détails.