2010-03-23 70 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);