Skip to content

Latest commit

 

History

History
219 lines (162 loc) · 6.26 KB

README.md

File metadata and controls

219 lines (162 loc) · 6.26 KB

c_vector

A simple vector-like struct in C

Introduction aux vecteurs

Il existe en C++ une classe vector. Cette classe permet de stocker des éléments de n'importe quel type.

A l'inverse des vecteurs en mathématiques, les vecteurs en langage de programmation sont simplement des tableaux d'éléments.

Ils permettent de ne plus avoir à se soucier de la gestion de la mémoire, et cette classe dispose de nombreuse méthodes pour manipuler les éléments stockés.

Afin de rendre nos codes plus propres, nous avons décidé d'adapter ces fonctions en C. Je vous propose donc de faire un tour rapide sur les fonctions à disposition avec des exemples simples.

Vous pouvez bien sûr créer vos propres fonctions et, pourquoi pas, les proposer au reste de la communauté.

Utiliser le vecteur

Cette librairie permet seulement d'enregistrer des pointeurs. Utile pour un tableau de structure par exemple.

Pourquoi ne pas l'utiliser pour lemin ?

La fonction ci-dessous permet de créer un nouveau vecteur. En dessous du prototype sont présentés ses paramètres ainsi que son utilisation.

t_vector   *new_vector(size_t elt_size, void (*_delete)(void *))

Prend 2 paramètres :

  • la taille de la donnée (ex: sizeof(t_muffin))
  • une fonction destructrice.

Exemple d'utilisation:

typedef struct   s_exemple
{
    char         *nom;
}                t_exemple;
 
void      fonction_qui_casse_tout(t_exemple *ex)
{
    free(ex->nom);
    free(ex);
}

void    affiche_nom(t_exemple *e)
{
    ft_putstr(e->nom);
}

int         main()
{
    t_vector    *vector;
    t_exemple   *ex;

    ex = (t_exemple *)malloc(sizeof(ex));
    ex->nom = "Super Muffin";
    vector = new_vector(sizeof(ex), &fonction_qui_casse_tout);
    vector->push(ex, vector);
    ft_putstr("Je suis un ");
    vector->map(vector, &affiche_nom);
    return (1);
}

Cet exemple stocke ex dans le vecteur et applique la fonction affiche_nom à tous les éléments du vecteur. On obtiendra donc:

$> Je suis un Super Muffin

Les fonctions du vecteur

Dans les descriptions suivantes, la première ligne correspond au prototype de la fonction (pour les curieux), la suivante correspond à son utilisation.

Nous devrons passer la référence du pointeur dans chaque fonction, ce qui n'est pas forcément beau mais est le seul moyen d'utilisation.

empty

Retourne un booléen: 1 si le vecteur est NULL, 0 si des éléments sont à l'intérieur.

int		vector_is_empty(t_vector *self);

self->empty(self);

Vous n'aurez à utiliser cette fonction que dans de rare cas.

size

Retourne le nombre d'éléments stockés dans le vecteur.

size_t     vector_size(t_vector *self);

self->size(self);

v_capacity

Retourne la capacité de stockage du vecteur.

size_t	vector_capacity(t_vector *self);

self->v_capacity(self);

Vous n'aurez à utiliser cette fonction que dans de rare cas.

swap

Intervertit deux éléments du vecteur.

void	vector_swap(t_vector *self, int index_1, int index_2);

self->swap(self, 1, 2);

1 devient donc 2, et 2 devient 1.

pop

Copie un élément du vecteur dans le pointeur à remplir elem, en partant de la fin.

void	vector_pop(void *elem, t_vector *self);

self->pop(ptr, self);

Correspond à la méthode LIFO (Last In First Out)

pop_front

Copie un élément du vecteur dans le pointeur à remplir elem, en partant du début.

void	vector_pop_front(void *elem, t_vector *self);

self->pop_front(ptr, self);

Correspond à la méthode FIFO (First In First Out)

push

Stocke l'élément elem en dernière position du vecteur.

int		vector_push(void *elem, t_vector *self);

self->push(ptr, self);

Renvoie 0 en cas d'erreur, 1 si tout va bien.

push_front

Stocke l'élément elem en première position du vecteur.

int		vector_push_front(void *elem, t_vector *self);

self->push_front(ptr, self);

Les anciens éléments seront donc décalés sur la droite !

at

Retourne une copie de l'élément présent dans le vecteur à l'index donné.

void	*vector_at(t_vector *self, int request);

self->at(self, 5);

front

Retourne le premier élément du vecteur.

void	*vector_front(t_vector *self);

self->front(self);

Toute modification sera enregistrée dans le vecteur.

back

Retourne le dernier élément du vecteur.

void	*vector_back(t_vector *self);

self->back(self);

Toute modification sera enregistrée dans le vecteur.

data

Retourne l'élément du vecteur à l'index donné.

void	*vector_data(t_vector *self, int request);

self->data(self, 5);

À l'inverse de at(), data() permet d'enregistrer dans le vecteur toutes les modifications faites sur le pointeur de retour.

each

Retourne chaque élément du vecteur (avec un appel en boucle). La mémoire du vecteur sera affectée.

void	*c_vector_each(t_vector *self);

while ((ptr = self->each(self)))
      do_stuff(ptr);

Notez que vous n'avez pas besoin de compteur, NULL sera renvoyé une fois le vecteur parcouru.

map

Applique une fonction sur chaque élément du vecteur.

void	c_vector_map(t_vector *self, void (*fct)(void *elt));

self->map(self, &affiche_nom);

Un seul appel à la fonction est nécessaire.

remove

Supprime un élément à un index donné.

int		c_vector_remove(size_t i, t_vector *self);

self->remove(5, self);

Tous les éléments à droite seront décalés vers la gauche.

Si jamais vous êtes arrivés là par hasard, le lien vers la librairie : c_vector

Cheers & Octocats !