Re: [問題] 請教如何只用x,y兩變數來交換彼此數值
: → 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
推
04/12 00:02, , 1F
04/12 00:02, 1F
推
04/12 00:07, , 2F
04/12 00:07, 2F
推
04/12 00:09, , 3F
04/12 00:09, 3F
推
04/12 00:12, , 4F
04/12 00:12, 4F
推
04/12 00:16, , 5F
04/12 00:16, 5F
→
04/12 00:39, , 6F
04/12 00:39, 6F
推
04/12 00:41, , 7F
04/12 00:41, 7F
→
04/12 00:41, , 8F
04/12 00:41, 8F
推
04/12 00:43, , 9F
04/12 00:43, 9F
推
04/12 07:36, , 10F
04/12 07:36, 10F
推
04/12 08:40, , 11F
04/12 08:40, 11F
推
04/12 10:08, , 12F
04/12 10:08, 12F
推
04/12 21:23, , 13F
04/12 21:23, 13F
推
04/12 21:40, , 14F
04/12 21:40, 14F
推
04/14 13:42, , 15F
04/14 13:42, 15F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 3 篇):