作者 LPH66 (-858993460) 看板 C_and_CPP
標題 Re: [問題] 請教如何只用x,y兩變數來交換彼此數值
時間 Mon Apr 11 23:40:29 2011
───────────────────────────────────────
: → littleshan:不要這樣寫!這是 implementation-defined behavior 04/11 15:48
: → littleshan:就是十誡之八啦 04/11 15:49
基本上這個寫法的確是 implementation-defined behavior
不管有沒有加括號都一樣
事情是這樣的
a ^= b ^= a ^= b;
1 2 3 4 5 6 7
這樣寫的人想要做的事的順序是
值為
(7) 取 b 的值 原來的 b
(5) 取 a 的值 原來的 a
(6) 做 (5)^(7) 並把值放回 a 去 原來的 a^b
(3) 取 b 的值 原來的 b
(4) 做 (3)^(6) 並把值放回 b 去 原來的 a
(1) 取 a 的值 原來的 a^b
(2) 做 (1)^(4) 並把值放回 a 去 原來的 b
但有些 compiler (如我手上的 g++ 4.1.0 for win) 會編成這個順序
值為
(1) 取 a 的值 原來的 a
(3) 取 b 的值 原來的 b
(5) 取 a 的值 原來的 a
(7) 取 b 的值 原來的 b
(6) 做 (5)^(7) 並把值放回 a 去 原來的 a^b
(4) 做 (3)^(6) 並把值放回 b 去 原來的 a
(2) 做 (1)^(4) 並把值放回 a 去 一定是 0
結果是原來 a 的值在 b 但 a 卻變成 0 了
問題在於
雖然這個式子的確是分析成
^= (2)
/ \
a ^= (4)
(1) / \
b ^= (6)
(3) / \
a b
(5) (7)
這個樣子 但在計算 a ^= b 時 a b 取值的順序卻是 implementation-defined
也就是在上面那棵語法樹的後序走訪中先走左子樹還是先走右子樹
如果先走左子樹 就是 1 3 5 7 6 4 2 的順序
先走右子樹 就是 7 5 6 3 4 1 2 的順序
而這兩個順序 上面我也寫出來了
後者是順利交換沒錯 前者卻是把 a 搬到 b 後把 a 炸成 0 !
所以結論是千萬不要用這個寫法
---
其實簡單一句話就是十三誡之八裡說的
你不可以在一個運算式(expression)中,對一個基本型態的變數修改其值
超過一次以上。否則,將導致未定義的行為(undefined behavior)
如果真要用 xor 來交換 乖乖寫三條
x ^= y; y ^= x; x ^= y;
就什麼事都沒有....
當然最好的寫法還是 int temp = x; x = y; y = temp; 就是了
--
'You've sort of made up for it tonight,' said Harry. 'Getting the
sword. Finishing the Horcrux. Saving my life.'
'That makes me sound a lot cooler then I was,' Ron mumbled.
'Stuff like that always sounds cooler then it really was,' said
Harry. 'I've been trying to tell you that for years.'
-- Harry Potter and the Deathly Hollows, P.308
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.30.142
推 attomahawk:推薦這棵 語法樹! 04/12 00:02
推 glennchen:好強大 04/12 00:07
推 loveme00835:不管多炫, 在可讀性上永遠是個失敗品, 是禁忌 04/12 00:09
推 james732:原來如此! 04/12 00:12
推 VictorTom:推語法樹:) 04/12 00:16
→ bibo9901:借問一下, 那寫成 a+=b; b=a-b; a-=b; 可以嗎 04/12 00:39
推 purpose:有緩衝區溢位的風險,如 a = INT_MAX; b = 1; 04/12 00:41
→ purpose:沒有緩衝區,打太快了 04/12 00:41
推 littleshan:overflow 是 undefined behavior 04/12 00:43
推 xatier:語法樹! 推 04/12 07:36
推 wanwan2:讚!! 04/12 08:40
推 genghiskii:3F正解 04/12 10:08
推 j094097:大推 04/12 21:23
推 yauhh:都忘了這件事,果然imperative就怕太依賴state 04/12 21:40
推 h520:用樹講解好清楚啊!! 大推 04/14 13:42
2012年4月22日 星期日
C&C++: Re: [問題] 請教如何只用x,y兩變數來交換彼此數值
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言