Re: [問題] 請教如何只用x,y兩變數來交換彼此數值

看板C_and_CPP作者 (-858993460)時間14年前 (2011/04/11 15:40), 編輯推噓13(1302)
留言15則, 14人參與, 最新討論串3/3 (看更多)
: → 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
借問一下, 那寫成 a+=b; b=a-b; a-=b; 可以嗎
04/12 00:39, 6F

04/12 00:41, , 7F
有緩衝區溢位的風險,如 a = INT_MAX; b = 1;
04/12 00:41, 7F

04/12 00:41, , 8F
沒有緩衝區,打太快了
04/12 00:41, 8F

04/12 00:43, , 9F
overflow 是 undefined behavior
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
3F正解
04/12 10:08, 12F

04/12 21:23, , 13F
大推
04/12 21:23, 13F

04/12 21:40, , 14F
都忘了這件事,果然imperative就怕太依賴state
04/12 21:40, 14F

04/14 13:42, , 15F
用樹講解好清楚啊!! 大推
04/14 13:42, 15F
文章代碼(AID): #1Deo3lyi (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1Deo3lyi (C_and_CPP)