2010-03-23 3 views
1

Я хочу сделать конкатенацию Token, но я хочу сделать это с содержимым переменной, а не с ее именем. как это. Препроцессор C во время выполнения?

 
#define call_function(fun, number) fun##_##number()

while (i < 10) { call_function(fun, i); }

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

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

О функции указатели.

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

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

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

Заранее благодарен!

ответ

5
#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); 
+0

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

+0

Нельзя ли иметь массив указателей на функцию или что-то еще? Прошло много времени с тех пор, как я даже подумал о коде C или C++ – Bob

+1

Обратите внимание, что хотя CPP не предоставляет циклы, это не единственный препроцессор. Это единственный, который встроен. Вы можете использовать более мощный препроцессор, например m4, для выполнения более сложной работы во время компиляции. – Ken

2

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

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

5

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

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

1

Попробуйте это (вдохновленный комментарий Боба). Вы можете просто индексировать в массив 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](); 

} 

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

1

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

0

В ответ на ваш вопрос с указателями на функции - все, что вам нужно сделать, чтобы решить эту проблему, это создать отображение из десяти символов вы заинтересованы в числам от 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[] = "&*^><[email protected]#$%"; 
    char *p = strchr(lookup_table, c); 

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

Тогда для вызова функции, вы можете просто:

result = func_table[get_index(somechar)](arguments); 
Смежные вопросы