理解できない異なる結果を実際に出力する2つのフォームがあります
int x = *(int*)&M[index]
に比べ
int x = (int)M[index]
誰かが私に違いを説明できますか?
理解できない異なる結果を実際に出力する2つのフォームがあります
int x = *(int*)&M[index]
に比べ
int x = (int)M[index]
誰かが私に違いを説明できますか?
M のデータ型が int[] でない場合、それらは異なる可能性があります。2 つの (16 ビット) short の配列、0x0123 と 0x4567 があるとします。メモリ レイアウト (ビッグ エンディアン) は次のようになります。
0x01 0x23 0x45 0x67
M[0] を使用した後者の場合、M[0] を読み取って整数 0x00000123 に変換するため、short を整数に正しく割り当てます。
最初のケースでは、M[0] のアドレスを取得し、メモリ内に整数があると仮定します。これを 32 ビット整数型で指定すると、結果は 0x01234567 になります (つまり、4 バイトすべてが読み取られます)。
2番目の値は値をintにキャストします。これは、意味のある方法で値を変換することを意味します(キャストが不可能な場合はエラーが発生します)。最初の値は、メモリ内の場所からsizeof(int)バイトを取得し、これは意味がないかもしれませんが、intとしてそれらを。
例えば:
double a[10];
a[5] = 281907.2389727;
int x = *(int*)&a[5];
int y = (int)a[5];
printf("%d %d", x, y);
(私のマシン/コンパイラで)出力します:
-189447571 281907
キャスト(int)はdoubleを切り捨て、*(int *)はdoubleの最初のsizeof(int)バイトを取得し、整数であると「ふり」するため、これはもちろん意味のある結果にはなりません。サイズとバイナリ表現が異なるためです。
前者は、&M[index]
あたかもint
そこに格納されているかのようにメモリのバイトを解釈し、それを提供しますint
。
後者は の数値を取り、M[index]
それを に変換しint
ます。
M[index]
がタイプの場合int
、明らかに違いはありません。
わからないのはどの部分ですか?
最初の式は 2 つの式で構成されています: ポインター逆参照と、ポインターに評価される式です。*(int *)
は最初の部分であり、後に続く必要があるポインターを参照し、&M[index]
単に「配列 M` の index:th 要素のアドレス」を意味します。
M
どちらの例でも、が配列であると仮定するとint
、キャストは完全に不要であり、削除する必要があります。以下を使用することもできます。
int x = *(&M[index]);
この形式には、2 つの部分がより明確になるという追加の利点があります。最初の部分は*
括弧の外側の演算子であり、2 番目の部分は括弧内のコードです。
また
int x = M[index];
後者の形式が好まれます。明確で要点が明確です。