C + +第1部でポインタと参照
ポインタと参照は、コンピュータサイエンスの2つの非常に重要な概念です。 彼らは、ドレスや少し異なると多くのプログラミング言語で表示されますが、治療は基本的に同じです。 C + +では、ポインタは不可欠なスキルです。
ポインタは、変数などのメモリ内のいくつかの他のデータへの(またはしない)で宣言されたことができるデータ、の特殊なタイプです。 ポインタ型の変数は、メモリ内の1つの他のもののアドレスを保持します。 このことは、特にデータセット、機能、任意の変数、定数、最初にすることができます。
の宣言ポインタ
ポインタの宣言は、通常、変数名の前に*を追加することによって行われます。 我々は象徴的ではなく、"ポインタ変数"の"型へのポインタ"を宣言しているが、それらは等価であるということを言っている型の名前を貼り付けるために広く使用されている表記*。 次に例を示します。
intへの/ /ポインタ。 ptr_num1 ; int型 * ptr_num1。 / /あるいは、そう。 ptr_num2 ; int型 * ptr_num2。 ダブルへ/ /ポインタ。 ptr_double1 ; * ptr_double1を 倍増 。 / /あるいは、そう。 ptr_double2 ; * ptr_double2を 倍増 。
一度宣言、ポインタが存在し、長さを有し、その結果、メモリ内で行われます。 ポインタのサイズは、通常、例えば機械/システムのビット数、32ビットシステムでは4バイトと等しくなります。
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | pc ; int i, * pi ; double d, * pd ; // O operador sizeof diz o tamanho do tipo do seu argumento. cout << "Size of char: " << sizeof ( c ) << " bytes" << endl ; cout << "Size of int: " << sizeof ( i ) << " bytes" << endl ; cout << "Size of double: " << sizeof ( d ) << " bytes" << endl ; cout << endl ; cout << "Size of char*: " << sizeof ( pc ) << " bytes" << endl ; cout << "Size of int*: " << sizeof ( pi ) << " bytes" << endl ; cout << "Size of double*: " << sizeof ( pd ) << " bytes" << endl ; にchar c、* PC、int型私、*π、 ダブル D、PD * / / sizeof演算子は、その引数の型の大きさは言う 裁判所 <<"charのサイズ:"<<sizeof 演算 (C)<<" バイト"<<endlを。 裁判所 <<"int型のサイズ:"<<sizeofの (I)<<"バイト"<<endlを。 裁判所 <<"二重のサイズ:"<<sizeofの (D)<<"バイト" <<endlを。 裁判所 <<endlを。 裁判所 <<"char *のサイズ:"<<sizeof 演算 (CP)<<"バイト"<<endl を。 裁判所 <<"int型*のサイズ:"<<sizeof 演算 (PI) <<"バイト"<<endl を。 裁判所 <<"二重の*サイズ :"<<sizeof演算 (PD)<<"バイト"<<endl を。 |
ポインタの使用
彼の文の後、ポインタの内容は任意の変数と同様に、ランダム値、メモリの無駄です。 それが有用であるために私たちはそれに何かを割り当てる必要があります。 ポインタがメモリアドレスを格納するように、我々はそれを有効なアドレスを割り当てる必要があります。
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | int型のx、y; px, * py ; int型 *ピクセル、* PY。 ; X = 13; ; Y = 10; x ; &X = ピクセル; y ; &Y = PY; 42 ; * Pxの= 42; py ) ++ ; (* Pyは)+ +; * px << endl ; 裁判所 <<*ピクセル<<endlを。 * py << endl ; 裁判所 <<* PY <<endlを。 ( * px ) * ( * py ) << endl ; 裁判所 <<(*ピクセル)*(* PY)<<endlを。 |
演算子&(アンパサンドまたはアンパーサンド変数名の前には)彼の名は"アドレス"であるため、"アドレス"を意味する。
何が平等で残されたものは平等の反対側にある同じ種類を維持できる必要があります。 ポインタはアドレスを保持します。 したがって、この場合のポインタにアドレスを割り当てるには、&演算子でアドレスを取得する必要があります。
暗黙の型変換は、(そのような数値型の間など)がある場合を除いて、コンパイルエラーの原因となる、あなたのタイプの異なるものに変数を割り当てます。 幸いなことに!
一度有効なアドレスを指すポインタを持って、我々は、演算子*(と、そのアドレスの内容にアクセスできるようにアスタリスクを持つ正式な名前です)、"デリファレンス演算子。"
ステートメント内のアスタリスクは、"型へのポインタ"を意味し、ポインタの内容を読み書きするの文脈で、"コンテンツに任命された。""アドレスの内容"を意味するかがあることに注意してください また、算術積の記号と混同しないように注意してください。 混乱を避けるために、その覚えている演算子の優先順位の巨大なテーブルをあなただけの目を過ごしたし、忘却の淵に落ちていること、。 ここでは、参照の演算子は乗算演算子よりも優先されることがわかります。 あなたがデリファレンス演算子は乗算演算子の前に評価されていることを忘れないことを行うこと。
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | pa, * pb ; int型のa、b、c、* paの、* 鉛; ; = 2; ; B = 3; a ; PA =&A; b ;沸点=&bの ; pa * * pb ; C = * PA * pbは、 pa * * pb ; C = * PA * pbは、 pa * * pb ; C = * PA * pbは、 pa ** pb ; ** C * PA = 鉛; * pa ) * ( * pb ) ; C =(* PA)*(* BP); "Valor da Pegadinha: " << c << endl ; 裁判所 <<"ガッチャの値:"<<C <<endlを。 |
ので、アルゴリズムのその証明は例の最後の5行のいずれかを作るものを求めるとき、あなたはそれがPAとPBが指す内容を乗算することがわかるでしょう。 これ以上のそれのためにDPを取得する必要はありません! あなたが本当にこれを実行する必要がある場合と、実際の生活の中で壊し、あなたの4世代が過去と5の将来の節約になります破門あなたが最後の行を使用することを選択した場合、。
あなたがコンテンツを使用して実行できる共通の変数で行うことができますすべてのいずれかの読み取りや、それがポインタがconstであることが明らかでない限り、(書き込み、ポインタが指すが、それは別の暴言だ...).
アドレスとポインタ
以下のコードを実行してください。
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | int型 A、B; pa, * pb ; int型 * PA、* 鉛; "Antes de qualquer atribuição: \n " ) ; のprintf(" 任意の代入前 :\ n")を; "&a = %p \n " , & a ) ; // Endereço válido dado pelo SO. OSで指定したprintf("&= の%P \ nを"、&)/ /有効なアドレス。 "&b = %p \n " , & b ) ; // Endereço válido dado pelo SO. OSで指定したprintf("&B =%P \ nを"、&B)/ /有効なアドレス。 "&pa = %p \n " , & pa ) ; // Endereço válido dado pelo SO. OSで有効なものとして のprintf("&AP =%P \ nを"、&PA)、/ /アドレス。 "&pb = %p \n " , & pb ) ; // Endereço válido dado pelo SO. OSで指定したprintf("&SC =%P \ nを"、&BP)/ /有効なアドレス。 " \n " ) ; の printf("\ N"); "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). のprintf("=%d 個\ nを"、)( ランダム)未初期化/ /コンテンツ。 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). (ランダム)初期化されていない のprintf("B =%d個\ nを"、B)/ /コンテンツ。 "pa = %p \n " , pa ) ; // Conteúdo não inicializado (aleatório). (ランダム)初期化されていない のprintf("PA =%P \ nを"、PA)/ /コンテンツ。 "pb = %p \n " , pb ) ; // Conteúdo não inicializado (aleatório). (ランダム)初期化されていない のprintf("SC =%P \ nを"、BP)/ /コンテンツ。 / /次の行を、再コンパイルおよび実行のコメントを外してみてください。 / /は、printf("* PA =%d個\ nを"、* PA)/ /(ランダム*)は何ですか? / /は、printf("* BP =%d個\ nを"、* bp)の/ /(ランダム*)は何ですか? " \n Após as inicializações dos ponteiros: \n " ) ; の printf("\ nはポインタの初期化後:\ n")を; a ; PA =&A; b ;沸点=&bの ; "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&= の%P \ nを"、&)/ /偶数の有効なアドレス。 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&B =%P \ nを"、&B)/ /偶数の有効なアドレス。 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&AP =%P \ nを"、&PA)/ /偶数の有効なアドレス。 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&SC =%P \ nを"、&BP)/ /偶数の有効なアドレス。 " \n " ) ; の printf("\ N"); "a = %d \n " , a ) ; // Conteúdo não inicializado (aleatório). のprintf("=%d 個\ nを"、)( ランダム)未初期化/ /コンテンツ。 "b = %d \n " , b ) ; // Conteúdo não inicializado (aleatório). (ランダム)初期化されていない のprintf("B =%d個\ nを"、B)/ /コンテンツ。 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). のprintf("PA =%P \ nを"、PA)/ /初期化されたコンテンツ(&)。 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). のprintf("SC =%P \ nを"、BP)/ /コンテンツの開始(&B)。 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a). PAによって任命された のprintf("* PA =%dは\ nを"、* PA)/ /コンテンツ(PA == * a)が。 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b). のprintf("* BP =%d個\ nを"、* bp)の / / bpのコンテンツ(* BP == B)が指す。 " \n Após as inicializações dos inteiros: \n " ) ; の printf("\ n個の整数の初期化後:\ n")を; ; = 10; ; B = 13; "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&= の%P \ nを"、&)/ /偶数の有効なアドレス。 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&B =%P \ nを"、&B)/ /偶数の有効なアドレス。 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&AP =%P \ nを"、&PA)/ /偶数の有効なアドレス。 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&SC =%P \ nを"、&BP)/ /偶数の有効なアドレス。 " \n " ) ; の printf("\ N"); "a = %d \n " , a ) ; // Conteúdo inicializado (10). のprintf("=%d 個\ nを"、)/ /初期化されたコンテンツ(10)。 "b = %d \n " , b ) ; // Conteúdo inicializado (13). のprintf("B =%d個\ nを"、B)/ /初期化されたコンテンツ(13)。 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). のprintf("PA =%P \ nを"、PA)/ /初期化されたコンテンツ(&)。 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). のprintf("SC =%P \ nを"、BP)/ /コンテンツの開始(&B)。 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa (*pa == a == 10). のprintf("* PA =%d個\ nを"、* PA)/ /コンテンツは、APは(* apは== A == 10)によって指摘。 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (*pb == b == 13). のprintf("* BP =%d個\ nを"、* bp)の / /(* BP == B == 13)bpの内容が指す。 " \n Alterando os valores através dos ponteiros: \n " ) ; の printf("\ nのポインタを介して値を変更してください:\ n"); 7 ; * PA = 7; 42 ; * BP = 42; "&a = %p \n " , & a ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&= の%P \ nを"、&)/ /偶数の有効なアドレス。 "&b = %p \n " , & b ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&B =%P \ nを"、&B)/ /偶数の有効なアドレス。 "&pa = %p \n " , & pa ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&AP =%P \ nを"、&PA)/ /偶数の有効なアドレス。 "&pb = %p \n " , & pb ) ; // Mesmo endereço válido dado pelo SO. OSで指定したprintf("&SC =%P \ nを"、&BP)/ /偶数の有効なアドレス。 " \n " ) ; の printf("\ N"); "a = %d \n " , a ) ; // Conteúdo inicializado (a == *pa == 7). のprintf("=%d 個\ nを"、)/ /初期化されたコンテンツ(* apは== A == 7)。 "b = %d \n " , b ) ; // Conteúdo inicializado (b == *pb == 42). のprintf("B =%d個\ nを"、B)/ /初期化されたコンテンツ(* BP == B == 42)。 "pa = %p \n " , pa ) ; // Conteúdo inicializado (&a). のprintf("PA =%P \ nを"、PA)/ /初期化されたコンテンツ(&)。 "pb = %p \n " , pb ) ; // Conteúdo inicializado (&b). のprintf("SC =%P \ nを"、BP)/ /コンテンツの開始(&B)。 "*pa = %d \n " , * pa ) ; // Conteúdo apontado por pa ( 7). のprintf("* PA =%d個\ nを"、* PA)/ / APのコンテンツ(7)で指摘した。 "*pb = %d \n " , * pb ) ; // Conteúdo apontado por pb (42). のprintf("* BP =%d個\ nを"、* bp)の / /コンテンツは、BP(42)が指す。 |
行18時19 respectivamneteは2つの整数と整数への2つのポインタを宣言する。
23 26の行は、私の変数のアドレスを示しています。 これらのアドレスは、オペレーティングシステムによって与えられたと、これらの変数は、そこに固定されている。 変数はプログラム実行中にアドレスを変更しませんが、別の実装から変更することができます。 誰がこのアドレスは、プログラム実行時のオペレーティングシステムであるかを定義します。 コンパイラは、xのバイトが各変数に必要なことを知っている、と解釈(型)のプログラムは、このスペースを与えること。
行30から33までは初期化されていないこれらの変数の内容を、示す。 それは、誰かが(私が誰を知っていない)コンピュータのメモリ内にそれらの場所を入れて、どれが今私の変数に属していることを最後の値ゴミだ。
彼らが初期化されていないPAとPB、で指されるコンテンツにアクセスしようとして、それが36と37のコメントを外しラインに安全であることに注意してください。 この試行時に、プログラムは、int型の変数の有効なアドレスのようにランダムなジャンクのそれらの値を解釈しようとします。 コンパイラによっては、OSが使用され、彼らの運命は無害かどうか可能性があります。 確かなことはこれらの行の結果は、問題の予測できないと、特定のソースであることです。
行で41と42のポインタは、整数変数aとbのアドレスで初期化されます そこからプリントが繰り返されます。
期待された変化しないポインタのアドレスを参照してください。 その内容の変更はどのようなものです。 変数pAおよびpBは、aとbそれぞれのアドレスを受け取ります。 手の内容が正確にプログラムの開始時にOSによって与えられたとbの変数のアドレス値であることに注意してください。 前回のプリントに確認してください。 PAとPBが指す内容はと初期化されていないB、、またはゴミのと同じ内容です。 しかし、前の手順とは異なり、現在有効なアドレスのとその内容(aとbのアドレス)へのポインタのポイントとbごみのメモリのポインタは、現在すでに割り当てられている変数を指すようです。
行で61と62の整数の変数は値10と13、再び繰り返されると版画で初期化されます。
この時間は、aとbのcoteúdosは、もはやゴミです。 値はよく知られている。 前のステップに関連する変数、値のみのアドレッシングに変化がないことに注意してください。
aとbが初期化された後に、PAとPBが指す内容も自動的に変更されている。も参照してください。 これは、PAとPBポイントのための変数PAとPBで使用されるのと同じメモリ領域に正確に行われます。 これにより、コンテンツはポインタが指す、彼が指摘した元の変数の内容を変更することで変更できることを意味します。 そして最後に、行81から97は、逆も真であることを示す、すなわち、内容はポインタが指す変更、自動的にそれらが指摘した元の変数の内容を変更します。
それは、コードを見るよりポルトガル語のフレーズのこの考え方を理解する方が簡単です。
今のところ...
これはポインタの基本的な操作であった。 そこに関数へのポインタとして表示されるように興味深いことは、例えば、まだ、それは、より高度なトピックと考えられている。 4件の記事のために計画されているこのシリーズ、続いて、最終的にはポインタと参照と関数へのポインタ間の参照、相違点と類似点を参照してください。
リンク
- ponteiros.zip (後のすべてのソース)。
- 01 - declaracao.cpp
- 02 - tamanhos.cpp
- 03 - utilizando.cpp
- 04 - pegadinha.cpp
- 05 - enderecos.cpp
- cplusplus.com上のポインタ
- ギルティ
コメント
- ブレブのブログBlaber:C + +第2部で http://blog.blabos.org/2009/05/ponteiros-e-referencias-em-c-parte-2/ ポインタと参照
- http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional Caloni.com.br国のブロゴスフィアでブログ» Blog Archive »最新の研究
- http://blog.blabos.org/2009/05/ponteiros-e-arrays/ ポインタと配列:ブレブのBlaberブログ
- フェルナンド
- フェルナンド
- http://blabos.pip.verisignlabs.com/ うっかり漏らす
- http://blabos.pip.verisignlabs.com/ うっかり漏らす
- ブルーノ http://www.brunodanielmarinho.com
- ブルーノ http://www.brunodanielmarinho.com

