2011-07-18 61 views
6

的價值我有數以百計的常量的定義爲宏.h文件:得到一個常數C

#define C_CONST_NAME Value 

我需要的是一個可以動態獲取其中的一個常量的值的函數。

需要的函數頭:

int getConstValue(char * constName); 

是,即使可能在C langage?

----編輯

感謝您的幫助,那是快:)

,因爲我想有我需要的不是靈丹妙藥。

其實我用的是頭文件被生成的「SCADE:http://www.esterel-technologies.com/products/scade-suite/

在解決方案,我從@克里斯得到的是使用一些Python生成C代碼,做的工作。

現在,我來做一些優化,以找到恆定的名稱。我有超過5000個常量O(500^2)

我也在看「X宏」我第一次聽說,它在C中工作,因爲我不允許使用C++ 。

謝謝

+0

常量是預處理器而不是編譯器常量,您必須移動到對象空間,例如,一個[地圖](http://en.wikipedia.org/wiki/Map_(C%2B%2B)) –

+1

不知道爲什麼你需要這樣做,但它不可能動態。上面定義的'常量'實際上並不存在於您的程序源代碼的編譯之後。它們被預處理器替換爲它們的實際值。 – Perception

+1

不要使用定義的常量。使用const值的關聯數組。 –

回答

4

你在這裏。您需要添加一行爲每個新的常量,但它應該給大家介紹的宏是如何工作的一個想法:

#include <stdio.h> 

#define C_TEN 10 
#define C_TWENTY 20 
#define C_THIRTY 30 

#define IFCONST(charstar, define) if(strcmp((charstar), #define) == 0) { \ 
    return (define); \ 
} 

int getConstValue(const char* constName) 
{ 
    IFCONST(constName, C_TEN); 
    IFCONST(constName, C_TWENTY); 
    IFCONST(constName, C_THIRTY); 

    // No match                                                        
    return -1; 
} 

int main(int argc, char **argv) 
{ 
    printf("C_TEN is %d\n", getConstValue("C_TEN")); 

    return 0; 
} 

我建議你運行gcc -E filename.c看到這個代碼做什麼GCC。

6

C不能爲你做這個。您需要將它們存儲在不同的結構中,或者使用預處理器來構建您需要的數百個if語句。像Cogflect可能會有所幫助。

3

預處理完成後,C預處理器宏(即由#define語句命名的某個內容)不再存在。一個程序不知道這些宏的名字,也沒有任何方法可以引用它們。

如果您告訴我們您要執行的任務,我們可能會建議一種替代方法。

1

這就是X-宏用於:

https://secure.wikimedia.org/wikipedia/en/wiki/C_preprocessor#X-Macros

但是如果你需要一個字符串映射到一個常數,你將有字符串表示陣列中搜索字符串,這是O(n^2)

+0

你從哪裏得到O(n^2)?即使你做了線性搜索,你也只需要O(n)。使用std :: map將其減少到O(log n)。 – zennehoy

+0

@zennehoy好吧,它不是'O(n^2)',它是'O(n * m)'。比較字符串是'O(n)'而不是'O(1)'。 –

+0

我第一次聽說「X-Macros」 – azalsup

1

C中沒有這樣的功能。但是,您可以使用工具(如doxygen)將源代碼中的所有#define提取到可在運行時讀取的數據結構中(doxygen可將所有宏定義存儲到XML )。

+0

事實上,我使用的頭文件是從SCADE生成的,我也有一個名爲constantes的xml版本。 所以我可以使用python來生成我的c代碼。謝謝 – azalsup

+0

@azalsup:不是在python中生成C代碼,而是生成一個yacc語法,運行yacc(或[GNU Bison](http://www.gnu.org/software/bison/))來生成高度優化的C代碼做匹配。實際上,該工具的'lex'部分可能就是您所需要的。 –

1

,也許可以與gperf,其生成使用perfect hash function查找功能做到這一點。

創建類似於以下一個文件,並與-t選項運行的gperf:

struct constant { char *name; int value; }; 
%% 
C_CONST_NAME1, 1 
C_CONST_NAME2, 2 

的gperf將輸出C(或C++)代碼,不會查找在恆定時間,指針返回到鍵/值對或NULL。

如果您發現您的關鍵字集對於gperf來說太大,請考慮使用cmph來代替。