Last active
June 25, 2019 20:47
-
-
Save growlnx/755c339d4e2c9cbd09f9977f0ee1031e to your computer and use it in GitHub Desktop.
implementação de um tipo genérico de dados em C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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