プラットフォームのエンディアンを知る方法はこのプログラムだと思いますが、理解できません
#include <stdio.h>
int main(void)
{
int a = 1;
if( *( (char*)&a ) == 1) printf("Little Endian\n");
else printf("Big Endian\n");
system("PAUSE");
return 0;
}
テストは何をしますか?
プラットフォームのエンディアンを知る方法はこのプログラムだと思いますが、理解できません
#include <stdio.h>
int main(void)
{
int a = 1;
if( *( (char*)&a ) == 1) printf("Little Endian\n");
else printf("Big Endian\n");
system("PAUSE");
return 0;
}
テストは何をしますか?
Anint
はほとんどの場合 1 バイトより大きく、多くの場合、アーキテクチャのワード サイズを追跡します。たとえば、32 ビット アーキテクチャには 32 ビットの int がある可能性があります。したがって、典型的な 32 ビット整数を考えると、4 バイトのレイアウトは次のようになります。
00000000 00000000 00000000 00000001
または最下位バイトを最初に:
00000001 00000000 00000000 00000000
char* は 1 バイトなので、このアドレスを char* にキャストすると、上記の最初のバイトが取得されます。
00000000
また
00000001
したがって、最初のバイトを調べることで、アーキテクチャのエンディアンを判断できます。
これは、sizeof(int) > 1
. char
例として、それが 2 で、aが 8 ビットであると仮定します。
基本的に、リトルエンディアンでは、16 ビット整数としての数値 1 は次のようになります。
00000001 00000000
しかし、ビッグエンディアンでは、次のようになります。
00000000 00000001
したがって、最初にコードが設定a = 1
され、次に次のようになります。
*( (char*)&a ) == 1)
のアドレスをa
取得し、それを へのポインタとして扱いchar
、逆参照します。そう:
a
リトル エンディアンの整数が含まれている場合は、00000001
セクションを取得します。char
a
ビッグエンディアンの整数が含まれている場合は、00000000
代わりに取得します。のチェック== 1
は失敗し、コードはプラットフォームがビッグエンディアンであると想定します。
int16_t
andint8_t
の代わりにint
andを使用すると、このコードを改善できますchar
。またはさらに良いことに、かどうかを確認してくださいhtons(1) != 1
。
a
char*
char*
が得られますint
1
、リトルエンディアンです。そうでなければ - 大きい。とするとsizeof(int) == 4
、次のようになります。
|........||........||........||........| <- 4bytes, 8 bits each for the int a
| byte#1 || byte#2 || byte#3 || byte#4 |
ステップ 1、2、および 3 が実行されると*( (char*)&a )
、最初のバイトが得られます| byte#1 |
。
次に、の値を確認することで、byte#1
ビッグ エンディアンかリトル エンディアンかを理解できます。
01 00 00 00
とビッグ エンディアンが含まれ00 00 00 01
ます。&a
することで、その配列の最初の要素のアドレスを取得します。(char*)&a
は、それを 1 バイトのアドレスにキャストします。*( (char*)&a )
に、そのアドレスに含まれる値を取得します。a = 00000000 00000000 00000000 00000001
^ ^
| |
&a if big endian &a if little endian
00000000 00000001
^ ^
| |
(char*)&a for BE (char*)&a for LE
*(char*)&a = 0 for BE *(char*)&a = 1 for LE
分解方法は次のとおりです。
a -- given the variable a
&a -- take its address; type of the expression is int *
(char *)&a -- cast the pointer expression from type int * to type char *
*((char *)&a) -- dereference the pointer expression
*((char *)&a) == 1 -- and compare it to 1
基本的に、キャスト(char *)&a
は式の型をへの&a
ポインターからint
へのポインターに変換しchar
ます。逆参照演算子を結果に適用すると、 の最初のバイトに格納されている値が得られますa
。
int
プログラムは、an が占めるスペースを s の配列として再解釈し、int が一連のバイトとして格納されるchar
と想定します。その最下位の順序は値 1 のバイトであり、残りは 0 です。1
したがって、最下位バイトが最初に発生する場合、プラットフォームはリトル エンディアンであり、それ以外の場合はビッグ エンディアンです。
これらの仮定は、存在するすべてのプラットフォームで機能するとは限りません。
*( (char*)&a )
int i=1 (サイズ 4 バイト) の BigEndian データは、次のようにメモリ内に配置されます:- (下位アドレスから上位アドレスへ)。
00000000 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000001 -->Address 0x103
LittleEndian は:-
00000001 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000000 -->Address 0x103
上記のキャストの分析:-
また&a= 0x100
、
*((char*)0x100)
0x100 のデータが参照されるように、1 バイト (int に 4 バイトがロードされるため) を使用することを検討することを意味します。
*( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian.