【C++】C++ポインタを初めて学ぶときの、紛らわしいところや疑問なところ

2405 ワード

C++のポインタは比較的複雑な知識概念であり、最近私はこの方面の知識を勉強しているので、この文章で学習時に生じやすい混同を記録します.私は初めて技术类の分かち合いを出して、漏れがあるかもしれなくて、皆さんの指摘を歓迎します^^!
1、*の2つの文脈の下での意味
まず、このコードを見てみましょう.
1 int i = 330;
3 int *p = &i;
5 cout << *p <<endl;

 
*は逆アドレッシング演算子(すなわち、アドレッシング値)であることはよく知られています.
cout <
ただしint*p=&i;この文は?
*は逆アドレス演算子ではありませんか?それはpアドレスで値を取ったメモリがiに書き込まれたアドレスではないでしょうか.しかし、これは論理的ではありませんか?
実は、*宣言文では逆アドレス演算子ではなく、intと*を全体として、すなわちint*pという書き方が適切で、私が上記のコードでわざとint*pと書いたのは、この例を挙げるためです.(注意:int*pとint*pはいずれも合法的)C++の基本データ型にはポインタタイプがあり、int*はp変数のタイプ宣言であり、文法的にはint*pのようなintと*空の書き方をサポートしているが、両者は全体として理解すべきである.
まとめ:ポインタ変数(定数)より前の*は逆アドレス演算子です.タイプを宣言する場合、*はポインタタイプ宣言の一部です.
 
2、配列名について
伝統芸能、コードを見てみましょう.
1 int array[] = {1,2,3,4,5};
2 
3 int* p = array;

 
 
配列名の本質を聞いたら?私がポインタ定数だと答えますか?そして、上の2行目のコードで私に証言して、「ほら、arrayはポインタpに値を割り当てることができます.ポインタではありませんか」と言いました.
そう思うなら、次のコードを見てください.
 
1 cout << sizeof(p) << endl; //   4
2 
3 cout << sizeof(array) < 
  

 
 
驚いたか?意外じゃない?
実は説明はこうです.
(1)arrayの本質は配列というデータ構造であり,cout<
(2)arrayは、強制タイプによってポインタタイプに変換することができ、このときarrayは&array[0]、すなわち配列ヘッダ要素のアドレスに等価であり、ポインタ定数として表現される.
 
3、chAR*とCHAR[]の違い
後で引用するために、まず例を挙げます.
1 char* p = “abc” ;
2 
3 char a[] = “abc”; 

 
pは、定数のポインタ、すなわち、定数アドレスを格納する変数である.p=&XXXなどのpの指向を修正することができます.しかし、*p++などの*pが指す値を変更することはできません.定数を指しているため、不正です.
aはポインタ定数として表現され、すなわちaが指すアドレスはa++のように修正できない.不法です.【特に注意:*(a++)はaの値を修正していない.これは合法的である.ここでのa++は伝値であり伝引用ではないからである.しかし、アドレス上の値の修正は合法的である.例えば*a=「d」である.
 
4、総合応用
上で学んだ3つの点を結びつけて、*paが出力しているものを説明してみてください.
1 char* pArray[] ={"apple","pear","banana" };
2 
3 char** pa = pArray;
4 
5 cout<< *pa <

解:
まずchar*pArrayの要素はchar型ポインタであるべきで、「apple」はchar配列ですか?どのように値を付与することができますか?配列名で述べたように、配列というデータ構造は強制的にタイプをポインタタイプに変換することができ、このとき「apple」は&'a(偽コード、「apple」の最初の文字「a」のアドレス)に等価です.
次に、pArrayはこのとき&pArray[0]に等価であり、pArray[0]はcharポインタであるため、paのタイプ宣言はポインタのポインタであるべきである.
最後に、*paは実際にはpArray[0]に等価であり&’a’(偽コード、「apple」の最初の文字「a」のアドレスを指す)にも等価であるが、coutリロードメカニズムのため、配列全体、すなわち「apple」を出力する.