深刻理解C語言中的類型轉換

隱式轉換

基本類型轉換

整形提高

表達式計算時,整型會首先提高到int類型,當int類型表示的範圍不夠時,會提高爲unsigned int類型。c語言中能夠進行整型提高的包括bool,char,short及其對應的無符號類型。下面例子中,無論是bool,char仍是short類型,在進行算術運算時,運算結果大小都是4個字節,這是由於編譯器會默認對這些整型進行提高,轉爲4個字節再進行運算。安全

int main()
{ 
    bool b1 = true;
    bool b2 = true;
    // output: 4 2
    cout << sizeof(b1 + b2) << " " << b1 + b2 << endl;

    char c1 = 'a';
    char c2 = 'b';
    // output 4 195
    cout << sizeof(c1 + c2) << " " << c1 + c2 << endl;

    short s1 = INT16_MAX;
    short s2 = 1;
    // output 4 32768
    cout << sizeof(s1 + s2) << " " << s1 + s2 << endl;

    return 0;
}

算術轉換

  • 整型和浮點數相加獲得浮點型;
  • 有符號整型和有符號整型相加獲得其中較大的有符號整型;
  • 無符號整型和無符號整型相加獲得其中較大的無符號整型;
  • 有符號整型和無符號整型相加獲得較大空間的類型,若是有符號整型空間大,則結果爲有符號整型,若是無符號整型空間大,則結果爲無符號整型,若是有符號整型和無符號整型空間相等,則結果爲無符號整型。

總結來講,算術轉換會往較大空間類型的方向轉換;若是空間同樣,則會往浮點型或者無符號方向轉換。ui

int i1 = INT32_MAX;
long long ll1 = 1;
// output 8 2147483648
cout << sizeof(i1 + ll1) << " " << i1 + ll1 << endl;

unsigned int ui1 = 1;
// output 4 2147483648
cout << sizeof(i1 + ui1) << " " << i1 + ui1 << endl;

int i2 = 1;
// output 4 -2147483648 整數溢出
cout << sizeof(i1 + i2) << " " << i1 + i2 << endl;

指針轉換

任何指針類型均可以隱式轉換成void*類型,反之不成立。spa

int a = 0;
int* pa = &a;
void* pb = pa;    // 正確
pa = pb;          // 編譯錯誤

顯示轉換

第一部分中提到了C語言中基本類型之間的轉換以及任意指針轉換爲void指針,這些轉換均可以隱式地進行,編譯器默認幫助開發者操做,不會報錯。然而,對於void指針轉換爲某個具體類型的指針或者任意兩種不是void類型指針之間的轉換來講,編譯器都會拋出錯誤。須要明確的一點是,C語言中任意類型指針之間都是能夠完成轉換的,只不過編譯器以爲這個轉換很不安全,不會幫咱們暗地裏操做,須要程序開發者我的斷定安全性,使用顯示轉換。有人可能會以爲第一部分中的轉換也很不安全,好比double轉爲int,會使得數值損失精度,事實確實如此,但相比任意指針間的轉換來講,這種轉換的風險小得多,所以對於第一部分的狀況,編譯器支持默認轉換。指針

int a = 0;
void* pa = &a;
int* pb = (int*)pa;
// 正確,輸出0
cout << *pb << endl;

// 正確,輸出空,由於a爲0,其第一個字節爲0,在char型變量中,表示空
char* pc = (char*)pb;
cout << *pc << endl;
相關文章
相關標籤/搜索