2016-04-04 11 views
-1

ポインタに関する質問です。私は宣言で、int* pn = &npnがメモリアドレスnへのポインタとして初期化されていることを知っています。しかし、なぜ我々はint pn = &nと言うことができないのですか?このように書いたのであれば、変数pnnのメモリ位置に設定することと同じではないでしょうか? *がなぜ必要なのか正確には分かりません。C言語のint * pn =&nとint pn =&nの違い

+0

これは言語の設計方法です。それがあなたが提案する方法で働くならば、それは混乱であろう。 –

+0

コンパイラはこのようなコードをコンパイルしようとしたときにヒントを与えませんでしたか? –

+0

このような基本的な質問はすべてのCの本によって答えられます。読んでください。 – Olaf

答えて

1

あなたの質問は次のようになります。アドレスが本当に整数である場合、Cにポインタ型があるのはなぜですか?これにはいくつかの理由があります。明らか

  • まず、アドレスバスは、システムの整数型とは異なるサイズのものであるかもしれないので、整数内側にフィットしない場合があります。副義として、タイプはintに署名されているので、アドレスは通常は署名されていないため、その理由のためにアドレスを格納することはおそらく不適切です。

  • しかし、私たちは明白な整数と大きく混乱することのない明確なポインタ型を必要としているからです。 Cは、整数とポインタの間で暗黙の変換を行わないようにします。 int pn = &nという行は、この型の安全性に違反するため実際にはコンパイルされません(「単純割り当て」ルール)。いくつかのコンパイラは、たとえそれがCの標準違反であっても、これに対してコンパイラエラーを与えることについて少しゆるやかです。 (GCCでは-pedantic-errorsがセットされていることを確かめてください)

    そして、私たちは別のポインタ型を持っているので、ポインタ型の演算を行うこともできます。これは便利です。例えば、ポインタを配列のように使用することができます。 uintptr_tintptr_t

近代Cは安全にアドレスを格納するために使用できる2つの新しい整数型を導入しています。これらは、安全にアドレスを格納するのに十分な大きさであることが保証されていますが、まだポインタ型へ/からの明示的な変換を使用する必要がありますされています

uintptr_t pn = (uintptr_t)&n; 

(エキゾチック例ところがありますがintptr_tは、穏やかに便利ですあなたは実際に負のアドレスを持っています。特定のシステム上のいくつかの仮想メモリアドレッシングは、負のアドレスを使ってカーネルアドレス空間を示すかもしれません。)

+0

ルンディンはこの有益な情報をありがとう!ほんとうにありがとう。 –

2

pnintの方のポインタであり、実際にはintではないことを指定します。ポインタのサイズはオブジェクトのサイズと同じではありません(ほとんどの場合)。詳細については、ポインタについて読んでください。

3

大きな違いは、最初のケースpnポインタであり、あなたは、配列のインデックスと間接参照演算子を使用することを含む、そのように使うことができるということです。

pnは普通のint変数です。その内容にはちょうどnのアドレスが含まれています。

アドレスが64ビット(8バイト)で、intが32ビット(4バイト)である64ビットシステムでは、2番目のケースも危険です。


詳細は、 "グラフィック" のように見ることができている:

コードを仮定し

int n = some value; 
int *p = &n; // Make p point to n 
int v = &n; // Initialize v to the address of n 

そして、それは

 
+---+  +---+ 
| p | ---> | n | 
+---+  +---+ 

+---+ 
| v | 
+---+ 

変数vのようなものはただ一人で座って見えます初期化された値を含んでいます。しかし、pnの位置に。

実際には、実際のハードウェアでは、pvの内容は同じです(プラットフォーム上ではsizeof(int) == sizeof(int *)が問題ではありません)。これは、コンパイラがこれらの異なる変数をどのように扱うかを示しています。

+0

これは完璧な説明です。ありがとうございました! –

4

なぜ*が必要なのか正確には分かりません。

ポインタと整数を区別するために、おそらく意味と機能が異なるためです。

1

int pn = &n;というステートメントは、コードCコンパイラで&を使用すると必ずアドレスを扱うことがわかります。他のより簡単な用語では、&はオペレータのアドレスであると言うことができます。

ステートメントでは、通常の整数変数を別のアドレスで初期化しようとしていますが、これは正しくありません。&nを書くと、nのアドレスで変数を初期化しようとしているとコンパイラは考えています。アドレスは通常の変数に格納できないので、変数はポインタにする必要があります。それが助けてくれることを願って。

関連する問題