【C言語入門】
union(共用体)の使い方

■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));
  }
}