7

私はこれを試しました

char c[4];
int i=89;
memcpy(&c[0],&i,4);
cout<<(int)c[0]<<endl;
cout<<(int)c[1]<<endl;
cout<<(int)c[2]<<endl;
cout<<(int)c[3]<<endl;

出力は次のようになります:
89
0
0
0

これは私の胃のcuzをかなり訓練します私は数が0x00000059のようにメモリに保存されると思ったので、どうしてc [0]は89になるのですか?私はそれがc[3]にあるはずだと思った...

4

6 に答える 6

33

実行しているプロセッサはリトルエンディアンであるためです。マルチバイト基本型のバイト順序が入れ替わります。ビッグエンディアンのマシンでは、期待どおりになります。

于 2009-12-03T19:10:47.607 に答える
12

これは、リトルエンディアンのCPUでプログラムを実行しているためです。あちこちのエンディアンも参照してください

于 2009-12-03T19:11:35.720 に答える
9

ゴズが指摘したように、エンディアンネスは明らかに答えです。

ただし、それが何を意味するのかわからない場合は、例に表示されているバイトの順序が元のintの順序と同じであることを理解することも重要です。プラットフォームのエンディアンタイプに関係なく、Memcpyはバイト順序を変更しません。

于 2009-12-03T19:15:20.240 に答える
6

バイトオーダーは任意の設計上の決定であるためです。レジスタに入ると、バイトオーダー1はありません。

バイトオーダーは、バイトなどの小さなユニットをアドレス指定するときに発生します。これは、CPU設計者が行う本質的に恣意的な決定です。ビッグエンディアンまたはリトルエンディアンです。

状況を単純化し、バイト順であるのは主に周辺機器への接続であることを理解すると便利です。はい、証明したようにバイトアドレス指定を介して検出できますが、一般にスカラー値はユニットとしてレジスタにロードおよび格納され、この場合、バイト順序は何も変更しません。最上位ビットは、少なくとも、私たちが通常数字を書く方法の「左側」にあります。そのため、言語標準に従って使用した場合、<<および>>演算子は、ビッグエンディアンとリトルエンディアンのマシンで常にまったく同じ結果を生成します。

ただし、周辺機器へのデータストリームの読み取りと書き込みを行うには、バイトオーダーを選択する必要があります。これは、周辺機器が基本的にバイトストリームデバイスであるためです。最下位アドレスには最上位ビットがありますか、それとも最下位ビットがありますか?それは両方の方法で行われ、キャンプはかなり均等に分割されていました。

メモリ自体はバイトアドレス指定されているため、周辺機器なしでさまざまな動作を引き出すことは確かに可能ですが、これは通常、あなたが行ったように内部を意図的に覗き見しないと起こりません。

バイトがなく、32ビットワードのみが0、1、2としてアドレス指定されているCPUを想像してみてください。Cコンパイラは、char、int、およびlongのすべての32ビットオブジェクトを作成します。(これはCx9で許可されています。)うわー、バイトオーダーの問題はありません!両方です!しかし..最初の周辺機器を接続するとどうなりますか?


1.ええと、x86には小さなレジスタをエイリアスするレジスタがありますが、それは別の話です。

于 2009-12-04T05:21:32.613 に答える
2

マシンが異なればバイト順序も異なりますが、このコードを見て、バイトのレイアウト方法に応じて何が起こるかを考えてください。

long x = 89;
short *p = (short*)&x;
short y = *p;
于 2009-12-03T19:16:27.593 に答える
1

アプリケーションを移植可能にしたり、チーム内で開発したりする場合は、バグを見つけにくくなり、開発が長引くため、このロジックに従わないでください。

于 2009-12-03T20:34:27.833 に答える