コンパイラが何をしているのかわかりません++*p;
誰かがこのコードのメモリ内で何が起こっているのかを絵で説明できますか?
int main()
{
int arr[]={1,2,3,4};
int *p;
p=arr;
++*p;
printf("%d",*p);
}
答えは2でなければなりません
理由は、++*pが実際には配列の最初のメンバーを1つインクリメントしているためです。
要素を指す別のintポインターを作成して、その配列の最初の要素をインクリメントしてp
います。この線
++*p
pが指すオブジェクトの値をインクリメントします。この場合は、配列の最初の要素です。
この行を見てみましょう:
++*p
これにより、最初にpポインターが逆参照されるため、arr [0]にアクセスしてから、インクリメントします。
ここでarr[0]を印刷すると、2になります。
次に、arr[0]の印刷と同じ*pを印刷します。これは2に等しくなります。
最初の要素を41に置き換えてみてください。コードは、42を出力します。
ポインタがある場合int *p
、p
は「メモリアドレスがp
指す」を*p
意味し、「を指すメモリアドレスの内容」を意味しますp
。++
プレインクリメントを意味し、値を1つ増やすことを意味します*
。++
(プレフィックス演算子)は右から左であり、右から左にトラバースした場合よりも*
近く、前に動作します。したがって、「インクリメントしてから値を取得する」ではなく、「ポイントする値をインクリメントする」を意味します。より明確です。書くが、それは同じことを意味する。p
++
*
++
++*p
p
p
++(*p)
理解しておくべきことは、別の値を指すことを意味する「ポインタをインクリメントする」(例++p
)と「ポインタが指す値をインクリメントする」(例++*p
)の違いです。
あなたはこれを解決することができます、しかしそれはあなたがそれを理解するために必要なすべての情報です。
実際のメモリアドレスを作成し、メモリアドレスに「ma」を使用する
1000から始まるメモリアドレスには、4つの連続した4バイト(sizeof(int)= 4)スロットがあります。各スロットには、配列初期化子で指定された整数値が含まれています。
arr
ma1000 ... ma1015
_____________________
| 1| 2| 3| 4|
_____________________
arrは、4つのintスロットの開始アドレスとその数を示します。pは整数のアドレスを保持し、場所2000にあるメモリ内の1つの8バイトスロットを参照します(ポインタが8バイトの64ビットシステム上にあると仮定します-64アドレスビット/ 8ビット/バイト)。ステートメントの後p = arr、pはアドレス1000を保持します
p *p or arr[0]
ma2000 .. ma2007 ma1000 .. ma1003
__________ ________
| 1000| | 1 |
__________ ________
* pは、pが指すメモリアドレスの値を示します。pはメモリアドレス1000を保持し、メモリアドレス1000には1が含まれるため、*pは1になります。
++ * pは、「ポイントされた」intの値をpだけインクリメントすることを意味します。pは、値1を保持するメモリアドレス1000を保持します。アドレス1000の値は、1から2になります。
arr
ma1000 ... ma1015
_____________________
| 2| 2| 3| 4|
_____________________
次に、printfは、pが「指す」アドレスのint値(2)を出力します。
p *p or arr[0]
ma2000 .. ma2007 ma1000 .. ma1003
___________ ___________
| 1000| | 2|
___________ ___________
これは、ポインタを理解する上での非常に基本的な概念です。
p = arr ;
上記のコードは、「arr」が指しているものを指すポインタ「p」を作成します。「arr」自体は1番目の要素を指しています。
*arr = *(arr + 0) = arr[0] = 1
*(arr + 1) = arr[1] = 2
*(arr + 2) = arr[2] = 3
など...だから今あなたがするとき++(*arr) that means ++(1) = 2
としてp = arr
、残りの置換と計算を行うことができます。