«Динамическое» использование переменной в C? - PullRequest
1 голос
/ 14 мая 2011

Привет, если у меня есть следующая функция:

#define SIZE 100
double a[SIZE];
double b[SIZE];

double a_function(int index1, int index2)
{
    switch(index1)
    {
        case 1:
            return a[1]*a[2]*a[5]*a[3];
        case 2:
            return a[6]*cos(a[77])*exp(a[95]);
        // .............. MUCH MORE CASES 
        // ALWAYS USING ONLY VALUES OF ARRAY a
        case 100:
            return exp(a[20])*sin(a[21]);
    }
}

Я хочу добиться следующего: index2 находится в диапазоне от 0 до SIZE-1, а затем я хочу «заменять» каждые a[ index2 ] используя b[ index2 ] в КАЖДОМ случае, не изменяя конструкцию switch / case.Кроме того, a и b нельзя изменить, поэтому они доступны только для чтения!

Краткий пример этого:
a_function(2, index2) для index2! = {6, 77, 95} -> return a[6]*cos(a[77])*exp(a[95]);

a_function(2, 6) -> возвращает b[6]*cos(a[77])*exp(a[95]);

Есть идеи, как это сделать?Возможно, с помощью какой-нибудь вспомогательной функции или с помощью «шаблонов»?Большое спасибо заранее!

Ответы [ 3 ]

4 голосов
/ 14 мая 2011

Я думаю, вам нужно сделать макрос для этого

#define X(n) ((index2==n)?(b[n]):(a[n]))

double a_function(int index1, int index2)
{
   switch(index1)
    {
        case 1:
            return X(1)*X(2)*X(5)*X(3);
        case 2:
            return X(6)*cos(X(77))*exp(X(95));
        ...
        case 100:
           return exp(X(20))*sin(X(21));
   }

}

2 голосов
/ 14 мая 2011

Похоже, у вас есть

{
    for (int j=0; j<SIZE; ++j) {
        a_function(index1, j);
    }
}

Так почему бы не использовать

double c[SIZE];

double a_function(double c[], int index1)
{
    switch(index1)
    {
        case 1:
            return c(1)*c(2)*c(5)*c(3);
        ...
    }
}

{
    double c[SIZE];
    for (int i=SIZE; i--; ) {
        c[i] = a[i];
    }

    for (int j=0; j<SIZE; ++j) {
        c[j] = b[j];
        ... = a_function(c, index1);
        c[j] = a[j];
    }
}

PS - Какой бы метод вы ни использовали, ваш гигантский коммутатор может быть лучше реализован в виде таблицы поиска указателей на функции.

typedef double (*transform_t)(double*);

double transform1(double* c) { return c[1]*c[2]*c[5]*c[3]; }
double transform2(double* c) { return c[6]*cos(c[77])*exp(c[95]); }
...
double transform100(double* c) { return exp(c[20])*sin(c[21]); }

transform_t transforms[100] = {
    transform1,
    transform2,
    ...
    transform100,
};


{
    double c[SIZE];
    for (int i=SIZE; i--; ) {
        c[i] = a[i];
    }

    ...

    for (int j=0; j<SIZE; ++j) {
        c[j] = b[j];
        ... = (transforms[index1])(c);
        c[j] = a[j];
    }
}

Обновление : я только что заметил, что «a и b нельзя изменить, поэтому они доступны только для чтения!».Скорректировано.

Обновление : Добавлено предложение альтернативы оператору переключения.

0 голосов
/ 14 мая 2011

Вот как:

    #define SIZE 100
     double a[SIZE];
     double b[SIZE];

     double a_function(int index1, int index2)
     {
switch(index1)
{
    double *choice = (index2 != 6)?a:b;          <<< set choice
    case 1:
        return a[1]*a[2]*a[5]*a[3];               
    case 2:
        return choice[6]*cos(a[77])*exp(a[95]);   <<< use choice
    // .............. MUCH MORE CASES 
    // ALWAYS USING ONLY VALUES OF ARRAY a
    case 100:
        return exp(a[20])*sin(a[21]);
}

}

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