→ longlongint: char的範圍是? 02/15 15:05
→ andrenvq57: 為什麼不是0x000088而是0xffff88 overflow是直接用ff 02/15 15:17
→ andrenvq57: 頂替嗎 02/15 15:17
→ stupid0319: char* b = (char*)&a; 這樣比較理想 02/15 15:20
→ stupid0319: 結果不是b = ffffff88嗎,怎麼下一行又變b = ffffff34 02/15 15:23
※ 編輯: vvrr (60.250.31.103), 02/15/2016 15:37:04
→ vvrr: 是88沒錯@@ 抱歉 02/15 15:37
推 stupid0319: char = 0x7F ,0x80 , 0x81 各試看看吧 02/15 15:42
→ vvrr: char就,一般的char. 應該是-128~127 02/15 15:43
→ vvrr: 2F,我也不知道為什麼是ff,gcc印出來的.. 02/15 15:44
※ 編輯: vvrr (60.250.31.103), 02/15/2016 15:46:25
推 CoNsTaR: 因為你 printf 要求的輸入不是 char 你卻給他 char 吧… 02/15 15:45
推 CoNsTaR: 它需要一個比 char 更大的型態 02/15 15:47
→ CoNsTaR: 像你這裡輸出的結果是 4*8=32bit 的型態 02/15 15:47
→ vvrr: 如果前面都會被補成ffff就還好,但是有些就不會 02/15 15:48
※ 編輯: vvrr (60.250.31.103), 02/15/2016 15:49:09
→ CoNsTaR: int i = 5000; 02/15 15:49
→ CoNsTaR: char c = (char)i;i = c;printf("%p\n", i); 02/15 15:49
→ CoNsTaR: @vvrr因為你不能知道你讀超過b之外的值是多少啊 02/15 15:50
→ CoNsTaR: 如果b前面的變數剛好都是0那讀出來當然就不會有f 反之 02/15 15:52
→ CoNsTaR: 亦然 02/15 15:52
→ CoNsTaR: 這裡沒有 overflow 只有 overbound 02/15 15:53
推 stupid0319: FFFFFF不是補上去的吧......看了我都快吐血了 02/15 16:04
推 stupid0319: 神人來說一下char跟int的負數怎麼表示吧 02/15 16:07
→ stupid0319: char跟int的-1各為FF跟FFFFFFFF 02/15 16:11
→ stupid0319: -2呢,FE跟FFFFFFFE 02/15 16:11
→ stupid0319: 所以char的0x88跟int的0xffffff88是等值的 02/15 16:13
→ stupid0319: 在一些程式中,輸入0x80000000可能造成bug 02/15 16:15
→ stupid0319: 很多遊戲的洗錢BUG就是這麼來的 02/15 16:15
推 LPH66: 關鍵字: sign extension 02/15 16:19
→ besmartAE: (unsigned char)才對 02/15 16:21
→ stupid0319: 一個道具10萬塊錢好了,買21475個,變成0x80003FE0 02/15 16:21
→ stupid0319: 買了道具後系統還要付給你21億 02/15 16:22
→ vvrr: 「所以char的0x88跟int的0xffffff88是等值的」 02/15 16:36
→ vvrr: 所以printf會先把後面的數字轉成int嗎? 02/15 16:36
→ vvrr: ^^^^^^^^^^ 後面的char型態的b 02/15 16:37
推 stupid0319: %x Unsigned hexadecimal integer 02/15 16:40
推 apologize: unsigned char b = (char)a; 改成 02/15 18:21
推 LPH66: >vvrr 16:36 是, 不過不是 printf 轉的 02/15 22:26
→ LPH66: 而是因為 printf 屬於可變參數函式, 不到 int 等級的整數 02/15 22:26
→ LPH66: 規定要轉成 int 再傳進去, 所以在那時就已經轉了 02/15 22:27
→ LPH66: 也因為規定轉成 int, 所以會轉成一個有號整數 02/15 22:27
→ LPH66: 這才用上了我上面講的 sign extension 02/15 22:28
→ LPH66: 概念上就是如 stupid0319 講的, 0x88 (等於十進位 -120) 02/15 22:29
→ LPH66: 會變成 int 的 -120 (0xffffff88) 02/15 22:29
→ LPH66: 那因為二進位觀點來看就是最高位的正負號位元往前補滿 02/15 22:29
→ LPH66: 所以要說「ffffff 是補上去的」技術上來說也沒有錯就是了 02/15 22:30
推 azter: 其實可以開小算盤的程式設計師模式 02/16 01:00
→ azter: 第一步計算5000+128 02/16 01:02
→ azter: 第二步 將第一步結果 mod 256 02/16 01:03
→ azter: 第三步 將第二步的結果再減去減去128 02/16 01:04
→ azter: 小算盤的輸出結果是-120 02/16 01:07
→ azter: 單看-120可能看不出端倪,請看小算盤下面顯示一堆1 0那欄 02/16 01:10
推 LPH66: 要講型態轉換的話, 這樣操作: (1) 左下角選 dword, 10 進位 02/16 03:30
→ LPH66: 然後輸入 5000; (2) 左下角點選 byte; 這等同於轉型成 char 02/16 03:31
→ LPH66: 你會看到它變成了 -120 了 02/16 03:31
→ LPH66: (3) 根據我上面說的, 傳進 printf 前會再轉成 int 02/16 03:31
→ LPH66: 所以再點回 dword, 你會看到數值還是 -120 02/16 03:32
→ LPH66: 但下面的二進位顯示部份前面卻是全部補了 1 進去 02/16 03:32
→ LPH66: (4) 輸出成 %x, 所以點選 16 進位, 就看到 ffffff88 出來了 02/16 03:33
→ LPH66: 你把你實驗的值代換掉上面的 5000, 觀察下面二進位顯示 02/16 03:34
→ LPH66: 就會知道為什麼有些數會這樣變有些數會那樣變 02/16 03:34
→ vvrr: 謝謝大家<(_ _)> 02/16 10:58
→ vvrr: 1. int a 轉成 char b的時候,不論正負只留最後1個byte 02/16 10:59
→ vvrr: 2. char b傳進printf前會根據b此時代表數值轉成signed int 02/16 11:00
→ vvrr: 3. printf實際上印出來的都是int.有些只看到1byte的只是前面 02/16 11:01
→ vvrr: 都是0(而且我沒有叫printf印出來) 大概是這樣沒錯吧 02/16 11:02