Páginas

terça-feira, 16 de março de 2010

pilha genérica em c (aceita qualquer tipo de dados)

 
/*
    Uisleandro Costa dos Santos
    Pilha generica em C
  
    Não sei se é o melhor jeito de fazer isso,
    mas com certeza é interessante!

    Aceita qualquer tipo de dados, no entanto é preciso
    fazer o cast corretamente.
*/

#include <stdlib.h>;
#include <stdio.h>;
#include <string.h>;

/* É muito bom poder passar parametros para o define... ;) que tal uma pilha de pilhas? */
#define PILHA_INICIA(_pilha)\
{\
    _pilha = malloc(sizeof(pilha));\
    _pilha->topo = (nodo *)NULL;\
    _pilha->count = 0;\
}

// insere ..
#define PILHA_PUSH(pilha, tipo, valor)\
{\
    nodo * NODO_AUX;\
 if(!pilha) exit (1);\
    NODO_AUX = (nodo *)malloc(sizeof(nodo));\
    if(!NODO_AUX) exit(1);\
    NODO_AUX->value = (void *)malloc(sizeof(tipo));\
    if(!(NODO_AUX->value))exit(1);\
    *((tipo *)NODO_AUX->value) = valor;\
    NODO_AUX->next = pilha->topo;\
    pilha->topo = NODO_AUX;\
    pilha->count++;\
    NODO_AUX = NULL;\
}

// retira um valor da pilha, sem retornar..
#define PILHA_POP(pilha)\
if(pilha->count > 0)\
{\
    nodo * NODO_AUX = pilha->topo;\
    pilha->topo = pilha->topo->next;\
    free(NODO_AUX->value);\
    free(NODO_AUX);\
    pilha->count--;\
    NODO_AUX = NULL;\
}

// vê o ultimo valor inserido
#define PILHA_PEEK(pilha, tipo) (*((tipo *)pilha->topo->value))

// vê se a pilha está vazia
#define PILHA_ISEMPTY(pilha) (pilha->count <= 0)

// remove todos os valores da pilha..
#define PILHA_DESTOI(pilha)\
{\
    nodo * NODO_AUX;\
    while(pilha->topo)\
    {\
        NODO_AUX = pilha->topo;\
        pilha->topo = pilha->topo->next;\
        free(NODO_AUX->value);\
        free(NODO_AUX);\
        pilha->count--;\
        NODO_AUX = NULL;\
    }\
}

typedef struct nodo
{
    void * value;
    struct nodo * next;
} nodo;

typedef struct
{
    struct nodo * topo;
    int count;
} pilha;

// um tipo criado só para testar a pilha.
typedef struct
{
    char nome[30];
    int idade;
} pessoa;


int main()
{
    pilha * p;
    pessoa pe;
 
    strcpy(pe.nome,"Fulano de tal ");
    pe.idade = strlen(pe.nome);
  
    PILHA_INICIA(p);

    PILHA_PUSH(p, int, pe.idade);
    PILHA_PUSH(p, pessoa, pe);  
    PILHA_PUSH(p, float, 12);

     //pilha_destroi(&p);
     //PILHA_DESTOI(p);
     //printf("%d", PILHA_ISEMPTY(p));
     //system("pause");

    printf("R$ %.2f ", PILHA_PEEK(p, float));
    PILHA_POP(p);
    
    printf("%s", PILHA_PEEK(p, pessoa).nome);
    PILHA_POP(p);
  
    printf("%d", PILHA_PEEK(p, int));
    PILHA_POP(p);
  
    printf("\n");
 
    system("pause");
 
    return 0;
}