【揭秘】C語言類型轉換時發生了什么?


ID:技術讓夢想更偉大
作者:李肖遙
鏈接:https://mp.weixin.qq.com/s/ZFf3imVaJgeesuhl1Kn9sQ

在C語言中,數據類型指的是用於聲明不同類型的變量或函數的一個廣泛的系統,我們常用的算術類型包括兩種類型:整數類型和浮點類型。那么相互之間具體是怎么轉化的呢?

了解一下類型轉換

不同數據類型的存儲大小和值范圍是不一樣的,程序在初始化的時候就已經設定了,例如:

int a = 9;
float b = 8.5;

a,b占的字節大小不一樣,這個我們應該都知道,在C語言中一個表達式允許不同類型的數據進行運算,例如:

int a = 9;
float b = 8.5,c;
c = a + b;

因為計算機硬件在進行算術操作時,要求各操作數的類型具有相同的存儲位數以及一樣的存儲方式,所以就出現了類型轉換。

對於某些類型的轉換,編譯器可以隱式地自動進行,這種轉換稱為自動類型轉換

而有些類型轉換需要程序員顯式指明,那么通常把這種轉換稱為強制類型轉換

自動類型轉換

自動轉換是在源類型和目標類型兼容以及目標類型廣於源類型時發生一個類型到另一類的轉換。我們先來看一段代碼

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據賦值給指針類型
 pPoint = c;
 pPoint = s;
 pPoint = i;
 pPoint = l;
 pPoint = f;
 pPoint = d;
 
 return 0;
}

由於指針變量和整型、浮點這些數據型的類型是不能相互賦值的,編譯報錯輸出:

那么我們把同類型數據類型進行運算后賦值呢?

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據運算之后賦值給指針類型
 pPoint = c + c;
 pPoint = s + s;
 pPoint = i + i;
 pPoint = l + l;
 pPoint = f + f;
 pPoint = d + d;
 
 return 0;
}
  • char同類型運算,結果是一個int類型。
  • short同類型運算,結果是一個int類型。
  • int同類型運算,結果是一個int類型。
  • long同類型運算,結果是一個long類型。
  • float同類型運算,結果是一個float類型。
  • double同類型運算,結果是一個double類型。

如下圖所示:

同類型運算中:

  • 整型:比int小的,都會轉換成int,比int大的不變。
  • 浮點:不變。

那么我們把不同類型數據類型進行運算后賦值呢?

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include <stdio.h>
int main()
{
 //定義一個整型指針變量pPoint
 int* pPoint;

 //定義基本的數據的類型
 char c;
 short s;
 int i;
 long l;
 float f;
 double d;

 //將整型浮點型數據混合運算賦值給指針類型
 pPoint = c + s;  // char + short = int
 pPoint = c + i;  // char + int = int
 pPoint = c + l;  // char + long = int
 pPoint = c + f;  // char + float = long
 pPoint = c + d;  // char + double = float
 
 return 0;
}
  • char類型與short類型運算,結果是一個int類型。
  • char類型與int類型運算,結果是一個int類型。
  • char類型與long類型運算,結果是一個long類型。
  • char類型與float類型運算,結果是一個float類型。
  • char類型與double類型運算,結果是一個double類型。

結果如下圖所示:

可以得出在不同類型運算中:

  • 如果兩邊均比int小或等於int,那么結果為int。
  • 如果兩邊有比int大的,那么結果為比int大的類型。

我們得到結論如圖:

  • 整型類型級別從低到高依次為:
    int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long

  • 浮點型級別從低到高依次為:
    float -> double

自動轉換規則:

  • 圖中橫向箭頭表示必須的轉換,如兩個float型數參加運算,雖然它們類型相同,但仍要先轉成double型再進行運算,結果亦為double型。
  • 圖中縱向箭頭表示當運算符兩邊的運算數為不同類型時的轉換,如一個long 型數據與一個int型數據一起運算,需要先將int型數據轉換為long型, 然后兩者再進行運算,結果為long型。
  • 當較高類型的數據轉換為較低類型時,則可能有些數據丟失。
  • 當較低類型的數據轉換為較高類型時,一般只是形式上有所改變, 而不影響數據的實質內容。
  • 所有這些轉換都是由系統自動進行的,使用時你只需從中了解結果的類型即可。

強制類型轉換

強制類型轉換是通過類型轉換運算來實現的。其一般形式為:

(類型說明符) (表達式)

其作用就是把表達式的運算結果強制轉換成類型說明符所表示的類型的值。

//vs2019
//來源:技術讓夢想更偉大
//作者:李肖遙
#include<stdio.h>
#include<string.h>

int main()
{
    float f,x=1.3,y=1.4;
    int i = 4,a,b;
    a = x + y;
    b = (int)(x+y);
    f = 10/i;
    printf("a=%d,b=%d,f=%f,x=%f,y=%f\n",a,b,f,x,y);
}

運行結果如下:

我們從中可以看到,雖然x,y變強制轉換int型,但是最后輸出的值不變,強制類型轉換沒有影響x和y變量原本的類型。而上圖警告已經說明了一切。

注意:在C語言中,對一個變量賦值的時候,這個變量初始定義的類型包含了兩層含義:

  1. 這個數據類型表示的內存空間的大小。
  2. 編譯器把設定的數值放到這個內存空間,是數據類型的存儲方式解析后存進去的。

總結強調一點

進行強制類型轉換后,內存空間里面的內容是不會發生改變的,改變的是運算時的臨時數據對象的類型,是你去讀取這個內存空間時的解析方法。所以,一定要對這個數據類型的內存空間和解析方式有一個清晰的認知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM