誰でもここで何が起きているのか詳しく教えてください。ダブルポインタC
int main()
{
int **p = 0;
//p=? and why| *p=? and why|**p=? and why
++p;
//p=? and why| *p=? and why|**p=? and why
printf("%d\n", p);
return 1;
}
出力: -
- 4(?なぜ)
誰でもここで何が起きているのか詳しく教えてください。ダブルポインタC
int main()
{
int **p = 0;
//p=? and why| *p=? and why|**p=? and why
++p;
//p=? and why| *p=? and why|**p=? and why
printf("%d\n", p);
return 1;
}
出力: -
まず、p
は、整数へのポインタへのポインタです。= 0
int **p = 0;
p
、*p
=何も、**p
=何よりも少ないです。 Pと同じ
++p;
= P + 1のポインタ・ツー・INTさらに1つのポインタの径を意味します。ポインタは、基本的に、少なくともあなたのOS上では32ビット長(4バイト)です。 p
は0の後に4バイトを指すようになりました。p
の値はです。
それは明らかです。 intへのポインタへのポインタ(int **p
はintへのポインタへのポインタを意味します)は、実際にはのアドレス 0を保持します。アーキテクチャ内のポインタは32ビット(4バイト)なので、p
をインクリメントするとp + 4、つまり0 + 4 = 4となります。
算術。あなたはあなたの人生の残りの部分をうれしく思います! :)
「0 + 4 = 4」の場合+1 –
ちょっと!!このスタックオーバーフローは、優れたコンセプトを持つ人だけではありません。私はあまり知識がないかもしれませんが、自分のことがすべてうまくいって、このようなコメントをすることを意味するわけではありません。私は話しています(Cの本を手に入れてポインタ算術について学んでください。 ) –
私はまだポインタ算術に関する良いCの本から学ぶことでどこに問題があるか分かりません。あなたの質問から、あなたは十分にそのことを知らないと推測することができます。もしこれが失礼なのであれば申し訳ありません?私の意図はありませんでした。 –
p
は、int
へのポインタです。 0
に初期化されています。つまり、NULLポインタです。
メモリ内の次の連続ポインタ-をポイントするようにインクリメントされます。 *次のポインタはアドレス4になります。これは、プラットフォーム上でポインタのサイズが4バイトであるためです。
次に、printfはポインタ値を整数として解釈し、 "4"を表示します。
※ただし、これは未定義の動作です。
pはintへのポインタへのポインタです。そしてそれは0、すなわちNULLに初期化されます。あなたはそれをインクリメントすると
、それは今、32ビットシステムでは、4
++p
が実際に未定義の動作であることを起こるどの、intへの次のポインタを指しますが、何があなたの実装に起こったように見えますポインタのインクリメントは、UBではない場合、参照型のサイズに等しい数のバイトをアドレスに追加することを思い出してください。ですから、タイプint**
のヌルポインター(したがって参照タイプはint*
)を使用してインクリメントすると、アドレスは4
になります。それは保証されていないだけです。
%d
フォーマットはint
も未定義の動作です期待していますが、それは、int
とint**
の表現が十分に互換性があることが表示され、実装上の呼び出し規約可変引数は、それが成功していることを、十分に同様にそれらを扱う際にポインタを渡します4
と印刷されています。これは、sizeof(int) == sizeof(int**)
の実装ではそれほど驚くべきことではありませんが、保証されていません。
もちろん、定義されていない動作なので、他にも表示される可能性のある説明があります。
「なぜ」あなたも気になりました –
コードのコメントは私を混乱させます。 –
@Konrad:コードのコメントはコードの作成者を混乱させたと思います。 –