1

C/C++ のような言語では、次のようにします。

char c = 'A';

数値 65 を 2 進数で格納するためにメモリを割り当てます。

stuff_to_the_left_01000001_stuff_to_the_right

次に、次のようにします。

int i = (int) c;

私が理解しているように、私たちはコンパイラに、ビットパターンを として解釈するように言っていますstuff_to_the_left_01000001__00000000_00000000_00000000_stuff_to_the_right

操作中にキャストを実行すると、同じことが起こります

cout << (int) c << endl;

上記のすべてで、文字の「A」と10進数の65を取得しました。私は幸運なのだろうか、それとも根本的な何かが欠けているのだろうか?

4

5 に答える 5

2

C のキャストは、何も再解釈しません。それらは値の変換です。(int)cは、 の値を取得してcに変換することを意味intします。これは、基本的にすべてのシステムでノーオペレーションです。(ノーオペレーションに失敗する唯一の方法は、 の範囲がcharの範囲より大きい場合intです。たとえば、charintが両方とも 32 ビットであるcharが符号なしの場合です。)

値の基礎となる表現 (ビット パターン) を再解釈する場合、その値は、式の値 (通常は "rvalue" と呼ばれますが、この言語は C 標準では使用されません) だけでなく、最初にオブジェクト (左辺値) として存在する必要があります。 )。次に、次のようなことができます。

*(new_type *)&object;

ただし、 が文字型の場合を除いてnew_type、これはエイリアシング規則に違反することにより、未定義の動作を引き起こします。C++ には、これを行うための一種の「再解釈キャスト」があり、おそらくエイリアシング ルールの違反を回避できますが、私は C++ に精通していないため、詳細を提供することはできません。

C++ の例では、異なる結果が得られる理由は演算子のオーバーロードです。(int)'A'値やその解釈方法は変更しません。むしろ、異なる型を持つ式により、operator<<関数の異なるオーバーロードが呼び出されます。一方、C では、C で始まる型が(int)'A'あるため、常にノーオペレーションです。'A'int

于 2012-08-11T02:37:28.673 に答える
2

私は幸運なのだろうか、それとも根本的な何かが欠けているのだろうか?

はい、何か基本的なことが欠けています。コンパイラはchar、メモリが を表すかのように、メモリから を読み取りませんint。代わりに、chara を char として読み取り、値を an に収まるように符号拡張するintため、同様にchar -1なりint -1ます。符号拡張とは、その数値の符号ビットに応じて、拡張される最上位バイトの左側に1s またはs を追加することを意味します。0符号なしの型には常にゼロが埋め込まれます*

符号拡張は通常、専用のハードウェア命令を実行することによってレジスターで行われるため、非常に高速に実行されます。


* Eric Postpischilがコメントで指摘したように、C の実装によっては、型charが符号付きまたは符号なしの場合があります。

于 2012-08-11T02:40:56.263 に答える
0

コードでは、「i」には独自のアドレスがあり、「c」には独自のアドレスがあります。値はcからiに「コピー」されています。「(int)c」についても同様です。コンパイラは私たちのためにそれを行いますが、次のように。

     |--- i ---|- c-|  
 0x01 0x02 0x03 0x04
+--------------------......
| 00 | 00 | 08 | 08 |......  
+--------------------......

これがポインタベースの割り当てだったとしたら、あなたは正しかったでしょう。

例えば

 0x01 0x02 0x03
+---------------......
| 07 | 10 | 08 |......
+---------------......
int *p;
char c = 10;
p = &c;
print(*p); //not a real method just something that can print.

ここで、*pはmemアドレス0x02と0x03からの値を組み合わせたものになります。

于 2012-08-11T02:48:39.037 に答える
0

char を割り当てると、左または右に詰め込むようなものはありません。それは 8 ビットであり、それ以上のものではありません。したがって、8 ビット値を 32 ビットにキャストしても、65 になります。

0100.00010000.0000 0000.0000 0000.0000 0100.0001

魔法も運もありません。

于 2012-08-11T02:40:33.057 に答える
-1

つまり、この動作は、コンパイル先のプラットフォームと使用しているコンパイラーによって変わる可能性があります。

ISO規格では、(int)をキャストとして定義しています。この場合、コンパイラは(int)cをstatic_cast(c)// inc++のように解釈します。

幸運なことに、コンパイラは(int)を単純なキャストとして解釈します。これはどのc/c ++コンパイラでも一般的な動作ですが、名前のないc ++コンパイラがいくつか存在する可能性があります。これにより、そのコンパイラでキャストが再解釈され、予測できない結果になります(プラットフォームによって異なります)。

そのため、static_cast(c)を100%shureにする必要があります。それを再解釈したい場合は、もちろんreinterpret_cast(c)

ただし、これも通常はcスタイルのキャストであるため、cは整数にキャストされます。

于 2012-08-11T02:46:15.513 に答える