C強制型別轉換總結

2021-08-10 12:28:38 字數 4556 閱讀 7664

一、強制型別轉換目的、基本格式

二、c中變數的本質含義

三、普通變數強制型別轉換

四、指標變數型別轉換

一、強制型別轉換目的、基本格式:

1.1、強轉目的

c語言是強型別語言,如果乙個運算子兩遍的運算資料型別不同,先要將其轉換為相同的型別,強制型別轉換可以消除程式中的警告,即確保寫**的程式設計師自己清楚型別轉換,允許丟失一定精度,或做型別匹配。

例如:

//1、丟失精度情況

int main(void)

//結果:f=5,f=5.750000

//2、做型別匹配

int main(void)

; int *p = (int *)(&a + 1);

printf("*(p-1) = %d.\n", *(p-1));

}//結果:*(p-1) = 5

//這裡面&a + 1中+1,位址加sizeof(a)即乙個陣列長度

//(int *)將指向陣列型別指標,轉換為指向整形,賦值運算子左右對應

1.2、c中強轉的基本格式

方法比較簡單,如下所示:

type1 a;

type2 b;

a = (type1)b; // 強制轉換。

二、c中變數的本質含義:

(1)c中所有型別的資料儲存在記憶體中,都是按照二進位制格式儲存的。所以記憶體中只知道有0和1,不知道是int的、還是float的還是其他型別。

(2)int、char、short等屬於整形,他們的儲存方式(數轉換成二進位制往記憶體中放的方式)是相同的,只是記憶體格仔大小不同(所以這幾種整形就彼此叫二進位制相容格式);而float和double的儲存方式彼此不同,和整形更不同。

(3)c語言中的資料型別的本質,就是決定了這個數在記憶體中怎麼儲存的問題,也就是決定了這個數如何轉成二進位制的問題。一定要記住的一點是記憶體只是儲存1010的序列,而不管這些1010怎麼解析。所以要求我們平時資料型別訪問一致。

int a =5;

存放:編譯器給a分配4位元組空間,並且將5按照int型別的儲存方式轉成二進位制存到a所對應的記憶體空間中去(a做左值的);

取值:我們printf去列印a的時候(a此時做右值),printf內部的vsprintf函式會按照格式化字串(就是printf傳參的第乙個字串引數中的%d之類的東西)所代表的型別去解析a所對應的記憶體空間,解析出的值用來輸出。

解析規則:存進去時是按照這個變數本身的資料型別來儲存的(譬如本例中a為int所以按照int格式來儲存);但是取出來時是按照printf中%d之類的格式化字串的格式來提取的。此時雖然a所代表的記憶體空間中的10101序列並沒有變(記憶體是沒被修改的)但是怎麼理解(怎麼把這些1010轉成數字)就不一定了。譬如我們用%d來解析,那麼還是按照int格式解析則值自然還是5;但是如果用%f來解析,則printf就以為a對應的記憶體空間中儲存的是乙個float型別的數,會按照float型別來解析,值自然是很奇怪的乙個數字了。

//資料型別訪問差異

int main(void)

小結:

(1)int和char型別都是整形,型別相容的。所以互轉的時候有時候錯有時候對。

(2)int和char的不同在於char只有1個位元組而int有4個位元組,所以int的範圍比char大。在char所表示的範圍之內int和char是可以互轉的不會出錯;但是超過了char的範圍後char轉成int不會錯(向大方向轉就不會錯,就好比拿小瓶子的水往大瓶子倒不會漏掉不會丟掉),而從int到char轉就會出錯(就好象拿大瓶子水往小瓶子倒一樣)

三、普通變數強轉規則:

3.1、普通變數轉換規則

當較低型別的資料轉換為較高型別時,一般只是形式上有所改變, 而不影響資料的實質內容, 而較高型別的資料轉換為較低型別時則可能有些資料丟失。如果乙個運算子兩邊的運算數型別不同,先要將其轉換為相同的型別,即將運算子右側數值轉換為運算子左側型別,同側低精度型別轉換為高精度型別,然後再參加運算,轉換規則如下圖所示。

double ← ── float 高

↑ long

↑ unsigned

↑ int ← ── char,short 低

橫向箭頭表示必須的轉換,如兩個float型數參加運算,雖然它們型別相同,但仍要先轉成double型再進行運算,結果亦為double型。

縱向箭頭表示當運算子兩邊的運算數為不同型別時的轉換,如乙個long 型資料與乙個int型資料一起運算,需要先將int型資料轉換為long型,然後兩者再進行運算,這些轉換可以說是自動的,但盡量(確保自己允許轉換發生)使用以顯式的形式強制轉換型別的機制。

3.2、具體轉換細節

(1) 浮點型與整型

將浮點數(單雙精度)轉換為整數時,將捨棄浮點數的小數部分, 只保留整數部分。 將整型值賦給浮點型變數,數值不變,只將形式改為浮點形式,即小數點後帶若干個0。注意:賦值時的型別轉換實際上是強制的。

(2) 單、雙精度浮點型

由於c語言中的浮點值總是用雙精度表示的,所以float型資料只是在尾部加0延長為doub1e型資料參加運算,然後直接賦值。doub1e型資料轉換為float型時,通過截尾數來實現,截斷前要進行四捨五入操作。

(3) char型與int型

int型數值賦給char型變數時,只保留其最低8位,高位部分捨棄。 char型數值賦給int型變數時,一些編譯程式不管其值大小都作正數處理,而另一些編譯程式在轉換時,若char型資料值大於127,就作為負數處理。對於使用者來講,如果原來char型資料取正值,轉換後仍為正值;如果原來char型值可正可負,則轉換後也仍然保持原值,只是資料的內部表示形式有所不同。

(4) int型與1ong型

long型資料賦給int型變數時,將低16位值送給int型變數,而將高16 位截斷捨棄。(這裡假定int型佔兩個位元組)。 將int型資料送給long型變數時,其外部值保持不變,而內部形式有所改變。

(5) 無符號整數

將乙個unsigned型資料賦給乙個佔據同樣長度儲存單元的整型變數時(如:unsigned→int、unsigned long→long,unsigned short→short) ,原值照賦,內部的儲存方式不變,但外部值卻可能改變

用強制型別轉換是乙個好習慣,這樣,至少從程式上可以看出想幹什麼。

四、指標變數強轉規則:

(1)指標變數強轉,改變了指標取址能力。

(2)乙個指標涉及2個變數:乙個是指標變數自己本身,乙個是指標變數指向的那個變數

(3)int p;定義指標變數時,p(指標變數本身)是int 型別,*p(指標指向的那個變數)是int型別的。

(4)int 型別說白了就是指標型別,只要是指標型別就都是佔4位元組,解析方式都是按照位址的方式來解析(意思是裡面存的32個二進位制加起來表示乙個記憶體位址)的。結論就是:所有的指標型別(不管是int 還是char * 還是double *)的解析方式是相同的,都是位址。

(5)對於指標所指向的那個變數來說,指標的型別就很重要了。指標所指向的那個變數的型別(它所對應的記憶體空間的解析方法)要取決於指標型別。譬如指標是int *的,那麼指標所指向的變數就是int型別的。

#include 

int main(void)

; int

*p1 = a;

printf("*p1 = 0x%x\n", *p1); //

*p1 = 0x11223344

char *p2 = (char *)a; //改變取址能力

printf("*p2 = 0x%x\n", *p2); //

*p2 = 0x44

printf("*p2 = 0x%x\n", *(p2+1)); //

*p2 = 0x33

printf("*p2 = 0x%x\n", *(p2+2)); //

*p2 = 0x22

printf("*p2 = 0x%x\n", *(p2+3)); //

*p2 = 0x11

printf("*p2 = 0x%x\n", *(p2+4)); //

*p2 = 0xffffff88 ?

printf("*p2 = 0x%x\n", *(p2+5)); //

*p2 = 0x77

return

0;}

c 強制型別轉換(總結)

什麼是型別轉換?型別轉換的含義是通過改變乙個變數的型別為別的型別從而改變該變數的表示方式。為了型別轉換乙個簡單物件為另乙個物件你會使用傳統的型別轉換操作符。c與c 的型別轉換 c中 t element 或者 t element c 中 reinterpret cast expression dyna...

c 強制型別轉換(總結)

什麼是型別轉換?型別轉換的含義是通過改變乙個變數的型別為別的型別從而改變該變數的表示方式。為了型別轉換乙個簡單物件為另乙個物件你會使用傳統的型別轉換操作符。c與c 的型別轉換 c中 t element 或者 t element c 中 reinterpret cast expression dyna...

C 強制型別轉換

四種型別可能很多人都常常忽略就象我一樣,但是有時還是比較有用的。不了解的建議看看,一些機制我也不是十分了解,只是將一些用法寫出來讓大家看看。強制轉化無論從語法還是語意上看,都是c 中最難看的特徵之一。但是基於c風格的轉化的語義的不明確性及其一些潛在問題。強制型別轉化最終還是被c 接受了。1.stat...