我想實現這樣的事情:陣列中的#define
#define MACRO(x) {PORTB=0,PORTC=0,PORTD=0}
MACRO(0); //This would get replaced by PORTB=0;
MACRO(1); //PORTC=0;
MACRO(2); //PORTD=0;
我想創建一個「宏陣列」。我會傳入一個索引,它會返回正確的代碼。
這可能嗎?
編輯:
如果有幫助,PORTB,PORTC和PORTD都是#define語句。
我想實現這樣的事情:陣列中的#define
#define MACRO(x) {PORTB=0,PORTC=0,PORTD=0}
MACRO(0); //This would get replaced by PORTB=0;
MACRO(1); //PORTC=0;
MACRO(2); //PORTD=0;
我想創建一個「宏陣列」。我會傳入一個索引,它會返回正確的代碼。
這可能嗎?
編輯:
如果有幫助,PORTB,PORTC和PORTD都是#define語句。
它可以通過預處理器來完成,但它可以說是醜陋的。
#define MACRO_CASE0 PORTB = 0
#define MACRO_CASE1 PORTC = 0
#define MACRO_CASE2 PORTD = 0
#define MACRO(X) MACRO_CASE##X
也看看Boost.Preprocessor庫。 (它適用於C和C++)。
更新:後與Jonathan Leffler討論(見下文),我覺得有義務更新爲新的C程序員規勸答案不要濫用(強大的,但髒)技術如上所示。
如果你 - 作爲OP要求 - 想要傳遞給它的索引,它將返回正確的代碼,那麼你需要求助於預處理器編程。然而,如果你想要做的是執行基於某些條件的不同代碼,並且如果條件是編譯時常量,那麼希望它沒有運行時間開銷,那麼以下方法不僅更清潔,而且更多靈活,因爲它也允許傳遞運行時間值。現在
/* '#include' this definition in any file where you want to use it. */
static inline void
do_the_right_thing(const int selector)
{
switch (selector)
{
case 0:
PORTB = 0;
break;
case 1:
PORTC = 0;
break;
case 2:
PORTD = 0;
break;
default:
assert(!"cannot do the right thing: invalid selector");
}
}
,在你的代碼,如果你寫
do_the_right_thing(1); /* selector is a compile-time constant */
一個體面的編譯器優化適當啓用相比,使用宏將產生的開銷。但是,你也可以寫
do_the_right_thing(rand() % 3); /* selector is a run-time expression */
,編譯器會插入一些快速切換代碼選擇在運行時適當的操作。
這將做任務,但它並沒有延長或概括很優雅:
#define MACRO(x) (((x) == 0) ? PORTB=0 : ((x) == 1) ? PORTC=0 : PORTD=0)
...並且效率不高(OP代碼看起來像某些微控制器的代碼)。 – 2014-09-24 14:25:19
@MichaelWalz:什麼是低效?這是問題中顯示的示例的編譯時常量。首先這不是一個好主意,但它確實按照要求做了什麼。 – 2014-09-24 14:26:43
實際上,它**效率很高,因爲編譯器會優化所有內容。宏MACRO(0)的預處理器輸出是(((0)== 0)?B = 0:((0)== 1)?C = 0:D = 0);' – 2014-09-24 14:40:14
+1:與我的[答](http://stackoverflow.com/a/26019383/15168)相比,這有一個優點,它只能用於整數常量的參數;它也有缺點。 – 2014-09-24 14:32:29
@JonathanLeffler真的,但誰會想用一個整數索引一個數組?如果你想,你也可以使用符號名稱。 – 5gon12eder 2014-09-24 14:34:43
這取決於你是否想要動態選擇索引:'if(i> = 0 && i <= 2)MACRO(i);'或者類似的東西。如果它是一個微控制器,我懷疑你不想要那個,但是在代碼中我看不到'MACRO(1);'比'PORTC = 0'更清晰 - 實際上它少了很多對我清楚。但是,這可能部分地成爲問題的假象。如果宏背後的代碼是選擇PORTB,PORTC或PORTD中的一個用於賦值的LHS(因此用法是「MACRO(1)= 0」),那麼我建議不起作用 - 正如我的'不擴展或概括'評論。 – 2014-09-24 14:41:38