С препроцессором во время выполнения? - PullRequest
1 голос
/ 23 марта 2010

Я хочу сделать конкатенацию токена, но я хочу сделать это с содержимым переменной, а не с ее именем. как это. <pre> <code>#define call_function(fun, number) fun##_##number ()

while (i

но я даю fun_number (), я хочу дать fun_1, fun_2 и так далее ...

как это сделать?

О функциональных указателях.

Я иду, чтобы обработать пользовательский ввод символов ascii, я могу выбрать & * ^> <и так далее до десяти токенов. </p>

чтобы обработать его в массиве с указателем на функцию, мне нужно создать массив из 127 блоков только для десяти токенов!

это слишком дорого! спасибо за все ответы.

Заранее спасибо !!!

Ответы [ 6 ]

5 голосов
/ 23 марта 2010

вам нужно создать массив указателей на функции и вызвать через этот массив.

 typedef int (*pfunc)(int);
 pfunc[] = {func0,func1,func2,func3};
 for(int i = 0; i < 3; i++)
 {
     pfunc[i](arg);
  }

Я уверен, что у меня где-то неправильный синтаксис - проверьте http://www.newty.de/fpt/fpt.html

5 голосов
/ 23 марта 2010
#define call_function(fun, member) fun##_##number ()
// ------------------------^
// should be "number".

Несмотря на это, вы получите только fun_i. Вы не можете вызывать макросы препроцессора во время выполнения, потому что они используются только в предварительной обработке (даже перед анализом и компиляцией).

Вам необходимо расширить цикл вручную.

call_function(fun, 0);
call_function(fun, 1);
call_function(fun, 2);
call_function(fun, 3);
call_function(fun, 4);
call_function(fun, 5);
call_function(fun, 6);
call_function(fun, 7);
call_function(fun, 8);
call_function(fun, 9);

Или используйте __COUNTER__ (требуется gcc ≥ 4.3):

#define CONCAT3p(x,y,z) x##y##z
#define CONCAT3(x,y,z) CONCAT3p(x,y,z)
#define call_function(func) CONCAT3(func, _, __COUNTER__)()

call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
call_function(fun);
2 голосов
/ 23 марта 2010

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

Взгляните на указатели функций - это может вам помочь!

1 голос
/ 23 марта 2010

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

1 голос
/ 23 марта 2010

Попробуйте (вдохновлено комментарием Боба). Вы можете просто индексировать в массив fns вместо использования ключа.

#include <stdio.h>
#include <stdlib.h>

int fn_0() { printf("0\n"); }
int fn_1() { printf("1\n"); }
int fn_2() { printf("2\n"); }
int fn_3() { printf("3\n"); }
int fn_4() { printf("4\n"); }
int fn_5() { printf("5\n"); }

int main(char **argv, int argc)
{

  int (*fns[6])(void);
  int i;

  fns[0] = *fn_0;
  fns[1] = *fn_1;
  fns[2] = *fn_2;
  fns[3] = *fn_3;
  fns[4] = *fn_4;
  fns[5] = *fn_5;

  for(i = 0; i < 6; ++i)
    fns[i]();

}

Конечно, если ваш массив разреженный (не непрерывный набор целых чисел), то вам, вероятно, следует использовать переключатель.

0 голосов
/ 24 марта 2010

В ответ на вашу проблему с указателями на функции - все, что вам нужно сделать, чтобы решить проблему, - это создать отображение из десяти интересующих вас символов в числа от 1 до 10:

#include <string.h>

typedef int (*funcptr_t)(int);

funcptr_t func_table[11] = { func_unknown, func_ampersand, func_asterisk, func_circumflex, /* ... all the rest here */ };

/* get_index: Returns a value from 1 to 10 if c is in the allowed set, or 0 if not */
static int get_index(char c)
{
    static const char * const lookup_table[] = "&*^><!@#$%";
    char *p = strchr(lookup_table, c);

    return p ? (p - lookup_table) + 1 : 0;
}

Затем, чтобы вызвать функцию, вы можете просто сделать:

result = func_table[get_index(somechar)](arguments);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...