ポインタに関する質問です。私は宣言で、int* pn = &n
、pn
がメモリアドレスn
へのポインタとして初期化されていることを知っています。しかし、なぜ我々はint pn = &n
と言うことができないのですか?このように書いたのであれば、変数pn
をn
のメモリ位置に設定することと同じではないでしょうか? *
がなぜ必要なのか正確には分かりません。C言語のint * pn =&nとint pn =&nの違い
答えて
あなたの質問は次のようになります。アドレスが本当に整数である場合、Cにポインタ型があるのはなぜですか?これにはいくつかの理由があります。明らか
まず、アドレスバスは、システムの整数型とは異なるサイズのものであるかもしれないので、整数内側にフィットしない場合があります。副義として、タイプは
int
に署名されているので、アドレスは通常は署名されていないため、その理由のためにアドレスを格納することはおそらく不適切です。しかし、私たちは明白な整数と大きく混乱することのない明確なポインタ型を必要としているからです。 Cは、整数とポインタの間で暗黙の変換を行わないようにします。
int pn = &n
という行は、この型の安全性に違反するため実際にはコンパイルされません(「単純割り当て」ルール)。いくつかのコンパイラは、たとえそれがCの標準違反であっても、これに対してコンパイラエラーを与えることについて少しゆるやかです。 (GCCでは-pedantic-errors
がセットされていることを確かめてください)そして、私たちは別のポインタ型を持っているので、ポインタ型の演算を行うこともできます。これは便利です。例えば、ポインタを配列のように使用することができます。
uintptr_t
とintptr_t
:
近代Cは安全にアドレスを格納するために使用できる2つの新しい整数型を導入しています。これらは、安全にアドレスを格納するのに十分な大きさであることが保証されていますが、まだポインタ型へ/からの明示的な変換を使用する必要がありますされています
uintptr_t pn = (uintptr_t)&n;
(エキゾチック例ところがありますがintptr_t
は、穏やかに便利ですあなたは実際に負のアドレスを持っています。特定のシステム上のいくつかの仮想メモリアドレッシングは、負のアドレスを使ってカーネルアドレス空間を示すかもしれません。)
ルンディンはこの有益な情報をありがとう!ほんとうにありがとう。 –
pn
がint
の方のポインタであり、実際にはint
ではないことを指定します。ポインタのサイズはオブジェクトのサイズと同じではありません(ほとんどの場合)。詳細については、ポインタについて読んでください。
大きな違いは、最初のケース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
のようなものはただ一人で座って見えます初期化された値を含んでいます。しかし、p
点n
の位置に。
実際には、実際のハードウェアでは、p
とv
の内容は同じです(プラットフォーム上ではsizeof(int) == sizeof(int *)
が問題ではありません)。これは、コンパイラがこれらの異なる変数をどのように扱うかを示しています。
これは完璧な説明です。ありがとうございました! –
なぜ*が必要なのか正確には分かりません。
ポインタと整数を区別するために、おそらく意味と機能が異なるためです。
int pn = &n;
というステートメントは、コードCコンパイラで&を使用すると必ずアドレスを扱うことがわかります。他のより簡単な用語では、&はオペレータのアドレスであると言うことができます。
ステートメントでは、通常の整数変数を別のアドレスで初期化しようとしていますが、これは正しくありません。&n
を書くと、nのアドレスで変数を初期化しようとしているとコンパイラは考えています。アドレスは通常の変数に格納できないので、変数はポインタにする必要があります。それが助けてくれることを願って。
- 1. C言語のポインタ:int ** Vs. int(* g)[]
- 2. intとsigned int宣言の違い
- 3. C - unsigned int型のプロパティのN量
- 4. `int(numpy.sqrt(N))`の安全性
- 5. long intをC言語のintに変換する方法
- 6. [^ \ n]とは何ですか?(C言語)
- 7. toString(int variable、n)vs toString()
- 8. Iタイプの画分(INTのN、INT d)は
- 9. C#intとint32の宣言
- 10. `*(unsigned int *)(unsigned int)ブロック+ n * i)の意味は?
- 11. [:n]と[n:]のスライスの違い
- 12. なぜstd :: variantはC言語でstd :: variant <int、const int>
- 13. SMLのint - > int - > intと(int * int) - > intの違いは何ですか?
- 14. var map = HashMap <Int,String>()とvar map = HashMap <Int,String>(n)の違いは何ですか?
- 15. ファイルを使用した例_ $ {PN}
- 16. "int f(int(fn)())"と "int f(int(* fn)())"の違いは?
- 17. Cポインタの違いChar Int
- 18. Cのint * ptrとint * ptrの違いは何ですか?
- 19. Cのintとextern intの違いは何ですか?
- 20. C++で "const int"と "int"の違いはありますか?
- 21. コンパイラの違い。 C言語
- 22. x = malloc(n * sizeof(int)); voidをintに変換できません
- 23. "n * 3"または "n +(n * 2)"という高速コードにコンパイルされますか?
- 24. 次の言語のDFAを作成します。L = {a^n b^n | n> = 1}
- 25. angularJSのslice()メソッドpnオブジェクト配列の使い方
- 26. int * array [60]とint * array = new int(60)の違いです。
- 27. N行、N行、N行を印刷することは可能ですか?C言語
- 28. System.getProperty( "line.separator")の違い。と "\ n"?
- 29. "int * a = new int"と "int * a = new int()"の違いは何ですか?
- 30. フロアとintキャストの違い
これは言語の設計方法です。それがあなたが提案する方法で働くならば、それは混乱であろう。 –
コンパイラはこのようなコードをコンパイルしようとしたときにヒントを与えませんでしたか? –
このような基本的な質問はすべてのCの本によって答えられます。読んでください。 – Olaf