次のコードを検討してください。
int a=100;
int *p1=&a,**p2=&p1;
char *p3=&a,**p4=&p3; //Here *p1,*p3,**p2,**p4 all return 100
p4=&p1;
p2=&p3;
*p1
、*p3
、**p2
および**p4
すべて 100 を返します。
ポインタを整数と文字で指定する意味を知りたいです。
次のコードを検討してください。
int a=100;
int *p1=&a,**p2=&p1;
char *p3=&a,**p4=&p3; //Here *p1,*p3,**p2,**p4 all return 100
p4=&p1;
p2=&p3;
*p1
、*p3
、**p2
および**p4
すべて 100 を返します。
ポインタを整数と文字で指定する意味を知りたいです。
ポインターの型によって、ポインター先のデータのサイズとレイアウトに関してコンパイラーが行う仮定が決まります。あなたの例では:
char *p3=&a
&a
値を保持すると想定されるため、char
長さは 1 バイトです。int
anは少なくとも 2 バイトの長さ (そして通常は 4 バイトの長さ) であるため、これはもちろん正しくありません。それでも値 100 が得られる理由は、バイトがリトルエンディアン形式で格納されている Intel 互換の CPU でこのコードを実行している可能性が高いためです。この形式では、最下位バイトが最後ではなく最初に格納されます。値が 100 の 4 バイト整数は、次のように格納されます (16 進表記):
0x64 0x00 0x00 0x00
p3
このシーケンスの最初のバイトを指します。したがって、 が指すメモリにはp3
、値が 100 のバイトが含まれます。このレイアウトで値を使用する場合:
0x00 0x64 0x00 0x00
これは 25600 です:
int a=25600;
*p3
最初のバイトのみが考慮されるため、得られる値は 0 です。
それに加えて、 の値*(p3+1)
は 100 です。これは、ポインターを 1 インクリメントするchar
と、次のバイト (値は 100) へのポインターになるためです。*(p1+1)
これは、 の 4 バイト後にあるメモリ アドレスを取得する とは異なりますp1
。