2016-05-18 3 views
2

C言語のユニオンでエンディアンスワップを実行する方法を理解しようとしています。ユニオンには複数のタイプのデータを保持する機能がありますが、時間。私が理解しようとしているコードは以下のようになります。これはユニオンの定義です:C連合のエンディアンスワップ

union byte4 { 
      char byte[4]; 
      int numint; 
      float numfloat; 
    }; 

これは関数です。機能において

int endianSwap4int(int a) { 
     union byte4 un; 
     un.numint = a; 

     // swap 
     char c1 = un.byte[0]; 
     un.byte[0] = un.byte[3]; 
     un.byte[3] = c1; 
     c1 = un.byte[1]; 
     un.byte[1] = un.byte[2]; 
     un.byte[2] = c1; 

     return un.numint; 
    } 

、入力a関数がun.numintが返される6010を返し、2048327680である場合。私はun.byteの操作はun.numintを間接的に操作していることを理解しています。なぜなら、組合は一度に1つのものしか保持できないからです。

+0

共用体のすべてのメンバーは、非常に同じメモリ領域を共有します。彼らはアクセス時にのみ異なる解釈を提供します。バイト配列抽象化により、個々のバイトを簡単にシャッフルできます。同じメモリを参照するため、オーバーレイされた 'int'の値に直接影響します。 –

答えて

1

2048327680の16進表現を見ると、それは7A 17 00 00であることがわかります。したがって、マシンがこの値をリトルエンディアン形式で格納する場合、LSBが最初に格納されます。

次のように我々はendianSwap4intに追加のデバッグを追加する場合:あなたは、次の出力表示されます

int endianSwap4int(int a) { 
     union byte4 un; 
     int i; 
     un.numint = a; 

     printf("before:\n"); 
     for (i=0;i<4;i++) { 
      printf("un[%d]=%02X\n", i, un.byte[i]); 
     } 

     // swap 
     char c1 = un.byte[0]; 
     un.byte[0] = un.byte[3]; 
     un.byte[3] = c1; 
     c1 = un.byte[1]; 
     un.byte[1] = un.byte[2]; 
     un.byte[2] = c1; 

     printf("after:\n"); 
     for (i=0;i<4;i++) { 
      printf("un[%d]=%02X\n", i, un.byte[i]); 
     } 
     return un.numint; 
    } 

:ここ

before: 
un[0]=00 
un[1]=00 
un[2]=17 
un[3]=7A 
after: 
un[0]=7A 
un[1]=17 
un[2]=00 
un[3]=00 

を、あなたはLSB元の数のが最初であることがわかりますスワップの前に元の番号のMSBが最初にスワップされます。したがって、ユニオンのint部分には、00 00 17 7Aという値が含まれています。これは10進数で6010です。

+0

それは意味があります、ありがとうございます。 –