-1

C/C++ が下手だとは言えませんが、興味深い構文に遭遇しました。私はこのコードを持っています:

int i=7;
char* m=(char*)&i;
m[2]=9;
cout<<i;

その出力は589831です。誰かがここで何が起こっているのかを詳しく説明できますか.

4

5 に答える 5

3
  1. 4 バイトの整数には 7 が入ります。
  2. 4 バイトの整数は、4 つの単一バイト (char) の配列にマップされます。x86 のようなリトル エンディアン アーキテクチャでは、最下位バイトが最初に来るため、配列はメモリ内で次のようになります。{ 07, 00, 00, 00 }
  3. 整数スラッシュ バイト配列の 3 番目のバイトが 9 に変更されます。これは次のようになります。{ 07, 00, 09, 00 }
  4. 結果の整数 (16 進数 90007) が stdout に書き込まれます (10 進数形式: 589831)。

簡単に言えば、これはマルチバイト整数で個々のバイトを操作する方法の例です。

于 2012-12-02T23:01:02.863 に答える
3

整数iはおそらく 4 バイトで、最初に最小値 (リトル エンディアン) で配置されます。メモリでは、値は次のようになります。

0x07 0x00 0x00 0x00

インデックス 2 の値を変更したので、次のようになります。

0x07 0x00 0x09 0x00

バイトを逆にして元に戻すと、16 進数の 0x00090007 になり、10 進数の 589831 と同じになります。

于 2012-12-02T23:06:35.100 に答える
1

整数アドレスを にキャストし、char*配列表記を使用して変更しています。このステップ

m[2] = 9;

ポインタ演算と同じ

*(m+2) = 9;

つまり、アドレスm+ 2 バイトのバイトを変更しています。したがって、初期整数値のバイトの 1 つ (3 番目) を変更しました

于 2012-12-02T23:01:13.657 に答える
1

これが何が起こっているかの私の内訳であり、次に説明です。

// An integer on the stack, probably 4 bytes big, but we can't say that for sure.
int i=7; // Looks like 0x0000007 in memory. Endianness needs to be considered.

// Treat that integer as a \0 terminated string.
char* m=(char*)&i; // Acts as an empty string since the first byte is a 0, but we can't count on that.

// Set the second byte to 9.
m[2]=9; // Results in i being 0x00090007 (589831 decimal) on whatever architecture you are running. Once again, can't count on it.

// Print the modified integer.
cout<<i;

これは、3 つの理由から、信じられないほど危険で愚かなことです...

  1. アーキテクチャのエンディアンを当てにするべきではありません。あなたのコードは、 が何であるかの基本的な表現が異なる CPU で実行される可能性がintあります。

  2. int常に 4 バイトであるとは期待できません。

  3. これで、文字列操作を実行するとクラッシュする可能性があるchar*ことがわかりました。あなたの特定のケースでは、空の文字列を出力しますが、その整数に 0 バイトが含まれておらず、スタックの他の部分を読み続けるのにそれほど時間はかかりません。

本当に、本当に、本当にこれを行う必要がある場合、推奨される方法はユニオンを使用することですが、この種のちょっとしたいじりは非常にエラーが発生しやすく、ユニオンはほとんど役に立ちません。

于 2012-12-02T23:17:38.747 に答える
0

int i=7整数用に4バイトのメモリを予約し、CPUアーキテクチャに応じて(あなたがi86であるとしましょう)、メモリ内にこのようなものを生成します 7 0 0 0

次に、 の先頭を指すように作成されたポインター m 7 0 0 0。afterm[2] = 9メモリは次のようになります 7 0 9 0(配列はゼロベースです);

次に、私を印刷します

于 2012-12-02T23:11:52.700 に答える