2013-04-02 20:01:51Morris

[C/C++] union&bit field 回顧

union 這個結構中的所有位址都指向相同記憶體。
想像組合語言的 reverse order 的儲存方式,一個 byte(8bits)的倒序儲存。


所附代碼的輸出:
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111100000000
0100000000101000011101111100111011011001000101101000011100101011



原本老師是說為了同時具有 static type checking, dynamic type checking,
但由於如 float point 的儲存方式比較特殊, 因此也沒有辦法做得很好。

如圖就可以看出來,要找到 double, float 的儲存方式是很容易的。
作業困擾你轉換嗎?寫這個短短的程式就可以了。

同時要記住,如果修改型態較小的數據時,會保留沒用到的高位元內容。


#include <stdio.h>
union S {
    int Integer;
    char Character;
    double Double;
    float Float;
    unsigned long long ULL;
    long long LL;
} V;
int main() {
    V.LL = -1;
    for(int i = 63; i >= 0; i--)
        printf("%d",(V.ULL>>i)&1);
    puts("");
    V.Character = 0;
    for(int i = 63; i >= 0; i--)
        printf("%d",(V.ULL>>i)&1);
    puts("");
    V.Double = 12.234;
    for(int i = 63; i >= 0; i--)
        printf("%d",(V.ULL>>i)&1);
    puts("");
    return 0;
}

位元欄位(bit field)可以控制每個變數的 bit 數,所附程式只有用 1,實際上可以改別的值。
與 union 同時使用時, 可以直接查看該位元為何

範例輸出:
A(65)
0100-0001




懶得用 loop 轉 binary number, 這樣也可以的。


#include <stdio.h>
struct bitfield {
    unsigned int s0:1;
    unsigned int s1:1;
    unsigned int s2:1;
    unsigned int s3:1;
    unsigned int s4:1;
    unsigned int s5:1;
    unsigned int s6:1;
    unsigned int s7:1;
};
union NUM {
    char word;
    bitfield bit;
};
int main() {
    NUM n;
    n.word = 65;
    printf("%c(%d)\n", n.word, n.word);
    printf("%d%d%d%d-%d%d%d%d\n", n.bit.s7, n.bit.s6, n.bit.s5, n.bit.s4
           , n.bit.s3, n.bit.s2, n.bit.s1, n.bit.s0);
    return 0;
}