6

これはこの投稿のフォローアップですが、別の質問があるため、別のスレッドで質問する必要があると感じました.

私は、ファイルから読み込んだメモリに 4 つの連続したバイトがある時点にいます。これらをビット配列として保存したいと思います (それらの実際の int 値は後で問題になりません)。int の内容を出力すると、逆順 (リトルエンディアン) で格納されているように見えます。

バイトの順序を逆にする良い方法はありますか。次に、一度逆にして、2 バイトにまたがる連続したビットを取り出し、int に変換しますか?

unsigned char data[] = { 0x00, 0x02, 0x45, 0x28 };
NSInteger intData = *((NSInteger *)data);

NSLog(@"data:%08x", intData); // data:28450200
4

1 に答える 1

16

Cocoa (正確には Foundation フレームワーク) には、バイトのエンディアンを交換する関数があります: NSSwapIntNSSwapShortNSSwapLong、およびNSSwapLongLong. これらは何があってもバイトを交換します-スモールエンディアンの整数からビッグエンディアンの整数を作成し、その逆も同様です。

使用している形式がわかっている場合は、それをネイティブのエンディアンに交換する他の関数があります:NSSwapLittleIntToHostおよびNSSwapBigIntToHost. ネイティブ形式からリトルエンディアン形式またはビッグ エンディアン形式にスワップする逆関数もありNSSwapHostIntToLittleますNSSwapHostIntToBig。これらは、他の整数型と浮動小数点型にも使用できます。彼らが行うことは、必要に応じて値に対してプリミティブ スワップ関数を呼び出すことです。そのため、リトルエンディアン マシンでの結果を返すNSSwapLittleIntToHostwhile は何もしません。NSSwapBigIntToHostNSSwapInt

これらは、型ではなく、コンパイラの整数型のパラメーターを取ることに注意してくださいNSInteger。したがって、生成するコードが 32 ビットか 64 ビットかに応じて、使用している場合は異なる関数を使用する必要がありますNSInteger

また、バイト配列を整数ポインターにキャストして逆参照しないでください。ビットシフト操作を使用して整数を組み立てる方がよいでしょう。コードNSIntegerは 32 ビット幅の場合にのみ機能します。64 ビットの場合、数値がガベージになるか、プログラムがクラッシュすることさえあります。ただし、常に 32 ビット幅の整数型 (たとえばint32_t、C99 ヘッダーから)を使用している場合でも、これは期待どおりに機能しない可能性があります。<stdint.h>

于 2010-09-30T13:41:34.607 に答える