[英]Casting float to int pointer and back to float?
可以給我解釋一下我試圖了解其行為的C程序的行為嗎...
#include<stdio.h>
float x = 3.33,*y,z;
int *a,b;
int main() {
a = (int *)&x;
b = (int)x;
y = (float *)a;
z = (float)b;
printf("\nOriginal Value of X: %f \ncasting via pointer A:%d and back Y: %f \ndirect casting B:%d and back Z:%f\n",x,*a,*y,b,z);
}
輸出:
Original Value of X: 3.330000
casting via pointer A:1079320248 and back Y: 3.330000
direct casting B:3 and back Z:3.000000
好的,為什么A
的值是1079320248
,為什么它不是某個隨機值,對於X = 3.33
,它始終是相同的,並且如果X
更改為某個其他值(我希望像A
值是3
,它也會改變。
您的代碼中沒有發生“通過指針A進行廣播”這樣的事情。 您只是在強迫編譯器將a
指向一個浮點值,假定該值指向整數。
使用Reymond Chen在評論部分中指出的頁面 ,我們得到3.33的二進制表示形式:
01000000010101010001111010111000
現在,使用此頁面查找其32位有符號整數等效項。 您將獲得1079320248
,這是使您感到1079320248
的確切非隨機數。
如果這對您沒有意義,請讓我更清楚。 a
和y
都指向相同的二進制值01000000010101010001111010111000
,該二進制值表示兩個不同的值(float為3.33,int為1079320248),具體取決於您告訴編譯器使用的數據類型。
更新:
僅出於學術目的,如果您希望printf語句為A
打印3,則將第三個參數替換為:
(int) *((float *)a)
TL; DR將指針強制轉換為其他不兼容的類型,然后再訪問最后一個,這是可以的,當您嘗試使用不兼容類型的中間指針時,問題就開始了。
詳細地說,您的代碼會導致未定義的行為,因為您違反了嚴格的別名規則。
引用C11
,第6.5節
一個對象只能通過具有以下類型之一的左值表達式訪問其存儲值: 88)
—與對象的有效類型兼容的類型,
—與對象的有效類型兼容的類型的限定版本,
—一個類型,它是與對象的有效類型相對應的有符號或無符號類型,
—一種類型,是與對象的有效類型的限定版本相對應的有符號或無符號類型,
—集合或聯合類型,其成員中包括上述類型之一(遞歸地包括子集合或包含的聯合的成員),或
—字符類型。
因此,對於您來說,對於像
float x = 3.33,*y,z;
//....
a = (int *)&x;
b = (int)x;
y = (float *)a;
首先要根據第6.3.2.3/P7章中提到的規則,將指針轉換為float
,然后再將其轉換為float *
指向對象類型的指針可以轉換為指向不同對象類型的指針。 如果對於所引用的類型,結果指針未正確對齊68) ,則該行為未定義。 否則,當再次轉換回時,結果應等於原始指針。 [...]
因此,訪問y
是可以的,但不能訪問a
。 您將面臨對齊不匹配的情況,這將導致UB。 不要嘗試這樣做。 尊重類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.