2011-02-27 89 views
0

我在C中實現了一個計算機模擬器,不接受使用條件的挑戰(例如,沒有if/else,switch/case,while/for等)。我正在模擬的硬件中有很多複用器,所以如果我可以使用條件三元邏輯運算器將會很好。所以,我的問題是:C編譯器是否使用三元邏輯運算符創建MUX邏輯,還是創建分支?三元邏輯和多路複用器邏輯之間的連接?

實施例:

int a, b, q, r; 
/* Ternary logic */ 
r = q ? a : b; 
/* MUX equivalent logic */ 
r = (q & a) | ((~q) & b) 
/* Branch equivalent logic */ 
if (q) r = a; else r = b; 

回答

4

三元運算符相當於一個分支:即,不是返回的值不評估。

我不知道你有多少約束,所以請注意,布爾運算符&&||不要評估它們的第二個參數,結果可以從第一個確定。 (注意,你所在的行「MUX」與其他兩個表達式沒什麼區別:它根據q中相應位的值選擇來自a或b的位,它不選擇a或b取決於q是否爲空;編輯:更糟糕的是:您正在使用!q而不是〜q ...)。

+0

1.我知道三元運算符相當於一個分支,如上所述。我問的是,「編譯器在彙編層面上生成了一個分支嗎?」 2.我沒有發現&&和||的任何用處布爾運算符到目前爲止。我會記住你的見解。我對你使用「空白」一詞感到困惑。但是你是對的,在大多數情況下,我應該切換到〜(這是一個簡單的1位值的例子,但我會編輯它)。 – Robz 2011-02-27 14:02:30

+0

@Robz:1.一般來說,是的。 – 2011-02-27 14:07:04

+0

1.是的(它不能評估其他分支)。 3.零 – AProgrammer 2011-02-27 14:40:04

1

C編譯器使用三元語句創建分支。

使用飛思卡爾的CodeWarrior IDE,我編譯下面的C程序:

int a, b, q, r;  
void main(void) {  
    a = 0;  
    b = 1;  
    q = 0;  
    r = q ? a : b;  
.. 
..  
} 

對應於三元語句的組件如下:

... 
LDX 0x1104 ; load val[q] into register x  
BNE *+4 ; branch to abs addr 0xC016 if val[q]==a  
BRA *+5 ; branch to abs addr 0xC019 if val[q]!=a 
... 
1

通常,分支邏輯被創建,但如果兩個值都被評估,那麼很有可能在沒有任何分支的情況下進行三元運算。這樣考慮:

#include <stdio.h> 

static inline int isel(int cond, int a, int b) 
{ 
    int mask = cond | (-cond); 
    mask >>= 31; 
    return (b & mask) | (a & ~mask); 
} 

int main(void) 
{ 
    printf("1 ? 3 : 4 => %d\n", isel(1, 3, 4)); 
    printf("0 ? 3 : 4 => %d\n", isel(0, 3, 4)); 
    printf("-1 ? 3 : 4 => %d\n", isel(-1, 3, 4)); 
    return 0; 
} 

此代碼假定符號數向右移位將符號擴展,而的sizeof(int)的== 4. 一些處理器可以做ISEL()作爲組件指令。然而,這兩個價值將被評估,三元?:不會。

根據情況的不同,編譯器通常會盡量做最快的事情,要麼是分支來避免冗餘計算,要麼是在三元表達式中的值很簡單的情況下做這種邏輯。

+0

酷!我使用了一個帶有位域的結構體來擴展位信號,但是這也起作用,謝謝!我原本以爲編譯器會不惜一切代價避免分支,但正如你所說,檢查「冗餘計算」也是有意義的。 – Robz 2011-02-28 03:01:10