2014-06-17 207 views
1

我正在嘗試一些do和dont的類型轉換的例子。我無法理解爲什麼下面的代碼片段無法輸出正確的結果。從int,float,char,double的類型轉換

/* int to float */ 
#include<stdio.h> 
int main(){ 
     int i = 37; 
     float f = *(float*)&i; 
     printf("\n %f \n",f); 
     return 0; 
} 

這將打印0.000000

/* float to short */ 
#include<stdio.h> 
int main(){ 
     float f = 7.0; 
     short s = *(float*)&f; 
     printf("\n s: %d \n",s); 
     return 0; 
} 

這將打印7

/* From double to char */ 
#include<stdio.h> 
int main(){ 
     double d = 3.14; 
     char ch = *(char*)&d; 
     printf("\n ch : %c \n",ch); 
     return 0; 
} 

這將打印垃圾

/* From short to double */ 
#include<stdio.h> 
int main(){ 
     short s = 45; 
     double d = *(double*)&s; 
     printf("\n d : %f \n",d); 
     return 0; 
} 

這將打印0.000000

爲什麼從floatint的轉換會給出正確的結果,並且在明確轉換類型時所有其他轉換都會給出錯誤結果?

我不能清楚地瞭解爲什麼需要,而不是float

int i = 10; 
float f = (float) i; // gives the correct op as : 10.000 

但這種類型轉換的(float*)

int i = 10; 
float f = *(float*)&i; // gives a 0.0000 

什麼是上述兩種類型之間的區別蒙上?

爲什麼不能我們使用:

float f = (float**)&i; 
float f = *(float*)&i; 
+1

不是'float f =(float)&i'將'i'的內存位置賦給'f'嗎? –

+1

您正在轉換指針,而不是數值,這意味着您正在處理一種類型的對象(如'int')*,就像*它們是另一種類型的對象(例如'float')。結果是垃圾。要轉換數值,只需使用'int i = 37; float f = i;' - 或者,如果你堅持不必要的明確,'float f =(float(i);'。(所有數字類型都是隱式轉換的,因此很少需要從一個數字類型轉換爲另一個數字類型。 )('float'的範圍和精度要求不能超過16位。) –

回答

4

在這個例子中:

char ch = *(char*)&d;

你是不是從double鑄造到char。您正在從double*投射到char*;也就是說,您正在將雙指針指針轉換爲char 指針

C在轉換值時會將浮點類型轉換爲整數類型,但由於您將指針轉換爲這些值,因此沒有轉換完成。你會得到垃圾,因爲浮點數的存儲與定點數非常不同。

3

閱讀有關係統中浮點數的表示形式。它不像你期待的那樣。通過(float *)在您的第一個代碼片段中讀取最重要的前16位。如果你的系統是小端,那麼如果int類型變量中的值小於2^16,那麼在最高有效位中將始終爲零。

+1

在很多系統中,float和int都是32位。 –

+0

又改變了系統到系統 –

+0

是的,它確實 - 但你的答案沒有提到這一點。第一個片段'int i = 37; float f = *(float *)&i;'*不讀*最重要或最先它試圖從int對象中讀取'CHAR_BIT * sizeof(float)'位。 –

1

如果你需要將int轉換成浮動,轉換是直的,因爲C.
的促銷規則所以,它足以寫:

int i = 37; 
    float f = i; 

這給出結果f == 37.0

但是,在鑄造(float *)(&i)中,結果是類型爲「指向浮點的指針」的對象。
在這種情況下,「指向整數」指針& i的地址與「浮點指針」(float *)(& i)的地址相同。但是,最後一個對象指向的對象是一個float,其位數與對象i(其爲整數)的位數相同。

現在,討論的要點是內存中的對象的位表示對於整數和浮點數是非常不同的。
正整數以明確的形式表示,如其二進制數學表達式所示。
但是,浮點數有其他表示形式,由尾數和指數組成。

所以,當一個對象的位被解釋爲一個整數時,它有一個含義,但是相同的位,被解釋爲一個浮點數,具有另一個非常不同的含義。

1

更好的問題是,它爲什麼能夠工作。你看,當你做

typedef int T;//replace with whatever 
typedef double J;//replace with whatever 
T s = 45; 
J d = *(J*)(&s); 

你基本上是告訴編譯器(獲得S的T *地址,reintepret它所指向爲J,然後得到該值)。實際上不會發生值的轉換(更改字節)。有時,幸運的是,這是相同的(低值浮點數將爲0,所以整數解釋可能是相同的),但往往是時間,這將是垃圾,或者更糟,如果大小不一樣的話像從char轉換爲double),你可以讀取未分配的數據(堆損壞(有時)!)。