2010-11-20 8 views
7

HII,родовое реализация в C

В то время как я был реализации некоторых программ для присвоения класса, он просто ударил меня, как это было бы осуществить то же самое в общем виде с использованием C.

I что мы должны использовать указатели и функции void, но я просто застрял в том, как это сделать. Пожалуйста, дайте мне пример, который прост и демонстрирует использование.

Как, как реализовать функцию сравнения для реализации сравнительную рода, или для вставки в связный список, где каждый узел имеет элемент разнообразного типа и т.д ...

PS: Любые ссылки на другие вопросы или статьи полезны и приветствуются.

+0

Вы имеете в виду "generics"? http://download.oracle.com/javase/tutorial/extra/generics/index.html –

+2

Вы переходите на C++ и используете шаблоны, вот как. – Puppy

+2

@deadMG: Я знаю, как программировать то же самое, используя generics в C++. Я хотел знать, как это сделать на C. – Flash

ответ

2

Вы можете использовать указатели void *, а затем много отливок. Обратите внимание, что вам нужно будет сохранить тип каким-то образом, чтобы вернуться к исходному элементу, поэтому он не совсем общий, но примерно так же близко, как и вы.

Очевидно, что это своего рода код очень подвержены ошибкам

2

Ну, очевидно, один из способов параметризуем типов является использование препроцессора, например:

#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; 
} 

Это реализует две функции: divide_double и divide_int. В более сложном (реалистичном) примере реализация может быть в отдельном файле компиляции, который скомпилирован (или включен) отдельно для каждого типа с другим DIVIDE_TYPE.

Недостатком по сравнению с реальными генериками является то, что реализации для разных типов не генерируются автоматически, то есть DIVIDE_CALL(mytype, x, y) не приводит к созданию реализации для mytype. (Конечно, это может быть организовано с некоторыми относительно простыми сценариями, но тогда можно утверждать, что вы больше не используете C, и есть языки с более красивыми встроенными генериками. =)

В любом случае это может работать для структур данных и таких, где желателен фактический тип данных (не указатель void *).

+1

В первой книге Custre Stroustrup не было шаблонов. Был пример того, как определить общий список с помощью макросов, он был похож на ваш код. – liori

0

Что-то вроде этого: https://github.com/10098/breakout/tree/master/dl_list/

Это реализация дважды связанного списка, который я написал в качестве упражнения. Я использую его в простой прорывной игре.

+0

, но как получить тип данных для каждого узла? –

+0

Я этого не делаю. Все подпрограммы, выполняющие операции в связанном списке, являются агностическими. Если кому-то нужно что-то конкретное по типу, это можно сделать с помощью функций обратного вызова, которые бы отображали указатели void на нужные типы и выполняли необходимые операции. Я не говорю, что это лучший подход. Может быть, кто-то укажет мне на лучшую реализацию. – 2010-11-20 13:35:21

Смежные вопросы