C 語言預設會幫我們作一些型別轉換的動作, 一般的型別轉換不只會更換資料型別, 更會使資料內容有所變動, 例如:

    float   fVar = 1.2;
    int32_t iVar;

    iVar = fVar;    // iVar 值為整數 1

但是萬一我們不想要這個預設的換轉, 只是想要把 fVar 的數值 (以 float 格式) 存放在變數 iVar 所佔用的記憶體中, 而又不想動用 union 設定呢? (因為使用 union 程式或多或少都需要修改, 萬一 compiler 不支援 Unnamed Structure and Union Fields (或者 Anonymous unions, C11 的功能), 則需要更動的幅度就會更大.)

答案是: (取值)<-(指標轉型)<-(取址)

    // 寫在等號右手邊
    iVar = *(int32_t*)&fVar;
    // 或者, 寫在等號左手邊
    *(float*)&iVar = fVar;

或者是反過來, 想要把 iVar 的數值 (以int32_t 格式) 存放在變數 fVar 所佔用的記憶體中.

    // 寫在等號右手邊
    fVar = *(float*)&iVar;
    // 或者, 寫在等號左手邊
    *(int32_t*)&fVar = iVar;

(取值)<-(指標轉型)<-(取址) 看似很複雜, 其實只是告訴 compiler: 我要用 (新指定的方式) 存取原本變數所在的位址, 所以看似很複雜的 C 程式碼, 但是編譯出來的目的碼並不會膨脹, 也沒有轉來轉去的問題.

Compiler 不支援 Anonymous unions 時改用 union 程式無論是使用整數型態存取, 或者使用浮點數型態存取的部份都需要修改, 寫法如下:

    float fVar = 1.2;
    union {
        int32_t i;
        float   f;
    } iVar;

    iVar.f = fVar;   // 浮點數型態的要改
    iVar.i = 123;    // 整數型態的也要改

Compiler 有支援 Anonymous unions 時, 只需要更動使用浮點數型態存取的部份, 寫法如下:

    float fVar = 1.2;
    union {
        int32_t iVar;
        float   iVarf;
    };

    iVarf = fVar;   // 浮點數型態的要改
    iVar  = 123;    // 整數型態的不用改


相關文章:

    MagicJackTing 發表在 痞客邦 留言(1) 人氣()