2010-03-23 71 views
1

我想做一个令牌串接,但我想用变量的内容来做这件事,而不是它的名字。喜欢这个。 C预处理器在运行时?

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

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

,但我给fun_number(),我想给fun_1,fun_2,等等...

怎么办呢?

关于函数指针。

我正在散步以处理ascii caracters上的用户输入,我的选项是& * ^> <等等,最多10个标记。

来处理它在一个具有函数指针的数组中,我需要创建一个只有十个令牌的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 2010-03-23 20:08:38

+0

不应该有可能有一个函数指针或一些数组?自从我考虑过C或C++代码以来,这已经过时了 – Bob 2010-03-23 20:10:09

+1

请注意,虽然CPP不提供循环,但它不是唯一的预处理器。这只是内置的唯一一个。您可以使用更强大的预处理器(如m4)在编译时执行更复杂的工作。 – Ken 2010-03-23 20:11:17

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);