2014-09-05 71 views
0

我有一大堆的#define語句,所有看起來像這樣的#define d,0,它們含有從公元了一封信,從0-8的數字,用逗號分隔的宏。超載有兩個參數

現在我正在嘗試創建一個宏,如下所示:Overloading Macro on Number of Arguments,但這可以適用於我的情況。這個網站上的宏只適用於帶有一個參數的#define,而我的有兩個。

這是我目前有:

#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME 
#define TEST_MACRO(...)  GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__) 

#define _TEST_MACRO_8(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7, letter8, number8)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8)) 
#define _TEST_MACRO_7(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6, letter7, number7)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7)) 
#define _TEST_MACRO_6(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5, letter6, number6)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6)) 
#define _TEST_MACRO_5(letter1, number1, letter2, number2, letter3, number3, letter4, number4, letter5, number5)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5)) 
#define _TEST_MACRO_4(letter1, number1, letter2, number2, letter3, number3, letter4, number4)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3) | (1 << number4)) 
#define _TEST_MACRO_3(letter1, number1, letter2, number2, letter3, number3)   (PORT##letter1 |= ((1 << number1) | (1 << number2) | (1 << number3)) 
#define _TEST_MACRO_2(letter1, number1, letter2, number2)   (PORT##letter1 |= ((1 << number1) | (1 << number2)) 
#define _TEST_MACRO_1(letter1, number1)   (PORT##letter1 |= (1 << number1)) 

如果我做的:

#define ONE D, 0 
#define TWO D, 1 
#define THREE D, 2 

TEST_MACRO(ONE); //Error: macro _TEST_MACRO_2 requires 4 arguments but only 2 given 
TEST_MACRO(ONE,TWO); //Error: macro _TEST_MACRO_4 requires 8 arguments but only 4 given 
TEST_MACRO(ONE,TWO,THREE); //Error: macro _TEST_MACRO_6 requires 12 arguments but only 6 given 

這裏有什麼問題嗎?我該如何解決它?

此致敬禮!

編輯:

澄清一下,這裏是哪裏,這是會得到中使用的背景我編程8位AVR微控制器。並且知道我有這樣定義的針腳:#define PIN1 A,0,其中A代表PINs字母,並且代表PIN號碼。

如果我有一大堆這樣定義,當我想改變它們的一些設置時,我必須一個接一個地手動完成它,就像這樣:PIN_HIGH(PIN1);PIN_HIGH(PIN2);PIN_HIGH(PIN3)並且有更多的代碼,亂。

所以我正在尋找一種方法來處理一個宏:PIN_HIGH(PIN1,PIN2,PIN3);。當我將它們傳遞給一個宏時,PIN1,PIN2,PIN3字母匹配也很重要,因爲有時我可以將該pin轉移到其他字母。

有關如何完成此任務的任何建議都非常值得歡迎!

+0

我想不出一個更好的方式來做到這一點......任何改進都超過歡迎! – user1806687 2014-09-05 21:30:11

+0

它更容易閱讀:PIN_HIGH(PIN_1,PIN_2,PIN_8);比PORTA | =((1 << PA1)|(1 << PA2)|(1 << PA8)),並且跟蹤所有PORTS和DDRS,而PINS只是做了很多工作而已,至少在我的看法。不過謝謝你的幫助。 – user1806687 2014-09-05 21:36:06

+0

我確定你可以做得比第二個例子更乾淨,而且幾乎所有的東西都比猜測要看到哪個宏實際上正在擴展更好。但正如我所說,我不會成爲與之合作的人,很明顯這是你的決定。然而,你*確實問過。 :-) – 2014-09-05 21:39:31

回答

1

字符。所以,我建議遵循下面的方式。

#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, NAME, ...) NAME 
#define TEST_MACRO(letter,...) (PORT##letter |= GET_MACRO(__VA_ARGS__, _TEST_MACRO_8, _TEST_MACRO_7, _TEST_MACRO_6, _TEST_MACRO_5, _TEST_MACRO_4, _TEST_MACRO_3, _TEST_MACRO_2, _TEST_MACRO_1) (__VA_ARGS__)) 

#define _TEST_MACRO_8(number1, number2, number3, number4, number5, number6, number7, number8) \ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) | (1 << number8) 
#define _TEST_MACRO_7(number1, number2, number3, number4, number5, number6, number7)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) | (1 << number7) 
#define _TEST_MACRO_6(number1, number2, number3, number4, number5, number6)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) | (1 << number6) 
#define _TEST_MACRO_5(number1, number2, number3, number4, number5)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) | (1 << number5) 
#define _TEST_MACRO_4(number1, number2, number3, number4)\ 
    (1 << number1) | (1 << number2) | (1 << number3) | (1 << number4) 
#define _TEST_MACRO_3(number1, number2, number3)\ 
    (1 << number1) | (1 << number2) | (1 << number3) 
#define _TEST_MACRO_2(number1, number2)\ 
    (1 << number1) | (1 << number2) 
#define _TEST_MACRO_1(number1)\ 
    (1 << number1) 


TEST_MACRO(D, 1); 
TEST_MACRO(D, 0, 1); 
TEST_MACRO(D, 0, 1, 2); 

#define ONE (D, 0) 
#define TWO (D, 1) 
#define THREE (D, 2) 
#define CAR(a,b) a 
#define CDR(a,b) b 
#define F(x) CAR x 
#define R(x) CDR x 
#define TEST_MACRO_WRAP(...) TEST_MACRO(__VA_ARGS__) 
TEST_MACRO_WRAP(F(ONE), R(ONE)); 
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO)); 
TEST_MACRO_WRAP(F(ONE), R(ONE), R(TWO), R(THREE)); 
+0

我真的很喜歡這個,但是有沒有辦法通過全** ** **,**兩**,**三** **定義,而不必通過其中的一部分,如來自** ONE的字母和數字**,然後只有**兩個**的數字。然後,是否有可能檢查一個宏是否所有傳遞的字母都是相同的,如果它們不是,則拋出#error?謝謝! – user1806687 2014-09-06 10:55:44

+0

這個檢查是否所有字母都是相同的,因此我必須在編譯時進行,因爲我的資源非常有限。再次感謝你! – user1806687 2014-09-06 10:59:13

+0

@ user1806687無法在預處理器中進行非數字相等的比較。 – BLUEPIXY 2014-09-06 11:04:05

0

ONETWOTHREE都擴大TEST_MACRO之前立即展開,所以當你說TEST_MACRO(ONE),該__VA_ARGS__宏ARG設置爲D, 0(的ONE擴展),這意味着你叫_TEST_MACRO_2,因爲這是兩個論據。

因爲你總是希望偶數的參數,你可以定義TEST_MACRO爲:表示該端口沒有比第一使用其他

#define TEST_MACRO(...)  GET_MACRO(__VA_ARGS__, _TEST_MACRO_4, ERROR, _TEST_MACRO_3, ERROR, _TEST_MACRO_2, ERROR, _TEST_MACRO_1, ERROR) (__VA_ARGS__) 
#define ERROR(...) #error "Odd number of arguments to TEST_MACRO" 
+0

我會試試看tommorow並讓你知道。因爲這裏晚了,我住在哪裏。 – user1806687 2014-09-05 21:32:34

+0

'#錯誤'錯誤。 – BLUEPIXY 2014-09-06 11:07:43