Skip to content

Instantly share code, notes, and snippets.

@growlnx
Last active June 25, 2019 20:47
Show Gist options
  • Save growlnx/755c339d4e2c9cbd09f9977f0ee1031e to your computer and use it in GitHub Desktop.
Save growlnx/755c339d4e2c9cbd09f9977f0ee1031e to your computer and use it in GitHub Desktop.
implementação de um tipo genérico de dados em C
#include <stdio.h>
#include <stdlib.h>
#define TYPE_NONE 100 // lembra de python? então...
#define TYPE_INT 101
#define TYPE_FLOAT 102
/// objeto generico
typedef struct object object;
struct object
{
// aponta para o endereço de outro ponteiro na memória
void* ref;
// necessário para saber o tipo de casting de ponteiro a ser realizado
int type;
};
object*
/// cria uma nova instância de object na heap
create_object(int type, void* ref)
{
// aloca espaço na heap
object* obj = (object*)malloc(sizeof(object));
// inicializa objeto
obj->type = type;
obj->ref = ref;
return obj;
}
void
/// remove a instância de object da heap
destroy_object(object* obj)
{
if (obj != NULL) {
free(obj->ref);
}
free(obj);
}
int*
/// cria uma nova instância de int na heap
create_int(int val)
{
// aloca espaço na heap
int* var = (int*)malloc(sizeof(int));
// inicializa objeto
*var = val;
return var;
}
int*
/// recupera um int a partir de sua referência
get_int_from_ref(void* ref)
{
// faz casting para ponteiro de inteiro pegando o endereço apontado por ref
return ((int*)ref);
}
float*
/// cria uma nova instância de float na heap
create_float(float val)
{
// aloca espaço na heap
float* var = (float*)malloc(sizeof(float));
// inicializa objeto
*var = val;
return var;
}
float*
/// recupera um float a partir de sua referência
get_float_from_ref(void* ref)
{
// casting de ponteiros
return ((float*)ref);
}
void
/// imprime array na saída para fins de debug
dump_array(object* arr[], const size_t arr_size)
{
printf("[ ");
for (int i = 0; i < arr_size; i++) {
switch (arr[i]->type) {
case TYPE_NONE:
printf("None");
break;
case TYPE_INT:
printf("%d", *get_int_from_ref(arr[i]->ref));
break;
case TYPE_FLOAT:
printf("%.2f", *get_float_from_ref(arr[i]->ref));
break;
}
// não imprimir virgula no último elemento do array
if (i != arr_size - 1) {
printf(", ");
}
}
printf(" ]\n");
}
void
/// remove todas as instância de object do array e depois desaloca o array
destroy_array(object* arr[], const size_t arr_size)
{
for (int i = 0; i < arr_size; i++) {
destroy_object(arr[i]);
}
free(arr);
}
int
main()
{
// tamanho do array
const size_t arr_size = 4;
object** arr = (object**)calloc(arr_size, sizeof(object));
// incializando array de objects
arr[0] = create_object(TYPE_INT, create_int(10));
arr[1] = create_object(TYPE_FLOAT, create_float(20.25));
arr[2] = create_object(TYPE_NONE, NULL);
arr[3] = create_object(TYPE_FLOAT, create_float(40.99));
// exibindo estado do array
dump_array(arr, arr_size);
// libera memoria alocada para o array
destroy_array(arr, arr_size);
// memoria anteriormente alocada foi liberada, caso queira testar...
// dump_array(arr, arr_size);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment