Как построить гибкую иерархию кода

Итак, у меня есть алгоритм, состоящий из параметров A, B, C и D и операций X, Y и Z. Цель состоит в том, чтобы написать код, который будет проверять все комбинации (в пределах определенного диапазона) A, B, C и D, и, возможно, изменить операции X, Y или Z.

Это было бы просто, если бы это было просто вопросом размещения переменных в определенном диапазоне. Но так как я хочу также менять операторов, это не так просто.

Моя идея - написать код, который бы охватывал все комбинации. Например, давайте рассмотрим, что есть только два параметра (A и B) и что диапазон одинаков для обоих: [1,2], целые числа. Код будет создавать (и, если возможно, выполнять) 4 различных исполняемых файла, соответствующих использованию алгоритма с:

A = 1, B = 1
A = 1, B = 2
A = 2, B = 1
A = 2, B = 2

Теперь добавляем операторов. Например, мы выбираем предыдущий пример и добавляем операцию X, где это может быть [+,-]. Результирующий набор:

A = 1, B = 1, X = +
A = 1, B = 2, X = -
A = 2, B = 1, X = +
A = 2, B = 2, X = -
A = 1, B = 1, X = -
A = 1, B = 2, X = +
A = 2, B = 1, X = -
A = 2, B = 2, X = +

(Надеюсь, я написал все комбинации)

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

Возможно, это создаст древовидную структуру? Я не уверен, полезно ли это иметь (и выбираю первый пример):

|--Makefile
|--A1
|   |--B1
|   |   |--a.out
|   |--B2
|       |--a.out
|--A2
    |--B1
    |  |--a.out
    |--B2
        |--a.out

С помощью make я считаю, что могу добавить в код дополнительные переменные / операторы и легко перестроить все тесты. Кроме того, позволяет ли эта структура использовать функциональность заданий make для запуска нескольких потоков?

Спасибо

1 ответ

Решение

Метод, который я использовал в прошлом:

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

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv[]){
    if (argc != 3){ //takes just 2 numbers (for example purposes)
        fprintf(stderr, "Usage: prog num1 num2\n");
        return 1;
    }
    int a = (int)strtol(argv[1], (char**)NULL, 10);
    int b = (int)strtol(argv[2], (char**)NULL, 10);
    int c = a MySpecialOperation b;
    printf("%d %s %d = %d\n", a, MySpecialOperationText, b, c);
    return 0;
}

Вы быстро заметите, что MySpecialOperation а также MySpecialOperationText не определены. Это намеренно. (Также программа предполагает, что аргументы командной строки действительны.)

Теперь предположим, что вы хотите 4 программы, которые выполняют 4 основных арифметических действия. Напишите скрипт для компиляции вашей программы (это в BASh):

echo \#define MySpecialOperation \+ > tmp.c
echo \#define MySpecialOperationText \"plus\" >> tmp.c
cat myprogram.c >> tmp.c
gcc tmp.c -o addition_prog
echo \#define MySpecialOperation \- > tmp.c
echo \#define MySpecialOperationText \"minus\" >> tmp.c
cat myprogram.c >> tmp.c
gcc tmp.c -o subtraction_prog
echo \#define MySpecialOperation \* > tmp.c
echo \#define MySpecialOperationText \"times\" >> tmp.c
cat myprogram.c >> tmp.c
gcc tmp.c -o multiplication_prog
echo \#define MySpecialOperation \/ > tmp.c
echo \#define MySpecialOperationText \"divided by\" >> tmp.c
cat myprogram.c >> tmp.c
gcc tmp.c -o division_prog
rm tmp.c

Этот скрипт автоматически создает новый файл, записывает оператор препроцессора #define к нему, определяя ранее неопределенные переменные, затем добавляет исходный файл к нему. Теперь компилятор заменит MySpecialOperation с операцией (+,-,*, или же /) а также MySpecialOperationText с соответствующим словом, и код скомпилирует и выполнит эту операцию.

Другие вопросы по тегам