общая реализация в C - PullRequest
       1

общая реализация в C

7 голосов
/ 20 ноября 2010

Hii,

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

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

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

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

Ответы [ 3 ]

2 голосов
/ 20 ноября 2010

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

#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 *).

2 голосов
/ 20 ноября 2010

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

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

0 голосов
/ 20 ноября 2010

Примерно так: https://github.com/10098/breakout/tree/master/dl_list/

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...