2

ここで小さな問題に遭遇しました。unsigned char 配列があり、バイト 2 ~ 3 (0xFFおよび0xFF) にアクセスして、その値を short として取得しようとしています。

コード:

 unsigned char Temp[512] = {0x00,0xFF,0xFF,0x00};
 short val = (short)*((unsigned char*)Temp+1)

私は val が含まれていることを期待していますが0xFFFF、実際には含まれています0x00FF。私は何を間違っていますか?

4

4 に答える 4

7

shortデータが正しく配置されていない場合に にアクセスできるという保証はありません。

一部のマシン (特に RISC マシン) では、バス エラーとコア ダンプが発生し、アクセスが正しく整列されていませんでした。他のマシンでは、ミスアラインされたアクセスは、エラーを修正するためにカーネルへのトラップを伴います。これは、コア ダンプよりもわずかに高速です。

確実に結果を得るには、シフトおよびまたはを行うのが最善です。

val = *(Temp+1) << 8 | *(Temp+2);

また:

val = *(Temp+2) << 8 | *(Temp+1);

これは、データのビッグ エンディアン (最初のオプション) またはリトル エンディアン (2 番目) の解釈を明示的に提供することに注意してください。

<<|;の慎重な使用にも注意してください。+の代わりに使用する場合|は、シフト式を括弧で囲むか、シフトの代わりに乗算を使用する必要があります。

val = (*(Temp+1) << 8) + *(Temp+2);
val = *(Temp+1) * 256 + *(Temp+2);

論理的であり、混合ではなく、論理または算術のいずれかを使用します。

于 2012-04-18T13:40:33.003 に答える
6

さて、あなたはあなたが間接参照unsigned char*すべきときに間接参照しているshort*

私はこれがうまくいくと思います:

 short val = *((short*)(Temp+1))
于 2012-04-18T13:37:06.217 に答える
4

問題は、配列の1バイトにしかアクセスしていないことです。

  • *((unsigned char*)Temp+1)Temp+1あなたに与えるポインタを間接参照します0xFF
  • (short)*((unsigned char*)Temp+1)逆参照の結果をにキャストしshortます。ショートにキャストunsigned char 0xFFすると明らかに0x00FF

だからあなたがやろうとしているのは*((short*)(Temp+1))

ただし、あなたがしていることは恐ろしいハックであることに注意する必要があります。まず第一に、あなたが異なっているときchars、結果は明らかにマシンのエンディアンに依存します。

第二に、アクセスされたデータがショートとしてアクセスされるように正しく整列されているという保証はありません。

したがって、アーキテクチャのエンディアンのようなものを実行するか、それに応じてshort val= *(Temp+1)<<8 | *(Temp+2)実行する方がよい場合があります。short val= *(Temp+2)<<8 | *(Temp+1)

于 2012-04-18T13:37:26.407 に答える
1

このアプローチはアーキテクチャ固有であるため、お勧めしません。

次の の定義を検討してくださいTemp

unsigned char Temp[512] = {0x00,0xFF,0x88,0x00};

システムのエンディアンに応じて、 ;にキャストTemp + 1すると、異なる結果が得られます。short *リトルエンディアン システムでは、結果は value0x88FFになりますが、ビッグ エンディアン システムでは、結果は になります0xFF88

また、アライメントの問題により、これは未定義のキャストだと思います。

使用できるものは次のとおりです。

short val = (((short)Temp[1]) << 8) | Temp[2];
于 2012-04-18T13:43:00.050 に答える