次のようなポインタがあります。
int val2 = 90;
int *p = &val2;
次に、私は:
int *pp = &p; // Line 3
はLine 3
違法です。と書かれているはずですがint **pp = &p
、その理由がわかりません。通常の変数のアドレスとポインタのアドレスが違うのですか?
次のようなポインタがあります。
int val2 = 90;
int *p = &val2;
次に、私は:
int *pp = &p; // Line 3
はLine 3
違法です。と書かれているはずですがint **pp = &p
、その理由がわかりません。通常の変数のアドレスとポインタのアドレスが違うのですか?
int *pp
pp
はへのポインタとして定義されていますが、 のアドレスではなくint
へのポインタのアドレスで初期化しようとしています。「int のアドレス」と「int へのポインターのアドレス」は同じ型ではないため、コンパイラーはこれを行うことを許可しません (少なくともキャストなしでは、ほぼ確実にそうしたくないでしょうが)。それを行う)。int
int
はい、2 種類のポインターはおそらく同じサイズであるため、CPU はデータをある場所から別の場所に移動しても問題はありません。ただし、コンパイラは型チェックを行って、自分自身を傷つけないようにしています。それが、ここで行っていることです。上記のキャストで求めていることを実行できますが、実行していることはほとんどまたはまったく意味がないため、本当にそれを行う必要がある場合はキャストを使用する必要があります.
静的タイプチェッカーの場合はい。実装の観点からはありません。
タイプチェックでは、割り当てて渡すものが、宣言方法に関して正しいことを確認する必要があるため、拒否する必要があります。
int *pp = &p;
pp
なぜなら、intへのポインタへのポインタをそこに格納しようとしているときにintへのポインタとして宣言しているからです。何かへのポインタと他の何かへのポインタに違いがない場合でも、特定の型として宣言した場合にチェックされる型には違いがあります。
大多数のプラットフォームでは、すべてのポインタはメモリ内で同じもの、つまりメモリ内の別の場所のアドレスです。この問題は、ほとんどの場合、コンピューターが正しい使用法を適用できるように、タイプ セーフにしようとする問題です。
それらを間違った型として格納する必要がある場合は、異なるポインター型の間でいつでも型キャストできます。
整数へのポインタを作成しているため、コンパイラは整数のアドレスを割り当てることを期待しています。代わりに、整数ではなくポインターのアドレスを割り当てています。コンパイラが int を探す場所を知るには、2 番目のアスタリスクを追加して、pp がメモリ アドレスを指し、それが int を指すことをコンパイラに伝える必要があります。