Одинаковый набор инструкций, разные типы. Как справиться? - PullRequest
0 голосов
/ 10 марта 2012

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

Инструкции, которые мне нужно выполнить с данными, в основном одинаковы, отличается только тип: возможно, файл содержит int s, double s или значения struct X. Независимо от типа операции будут идентичны; как я могу избежать повторения кода? В C ++ я бы справился с этим с помощью шаблонов. Как это обычно обрабатывается в C?

Ответы [ 4 ]

0 голосов
/ 10 марта 2012

Новый стандарт C, C11, имеет обобщенные выражения типов, которые вы можете использовать для этого. Компилятор C11 пока не сильно поддерживается, но, например, последняя версия clang имеет _Generic. Вы также можете использовать P99 для эмуляции функций C11 поверх аналогичных расширений, предоставляемых gcc.

0 голосов
/ 10 марта 2012

Решение этой проблемы очевидно с современными объектно-ориентированными языками - вы создаете объект каждого типа, который реализует интерфейс (или посредством наследования) действий, которые вы хотите выполнить.

Вы не можете сделать это в C, потому что язык не наивно поддерживает объектно-ориентированное, но вы можете «воспроизвести» ту же функциональность вместо того, чтобы позволить компилятору сделать это за вас. Для этого вам нужно использовать уровень косвенности, в частности, вам нужно использовать указатели функций.

Так что (в качестве примера) одно из действий, которое вы можете предпринять, - прочитать значения из файла. Одной из ваших переменных будет указатель на функцию, которая принимает в качестве параметра файл и переменную типа void (это изменится для каждой функции, которую вы пишете.) Напишите функцию для каждого из ваших типов, а затем при назначении типа выполнения функция для использования в зависимости от типа файла.

0 голосов
/ 10 марта 2012

В сферах действительно уродливых уловок препроцессора, если вы хотите скопировать тело функции для разных типов, но сохранить «структуру» кода идентичной, вы можете сделать что-то вроде этого:

foo.hc

#define YNAME(X) foo_ ## X
#define XNAME(X) YNAME(X)
#define NAME XNAME(TYPE)

int NAME(FILE* f) {
    TYPE myvar;
    ...
    return whatever;
}

foo.c

#define TYPE int
#include "foo.hc"
#undef TYPE

#define TYPE double
#include "foo.hc"
#undef TYPE

Этот foo.c будет предварительно обработан для:

int foo_int(FILE* f) {
    int myvar;
    ...
    return whatever;
}

int foo_double(FILE* f) {
    double myvar;
    ...
    return whatever;
}

Все, что вам нужно сделать в вашемОсновным циклом обработки является отправка нужной функции в зависимости от типа вашего файла.Простой оператор switch может работать довольно хорошо, может работать и массив указателей на функции.

0 голосов
/ 10 марта 2012

В C вы будете делать это через то, что вы надеетесь избежать - повторяя код.Как вы знаете, C ++ делает это более удобным для шаблонов, однако это просто простой способ повторить код и основать его на другом типе.

Что-то, что может подойти вам, - это предоставить другойфункции класса, но не вызывать их напрямую.Вместо этого на основе командной строки определите, какие функции будут обрабатывать ваши данные, и назначьте их указателям на функции.Затем ваш цикл управления просто вызовет функции обработки, используя эти указатели.Очевидно, это будет включать в себя все, что вы делаете с данными, но вы также можете решить использовать отдельные функции ввода в зависимости от типа данных.

Редактировать: Как говорит Мэт, есть типы типов, которые хорошо продвигаются, и поэтому один блоккод будет работать нормально.Я подозреваю, что именно поэтому ваше назначение включает в себя работу с некоторым типом структуры.

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