Вопрос

в моем проекте на языке Си у меня есть пять разных функций (с одинаковым именем), которые реализуют один алгоритм, но по-разному.Во время компиляции мне нужно выбрать только одну из этих функций.Могу ли я реализовать это с помощью #define и куча других #ifndef?Есть ли лучшие способы сделать это?

Это было полезно?

Решение

Вероятно, более элегантным подходом было бы определить их с 5 разными именами (например, f1, f2, f3, f4, f5), но всегда вызывать функцию, используя одно и то же другое имя (например, f). Затем скомпилируйте что-нибудь вроде:

gcc -Df=f1

Это скомпилирует любые вызовы f () как вызов f1 ().

Другие советы

ДА.Все, что вы делаете, это указываете это в коде:

#if defined(FUNC1)
    ...func1 here
#elif defined(FUNC2)
    ...func2 here
...ect. ect.
#endif

А затем, когда вы компилируете, добавьте опцию gcc -DFUNCX, например:

gcc -DFUNC1 -o myprogram myfile.c

Затем вы можете выбрать, в какой функции выполнять компиляцию, изменив значение, введенное в параметр -D.Это очень распространенная практика.

У вас не может быть двух разных функций с одинаковым именем, определенных в одной единице перевода.

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

gcc -o testsort main.c bubble.c
gcc -o testsort main.c merge.c
gcc -o testsort main.c radix.c

Где любой из bubble.c , merge.c , radix.c (и другие) имеет функцию с таким же именем:

int sort(int *data, size_t len) { /* ... */ }

В Си это единственный способ, которым я знаю, как это делать. С ++ тебе повезет.

Если у вас есть источник для функций в отдельных файлах (для моего примера, в f1.c и f2.c), то эта схема работает:

$ cat so.c
#define STRINGIZER(x) #x
#define HEADER(x) STRINGIZER(x)

#include HEADER(SOURCE)

int main(void)
{
    return(function());
}
$ cat f1.c
static int function(void)
{
    return(1);
}
$ cat f2.c
static int function(void)
{
    return(2);
}
$

Тогда я могу скомпилировать так:

$ gcc -DSOURCE=f1.c -o so1 so.c
$ gcc -DSOURCE=f2.c -o so2 so.c

Обратите внимание на использование оператора stringize и танца с двойным макросом - это стандартная идиома для препроцессора Standard C. Это позволяет мне не помещать кавычки в командную строку компилятора C; подумайте, насколько сложнее было бы использовать, если бы вам пришлось писать:

$ gxx -DSOURCE='"f1.c"' -o so1.c

Результаты выполнения so1 и so2 были следующими:

$ ./so1; echo $?
1
$ ./so2; echo $?
2
$

Здесь показан альтернативный способ достижения желаемого результата без каких-либо #ifdef строк.

Макросы ifndef кажутся единственной возможностью во время компиляции.

Вы можете попробовать использовать функцию ptrs во время выполнения.

Просто подумал, что вы можете создать каждую функцию в отдельном файле и связать соответствующую функцию, когда захотите. Никаких макросов, просто переключатель Makefile. Таким образом, вы сохраняете одну и ту же сигнатуру и решаете во время соединения, какую реализацию использовать. Ссылка algo1.o или ссылка algo2.o ...

Если бы я был тобой, у меня было бы 5 разных имен функций, а затем использовал бы оператор if, чтобы выяснить, какую из них вызывать во время выполнения.

C не имеет перегрузки (оператор или иным образом), поэтому другого способа сделать это нет. Боюсь, вы застряли с командами препроцессора.

если вы настаиваете на использовании C, вы можете использовать указатели на функции, но я бы посоветовал вам использовать C ++ и полиморфизм, это избавит вас от проблем:)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top