C語言中資料型別的自動型別轉換

QCZTZSWT357發表於2017-06-16

非常的重要的宣告:
這篇部落格的內容,主要參考網友的部落格
尊重智慧財產權,尊重原創!

一、 C在以下四種情況下會進行隱式轉換:

  1. 算術運算式中,低型別能夠轉換為高型別。
  2. 賦值表示式中,右邊表示式的值自動隱式轉換為左邊變數的型別,並賦值給他。
  3. 函式呼叫中引數傳遞時,系統隱式地將實參轉換為形參的型別後,賦給形參。
  4. 函式有返回值時,系統將隱式地將返回表示式型別轉換為返回值型別,賦值給呼叫函式。

二、 運算表示式中的自動型別轉換

運算表示式中,有如下型別轉換規則:

  1. 字元必須先轉換為整數(C語言規定字元型別資料和整型資料之間可以通用) 。
  2. short型轉換為int型(同屬於整型) 。
  3. float型資料在運算時一律轉換為雙精度(double)型,以提高運算精度(同屬於實型)

其次,有下面的規則:

當不同型別的資料進行操作時,應當首先將其轉換成相同的資料型別,然後進行操作,轉換規則是由低階向高階轉換。轉換規則如下圖所示:
這裡寫圖片描述

如上圖所示,再根據上述的算數表示式的轉換規則,我們可以得知:

  • 字元型資料和short型資料在算術表示式中,一律轉換為int型資料後,再參與運算。
  • float型資料在運算時一律轉換為雙精度(double)型,以提高運算精度(同屬於實型)。
  • 注意有符號數與無符號數之間的運算中出現的轉換。

三、 有符號數與無符號數之間的運算中出現的轉換

當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。因此,從這個意義上講,無符號數的運算優先順序要高於有符號數,這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是豐常重要的。

舉個例子:
程式碼如下:
這裡寫圖片描述
執行結果如下:
這裡寫圖片描述
結果分析如下:

在c語言操作中,如果遇到無符號數與有符號數之間的操作,編譯器會自動轉化為無符號數來進行處理,因此a=20,b=4294967166,這樣比較下去當然b>a了。

再舉個例子:
這裡寫圖片描述

編個程式碼測試如下:(注意要用gdb除錯,不要用printf函式列印。因為printf函式會對傳進去的引數進行型別轉換。)
這裡寫圖片描述
gdb除錯結果如下:(結果不是:-3)
這裡寫圖片描述


以下全文摘抄自網友部落格


下表來自MSDN:
這裡寫圖片描述
對上表補充說明一下:
1)在32位機上,int型和unsigned int型都是32位的(4個位元組)。
2)enum會跟據最大值來決定型別,一般來說為int型,如果超出int型所能表示的範圍,則用比int型大的最小型別來表示(unsigned int, long 或者unsigned long)
3)關於型別的大小。一般用所能表示的資料範圍來比較型別的大小,如char型unsigned char型short型…在表示式中,一般都是由小的型別向大的型別轉換(強制型別轉換除外)

  1. 所有比int型小的資料型別(包括char, unsigned char, short, unsigned short)轉換為int型。如果轉換後的資料會超出int型所能表示的範圍的話,則轉換為unsigned int型;
  2. bool型轉化為int型時,false轉化為0,true轉換為1;反過來所有的整數型別轉化為bool時,0轉化為false,其它非零值都轉為true;
  3. 如果表示式中混有unsigned short和int型時,如果int型資料可以表示所有的unsigned short型的話,則將unsigned short型別的資料轉換為int型,否則,unsigned short型別及int型都轉換為unsigned int型別。舉個例子,在32位機上,int是32位,範圍–2,147,483,648 to 2,147,483,647,unsigned short是16位,範圍0 to 65,535,這樣int型的足夠表示unsigned short型別的資料,因此在混有這兩者的運算中,unsigned short型別資料被轉換為int型;
  4. unsigned int 與long型別的轉換規律同3,在32位機上,unsigned int是32位,範圍0 to 4,294,967,295,long是32位,範圍–2,147,483,648 to 2,147,483,647,可見long型別不夠表示所有的unsigned int型,因此在混有unsigned int及long的表示式中,兩者都被轉換為unsigned long;
    (我自己的理解:在32位機上,unsigned long 和 unsigned int 是等效的,所以才會出現下面的結果。)
    這裡寫圖片描述
  5. 如果表示式中既有int 又有unsigned int,則所有的int資料都被轉化為unsigned int型別。

經過這番總結,前面提出的問題的答案應該就很明顯了吧。在表示式a*-1中,a是unsigned int型,-1是int型(常量整數的型別同enum),按第5條可以知道-1必須轉換為unsigned int型,即0xffffffff,十進位制的4294967295,然後再與i相乘,即4294967295*3,如果不考慮溢位的話,結果是12884901885,十六進位制0x2FFFFFFFD,由於unsigned int只能表示32位,因此結果是0xfffffffd,即4294967293。

相關文章