Lista de tipos indefinidos em C
Como muitos sabem, a linguagem C não permite que criemos variáveis com tipos distintos de dados. Entretanto existe uma forma de contornar isso que é utilizar void ** (ponteiro para ponteiro de void).
Se criarmos uma lista:
typedef struct node {
void ** conteudo;
struct lista ** prev;
struct lista ** next;
} Node;
typedef struct lista {
Node * first;
Node * last;
unsigned int length;
} Lista;
Desta maneira poderemos comportar qualquer tipo de dados, tendo apenas algumas preocupações a mais na hora de implementar as funções que darão sentido a lista.
É importante ter uma função responsável por criar uma nova lista:
Lista * listaInit()
{
Lista * l = (Lista * ) malloc(sizeof(Lista));
l->first = l->last = NULL;
l->length = 0;
return l;
}
É importante ter uma função responsável por inserir elementos na lista:
Observe que, além do novo elemento a ser adicionado, a função também precisa do seu tamanho em bytes.
void listaPush(Lista * l, void ** content, size_t osize)
{
Node * no = (Node *) malloc(sizeof(Node));
no->content = (void ** ) malloc(osize);
memcpy(no->content, content, osize);
no->prev = NULL;
no->next = NULL;
if (l->first == NULL) {
l->first = l->last = no;
} else {
no->prev = l->last;
l->last->next = no;
l->last = no;
}
l->length++;
}
A partir dessa estrutura podemos criar outras como filas e pilhas, que nada mais são do que listas, com funções de inserção e remoção restritas as uma das extremidades da lista e com regras de acesso fixas.
Também é possível criar macros para facilitar o acesso ao conteúdo dessas listas:
#define FOREACH(no, lista) for ((no) = (lista->first); (no); (no) = (no->next))
Futuramente disponibilizarei uma biblioteca dessas funções no meu github.
Ninguem é tão sábio que não tenha algo pra aprender e nem tão tolo que não tenha algo pra ensinar.
Blaise Pascal