程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言打印16進制出現0xffffff現象的問題剖析!

C語言打印16進制出現0xffffff現象的問題剖析!

編輯:關於C語言

C語言打印16進制出現0xffffff現象的問題剖析!


其實類似的問題不是只在網絡程序中才會出現的,看示例代碼:   復制代碼   1 #include <stdio.h>   2 int main()   3 {   4     char c = 0xc9;   5     printf("A:c = %2x\n",(unsigned char)c);   6     printf("B:c = %2x\n",c & 0xff);   7     printf("C:c = %2x\n",c);   8     return 0;   9 } 復制代碼   程序輸出如下:   A:c = c9 B:c = c9 C:c = ffffffc9   可以看到:     把c轉換成unsigned char打印是正確的。視作情況A。     把c與 0xff做&操作後打印正確。視作情況B。     對c不做任何處理,則問題復現了,打印出ffffffc9。視作情況C。     情況A B是我百度來的一些解決C現象的方法。那麼我們現在來逐一分析解釋ABC三種情況。          首先我們必須知道,printf()函數的%x(X)輸出的是Int型別的16進制格式。所以char型別的c變量會被轉換成Int型別。     其次,我們的知道計算機是用補碼表示數據的。關於原碼,反碼,補碼的知識請自行充電。   情況C:      c的補碼:11001001(0xc9)。      c的反碼:11001000(0xc9)。      c的原碼:10110111(0xc9)。       因為char型別是帶符號的,所以最高位的1這裡視為負號。      把c轉換成Int型別   char  -----> Int      Int_c的原碼:10000000 00000000 00000000 00110111(把c原碼的最高位1  提到最高位。其余高位補0)。      Int_c的反碼:11111111 11111111 11111111 11001000      Int_c的補碼:11111111 11111111 11111111 11001001(0xffffffc9)。      所以打印出來看似詭異的值其實是合情合理的。如何避免?看AB情況。   情況B:     我們在情況C的基礎上將c與0xff做&操作。     Int_c的補碼:11111111 11111111 11111111 11001001(0xffffffc9)。            &            00000000 00000000 00000000 11111111     最終結果為: 00000000 00000000 00000000 11001001(0xc9)。   情況A:     我覺得情況A的處理方式才是最正規的處理辦法,但是據說linux內核使用(&0xff)。      c的補碼:11001001(0xc9)。      c的反碼:11001001(0xc9)。      c的原碼:11001001(0xc9)。       這裡強制轉換c為unsigned char型別。因此最高位的1不是正負號      把c轉換成Int型別   char  -----> Int      Int_c的原碼:00000000 00000000 00000000 11001001(把c原碼的最高位1  提到最高位。其余高位補0)。      Int_c的反碼:00000000 00000000 00000000 11001001      Int_c的補碼:00000000 00000000 00000000 11001001(0xc9)。      因此打印正常。     以上分析,如有不正確的地方請各位指正。    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved