簡體   English   中英

#定義FUNC(x,y)x = ^ y; y ^ x; 在C

[英]#define FUNC(x,y) x=^y; y^x; in c

我有麻煩去理解當有定義然后有兩個異或表達式時的含義。 這個定義做什么?

我嘗試發送x = 8,y = 7,結果是x = 15和y = 8,為什么會發短信?

這是程序:

#define FUNC(a,b) a^=b; b ^=a;

int main(){
    int x=8,y= 7;
    FUNC(x,y);
    printf("%d %d\n",x, y);
}

就是一樣的

int main(){
    int x=8,y= 7;
    x^=y; y ^=x;;
    printf("%d %d\n",x, y);
}

因為定義只是一個簡單的文本替換,即所有帶有a將被x替換,所有帶有b將被y替換。

^是按位XOR運算符。

所以首先x = 8 ^ 7 = 15然后y = 7 ^ 15 = 8

這是因為XOR產生1時位中的一個而不是兩個都是1

x =  8 = 0b00000000000000000000000000001000  // Assuming 32 bit int
y =  7 = 0b00000000000000000000000000000111  // Assuming 32 bit int
 x=x^y = 0b00000000000000000000000000001111 = 15

x = 15 = 0b00000000000000000000000000001111  // Assuming 32 bit int
y =  7 = 0b00000000000000000000000000000111  // Assuming 32 bit int
 y=y^x = 0b00000000000000000000000000001000 = 8
                                        ^^^
                                        Zero because both bits are 1

更多關於原始問題的信息:

該宏具有按位方法的前兩個步驟,可以交換兩個值:

(1) a ^= b
(2) b ^= a
(3) a ^= b

讓我們稍微擴展一下:讓x = a; y = b,我們將通過x和y追蹤代數。 首先,用完整的表達式替換每個“更新”:

(1) a = a ^ b
(2) b = b ^ a
(3) a = a ^ b

現在,將x和y替換為從上到下滴下:

(1) a = x ^ y
(2) b = y ^ (x ^ y)
(3) a = (x ^ y) ^ (y ^ (x ^ y))

刪除括號並重新排列術語:

(1) a = x ^ y
(2) b = x ^ y ^ y
(3) a = x ^ x ^ y ^ y ^ y

...給我們留下b = x; a = y

現在,由於只有前兩個步驟,因此最終結果是

b = x (original value of a)
a = x ^ y (a.k.a. a ^ b)

這為您解釋了眼前的問題嗎?

定義多語句宏的規范方法是

#define FUNC() do { statement1; statement2; } while(0)

即使if(b) FUNC(); 做到了來電者的想法。

幾年前進行了討論,導致MISRA對此進行了更改。 MISRA不再推薦“做”策略,因為他們說應該總是使用花括號,例如if(b) { FUNC(); } if(b) { FUNC(); }可以很好地處理不受保護的多語句宏(並防止Apple證書goto搞砸之類的錯誤)。 相反, do{...會偽裝使用花括號的失敗。

我想我個人還是站在do一方,即使僅僅是因為我知道這一點。

CERT也推薦該技術。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM