簡體   English   中英

將float轉換為int指針,然后轉換為float?

[英]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的確切非隨機數。

如果這對您沒有意義,請讓我更清楚。 ay都指向相同的二進制值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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM