為什么變數b沒有被分配到10的值?
int *a。
int c = 5;
float b = 5.1;
a = (int*)&b;
*a = 10;
printf ("a = %p, & b = %p, b = %lf, *a = %d
", a, &b, b, *a)。)
結果:b = 0.00000, *a = 10
uj5u.com熱心網友回復:
雖然我們可以將一個普通的int賦值給一個float,反之亦然,然后得到一個隱式轉換,但這并不適用于指標。
a = (int*)&b是一個無效的指標轉換。你對編譯器撒謊,說存盤在地址&b的東西是一個int。但它不是。這是未定義的行為--兩種不同的型別可能有不同的大小--但這也是 "嚴格別名的違反"。什么是嚴格別名規則?
由于你的代碼包含未定義的行為,任何事情都可能發生。什么是未定義行為,它是如何作業的? 許多可能的行為之一是,系統試圖將二進制表示法重新解釋為一個浮點數,其中0xA最終在分數部分的位置很靠后,被舍入為零。該程式可能會崩潰或顯示任何隨機的垃圾。
uj5u.com熱心網友回復:
在*a = 10;中,被宣告為float的b的記憶體被使用*a訪問,其型別為int。這違反了C 2018 6.5 7中的規則:
- 一種與物件的有效型別兼容的型別。 ...
它繼續列出了一些其他允許的情況,但是通過int型別改變float物件不在其中。因為違反了這一規則,C標準并沒有定義程式的行為。(C 2018 4 2:"如果違反了出現在約束或運行時約束之外的 "應 "或 "不 "的要求,則行為未被定義。")
盡管C標準沒有定義該行為,但在當前的編譯器中,有兩種結果是常見的:
- 編譯器知道值5.1(大約,轉換為
float后)被存盤在b中。所以它忽略了任何通過*a嘗試的改變,并在printf陳述句中對b使用5.1。 - 編譯器將
int值10存盤在用于b的記憶體中。后來,當它得到b時,int10的位被重新解釋為float。float型別的編碼方式與int型別不同,所以位000...0001010在float型別中代表一個非常小的數字。由于%lf的轉換在小數點后只產生六個數字,這個小數字被顯示為 "0.000000"。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/306951.html
標籤:
