■union(共用体)とは
簡単に言うと構造体のメンバを重ねて参照するものだ。
■union(共用体)を使った16bitスワップ
uint16_t bswap_16(uint16_t x){
union {
uint16_t bit16;
struct {uint8_t b1,b2;} bit8x2;
} y,z ;
y.bit16 = x ;
z.bit8x2.b1 = y.bit8x2.b2;
z.bit8x2.b2 = y.bit8x2.b1;
return z.bit16 ;
}
bit16とbit8x2を重ねて参照します。
■union(共用体)を使った32bitスワップ
uint32_t bswap_32(uint32_t x){
union {
uint32_t bit32;
struct {uint8_t b1,b2,b3,b4;} bit8x4;
} y,z ;
y.bit32 = x ;
z.bit8x4.b1 = y.bit8x4.b4;
z.bit8x4.b2 = y.bit8x4.b3;
z.bit8x4.b3 = y.bit8x4.b2;
z.bit8x4.b4 = y.bit8x4.b1;
return z.bit32 ;
}
bit32とbit8x4を重ねて参照します。
■union(共用体)を使った64bitスワップ
uint64_t bswap_64(uint64_t x){
union {
uint64_t bit64;
struct {uint8_t b1,b2,b3,b4,b5,b6,b7,b8;} bit8x8;
} y,z ;
y.bit64 = x ;
z.bit8x8.b1 = y.bit8x8.b8;
z.bit8x8.b2 = y.bit8x8.b7;
z.bit8x8.b3 = y.bit8x8.b6;
z.bit8x8.b4 = y.bit8x8.b5;
z.bit8x8.b5 = y.bit8x8.b4;
z.bit8x8.b6 = y.bit8x8.b3;
z.bit8x8.b7 = y.bit8x8.b2;
z.bit8x8.b8 = y.bit8x8.b1;
return z.bit64 ;
}
bit64とbit8x8を重ねて参照します。
■標準関数を使ったバイトスワップ
#include <stdio.h>
#include <stdint.h>
#include <byteswap.h>//★重要
#include <limits.h>
int main(void){
for(uint64_t i = 0x0123456789abcdef ; i != 0; i >>= 4){
uint16_t u16 = i;
uint32_t u32 = i;
uint64_t u64 = i;
printf("%04X -> %04X\t", u16, bswap_16(u16));
printf("%08X -> %08X\t", u32, bswap_32(u32));
printf("%016lX -> %016lX\n", u64, bswap_64(u64));
}
}
■union(共用体)を使ったスワップ(まとめ)
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
//16bit(2byte)をスワップする
uint16_t bswap_16(uint16_t x){
union {
uint16_t bit16;
struct {uint8_t b1,b2;} bit8x2;
} y,z ;
y.bit16 = x ;
z.bit8x2.b1 = y.bit8x2.b2;
z.bit8x2.b2 = y.bit8x2.b1;
return z.bit16 ;
}
//32bit(4byte)をスワップする
uint32_t bswap_32(uint32_t x){
union {
uint32_t bit32;
struct {uint8_t b1,b2,b3,b4;} bit8x4;
} y,z ;
y.bit32 = x ;
z.bit8x4.b1 = y.bit8x4.b4;
z.bit8x4.b2 = y.bit8x4.b3;
z.bit8x4.b3 = y.bit8x4.b2;
z.bit8x4.b4 = y.bit8x4.b1;
return z.bit32 ;
}
//64bit(8byte)をスワップする
uint64_t bswap_64(uint64_t x){
union {
uint64_t bit64;
struct {uint8_t b1,b2,b3,b4,b5,b6,b7,b8;} bit8x8;
} y,z ;
y.bit64 = x ;
z.bit8x8.b1 = y.bit8x8.b8;
z.bit8x8.b2 = y.bit8x8.b7;
z.bit8x8.b3 = y.bit8x8.b6;
z.bit8x8.b4 = y.bit8x8.b5;
z.bit8x8.b5 = y.bit8x8.b4;
z.bit8x8.b6 = y.bit8x8.b3;
z.bit8x8.b7 = y.bit8x8.b2;
z.bit8x8.b8 = y.bit8x8.b1;
return z.bit64 ;
}
int main(void){
for(uint64_t i = 0x0123456789abcdef ; i != 0; i >>= 4){
uint16_t u16 = i;
uint32_t u32 = i;
uint64_t u64 = i;
printf("%04X -> %04X\t", u16, bswap_16(u16));
printf("%08X -> %08X\t", u32, bswap_32(u32));
printf("%016lX -> %016lX\n", u64, bswap_64(u64));
}
}