揭秘 C語言型別轉換時發生了什麼?

2021-10-08 07:54:02 字數 3956 閱讀 4828

在c語言中,資料型別指的是用於宣告不同型別的變數或函式的乙個廣泛的系統,我們常用的算術型別包括兩種型別:整數型別和浮點型別。那麼相互之間具體是怎麼轉化的呢?

了解一下型別轉換

不同資料型別的儲存大小和值範圍是不一樣的,程式在初始化的時候就已經設定了,例如:

int a = 9;

floatb = 8.5;

a,b佔的位元組大小不一樣,這個我們應該都知道,在c語言中乙個表示式允許不同型別的資料進行運算,例如:

int a = 9;

floatb = 8.5,c;

c = a + b;

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

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

而有些型別轉換需要程式設計師顯式指明,那麼通常把這種轉換稱為強制型別轉換。

自動型別轉換

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

#include

intmain()

//定義乙個整型指標變數ppoint

int* ppoint;

//定義基本的資料的型別

char c;

short s;

int i;

long l;

floatf;

double d;

//將整型浮點型資料賦值給指標型別

ppoint = c;

ppoint = s;

ppoint = i;

ppoint = l;

ppoint = f;

ppoint = d;

return0;

由於指標變數和整型、浮點這些資料型的型別是不能相互賦值的,編譯報錯輸出:

那麼我們把同型別資料型別進行運算後賦值呢?

#include

intmain()

//定義乙個整型指標變數ppoint

int* ppoint;

//定義基本的資料的型別

char c;

short s;

int i;

long l;

floatf;

double d;

//將整型浮點型資料運算之後賦值給指標型別

ppoint = c + c;

ppoint = s + s;

ppoint = i + i;

ppoint = l + l;

ppoint = f + f;

ppoint = d + d;

return0;

char同型別運算,結果是乙個int型別。

short同型別運算,結果是乙個int型別。

int同型別運算,結果是乙個int型別。

long同型別運算,結果是乙個long型別。

float同型別運算,結果是乙個float型別。

double同型別運算,結果是乙個double型別。

如下圖所示:

同型別運算中:

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

浮點:不變。

那麼我們把不同型別資料型別進行運算後賦值呢?

#include

intmain()

//定義乙個整型指標變數ppoint

int* ppoint;

//定義基本的資料的型別

char c;

short s;

int i;

long l;

floatf;

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

return0;

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型。

當較高型別的資料轉換為較低型別時,則可能有些資料丟失。

當較低型別的資料轉換為較高型別時,一般只是形式上有所改變, 而不影響資料的實質內容。

所有這些轉換都是由系統自動進行的,使用時你只需從中了解結果的型別即可。

強制型別轉換

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

(型別說明符) (表示式)

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

#include

#include

intmain()

floatf,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語言中,對乙個變數賦值的時候,這個變數初始定義的型別包含了兩層含義:

這個資料型別表示的記憶體空間的大小。

編譯器把設定的數值放到這個記憶體空間,是資料型別的儲存方式解析後存進去的。

總結強調一點

進行強制型別轉換後,記憶體空間裡面的內容是不會發生改變的,改變的是運算時的臨時資料物件的型別,是你去讀取這個記憶體空間時的解析方法。所以,一定要對這個資料型別的記憶體空間和解析方式有乙個清晰的認知。

c/c++學-習-交-流-裙

C 引數傳遞時到底發生了什麼

1 引用型別的變數只包含物件所在的記憶體位址,將要複製的是記憶體位址而不是物件本身,所以對底層物件的修改會保留。unsafeclassprogram fixed int pid mye.id 值為 uint pid uint pid testmethod mye fixed int pid mye....

點選列印按鈕時發生了什麼?

在windir system32 spool printer中生成了2個臨時檔案。shd和 spl。有可能還有 tmp檔案。各個檔案的作用如下 1 spl 檔案是實際的後台列印 列印作業 檔案。2 tmp 檔案是通常與 lpr 列印作業相關聯。3 shd 檔案提供有關哪台印表機列印作業傳送到或從其列...

對塊裝置讀寫時發生了什麼?

塊裝置一次傳輸乙個setor,使用者態卻沒有介面使用這一功能。而把塊裝置模擬成字元裝置,使用者態就可以用普通讀寫的方式來訪問塊裝置,比如將dd作用於塊裝置 複製mbr之類的 模擬的實現很容易想象,比如對於讀操作,將對位元組的需求轉換為對sector的需求,讀入需要的sector,再將要求的位元組送出...