2010-11-20 12 views
7

Hii,implementación genérica en C

Mientras estaba poniendo en práctica algunos de los programas para la asignación de clase, sólo me llamó la atención la forma en que sería la implementación de la misma de una forma genérica utilizando C.

I Sé que tenemos que hacer uso de los punteros y las funciones vacías, pero me quedé atrapado en cómo hacerlo. Por favor, dame un ejemplo que sea simple y demuestre el uso.

Al igual que la forma de aplicar una función de comparación para poner en práctica una especie de comparación, o para insertar en una lista enlazada donde cada nodo tiene un elemento de tipo variado, etc ...

PS: Los enlaces a otras preguntas o artículos son útiles y bienvenidos.

+0

¿Se refiere a "genéricos"? http://download.oracle.com/javase/tutorial/extra/generics/index.html –

+2

Actualiza a C++ y usa plantillas, así es como. – Puppy

+2

@deadMG: sé programar el mismo uso de genéricos en C++. Quería saber cómo hacerlo en C. – Flash

Respuesta

2

Puede usar void * pointers, luego mucha fundición. Tenga en cuenta que tendrá que almacenar el tipo de alguna manera para volver a refundir en el elemento original, por lo que no es exactamente genérico, pero lo más cerca que obtendrá.

Obviamente este tipo de código es muy propenso a errores

2

Bueno, obviamente, una forma de parametrizar tipos es utilizar el preprocesador, por ejemplo:

#define DIVIDE_FUNC(type) divide_##type 
#define DIVIDE_CALL(type, a, b) DIVIDE_FUNC(type)((a), (b)) 
#define DIVIDE_DECL(type) type DIVIDE_FUNC(type)(type a, type b) 
#define DIVIDE_IMPLEMENTATION DIVIDE_DECL(DIVIDE_TYPE) { return a/b; } 

#define DIVIDE_TYPE int 
DIVIDE_IMPLEMENTATION 
#undef DIVIDE_TYPE 
#define DIVIDE_TYPE double 
DIVIDE_IMPLEMENTATION 

#include <stdio.h> 

int main (void) { 
    int i = 5, j = 2; 
    (void) printf("int %d/%d = %d\n", i, j, DIVIDE_CALL(int, i, j)); 
    (void) printf("double %d/%d = %f\n", i, j, DIVIDE_CALL(double, i, j)); 
    return 0; 
} 

Esto implementa dos funciones: divide_double y divide_int. En un ejemplo más complejo (realista), la implementación podría estar en un archivo de compilación separado que se compila (o se incluye) por separado para cada tipo con un DIVIDE_TYPE diferente definido.

La desventaja en comparación con los genéricos reales es que las implementaciones para diferentes tipos no se generan automáticamente, es decir, DIVIDE_CALL(mytype, x, y) no genera la implementación de mytype. (Por supuesto, esto podría organizarse con algunas secuencias de comandos relativamente simples, pero entonces se podría argumentar que ya no se está usando C y existen lenguajes con genéricos incorporados más bonitos) =)

En cualquier caso, esto puede funcionar para estructuras de datos y tal, donde se desea el tipo de datos real (no un puntero void *).

+1

El primer libro en C++ de Stroustrup no tenía plantillas. Había un ejemplo de cómo definir una lista genérica usando macros, era similar a su código. – liori

0

Algo como esto: https://github.com/10098/breakout/tree/master/dl_list/

Es una implementación de una lista doblemente enlazada que escribí como un ejercicio. Lo uso en un simple juego tipo breakout.

+0

, pero ¿cómo se obtiene el tipo de datos para cada nodo? –

+0

Yo no. Todas las rutinas que realizan operaciones en la lista vinculada son de tipo agnóstico. Si alguien necesita algo específico del tipo, esto se puede hacer a través de funciones de devolución de llamada que arrojarían punteros vacíos a los tipos necesarios y realizarían las operaciones necesarias. No digo que sea el mejor enfoque, por supuesto. Tal vez alguien me indique una mejor implementación. –

Cuestiones relacionadas