Tempo de execução Determine o tipo para C
-
20-09-2019 - |
Pergunta
Se o tipo de variável deve ser determinado como tempo de execução em C, mas o nome da variável é corrigido e dado, existe alguma maneira de reutilizar o código que envolve a variável?
Na verdade, estou perguntando sobre a situação de contraparte C de Tempo de execução Determine o tipo para C ++.
Se possível, dê alguns exemplos.
Solução
O idioma C não possui os recursos orientados a objetos que tornam significativo perguntar sobre o tipo de objeto de tempo de execução em C ++.
Você normalmente implementa a genicidade em C, lançando de e para de e para void*
. Exemplo: a função C qsort.
Se sua pergunta é determinar em tempo de execução qual tipo real A void*
Ponteiro aponta, isso é impossível. As informações simplesmente não são armazenadas pela maioria dos compiladores.
Outras dicas
Uma técnica padrão é fornecer uma variável de informação de tipo rápido como um parâmetro e ativar isso e passar todos os dados por referência. Dentro da função, recuperamos o valor com fundição explícita. O tipo de vazio* é desmarcado pelo compilador, de modo que o perigo está enviando um tipo que é não tratado pela função (falha de segmentação, corrupção de dados ou resultado de comportamento desconhecido). Comece configurando uma enumeração dos tipos de que você precisa:
Nesse caso, eu uso a função do tipo de convenção para representar uma função retornando um tipo.
A Diretiva Enum escolhe números inteiros sucessivos de 0, ou você pode atribuir a cada enumeração seu próprio valor int.
typedef enum D_types {
ANINT, // don't use actual system type names
AFLOAT,
ADOUBLE,
ASTRING,
MY_STRUCT=100,
MY_STRUCT2=200
VOID_FUNCTION=1000,
INT_FUNCTION = 2000,
STRUCT_FUNCTION=3000
} DATATYPE;
/* an f_int is a function pointer to a function */
typedef int (*f_int)(int, void* );
Na sua definição de função, você envia os dados por referência e o tipo e o fundem para o tipo correto antes do uso:
int myfunction ( DATATYPE dt, void* data, )
{
int an_int = 0;
int * ip; // typed pointers for casting of the void pointer data
double * dp;
char * sp;
struct My_struct * msp;
struct My_struct_2 * ms2p;
f_int fp;
...
switch (dt){
case ANINT:
ip = (int*) data; // only pointers can be assigned void pointer values.
int i = *ip // dereference of typed pointer, no dereferencing void pointers.
...
break;
case ADOUBLE:
dp = (double*) data;
double d = *dp;
...
break;
case ASTRING:
char * s = strdup( (char*) data); // cast to char pointer allowed (pointer->pointer)
...
break;
case MY_STRUCT:
msp = ( struct My_Struct *) data;
char* ms_name = msp->name; // if my_struct has a name string ...
float dollarvalue = msp->dvalue;
...
case INT_FUNCTION:
fp = (f_int)data;
an_int = fp( ANINT, 5);
}
return an_int;
}
Como você pode imaginar, isso está jogando com partidas em uma fábrica de fogos de artifício e não incentivado como uma prática constante.
No seu código, você chamaria assim:
double pi =3.14159;
int g = myfunction( ADOUBLE, &pi ); // pass by reference, not value
int j = myfunction (ASTRING , "HEY NOW" ); //C strings pass by ref normally
f_int myfunc = myfunction; // a function pointer (ref to the functions address )
int r = myfunction ( INT_FUNCTION, myfunc ); /* function as a parameter ... */
Além de uma função única, é recomendável usar as funções varargshttp://www.eskimo.com/~scs/cclass/int/sx11b.html