*ポインタ [#b98431ab] C/C++のポインタの概念を説明します。 #contents **アドレス [#e2aa8599] int i = 10; というコードがあるとします。 これがコンパイルされたとき、EXEのなかではどう表現されているのでしょうか? 変数の値は、実際にはメモリのどこかに保存されています。 そして「どこに保存されているか」というメモリの住所は、番号で表現されます。 上記のコードは、たとえば 45450721番目のメモリに 10 を代入せよ のようにコンパイルされます。 何番目のメモリを使うかは、コンパイラが勝手に決めてくれます。 C言語を使えば、このようにどの変数にどこのメモリを割り当てるかを 自動的に割り振ってくれるわけですね。 この、"何番目のメモリ" という番号のことを「アドレス」と呼びます。直訳すれば "住所" ですね。 **ポインタ [#ta60fe66] さて、上記のコードにおいて、変数 i が何番目のメモリに格納されているかが知りたいときがあります。 用語を用いて言い換えれば、変数 i のアドレスが知りたいわけですね。 そういう時は &i と書けばおkです。上記の例では &i は 45450721 です。 C言語には、アドレスを格納するための特別な変数型があります。それを「ポインタ」と呼びます。 ポインタの宣言は int *p; のように書きます。たとえば int i = 10; int *p = &i; などとします。この p には、たとえば 45450721 などが格納されます。 この例では、p のことを「i へのポインタ」といいます。 「i へのポインタ」とは、"i のアドレスが格納されているポインタ"のことです。 では 45450721番目のメモリに入っている値(すなわち i に格納されている値)が知りたいときはどうするかというと printf("%d", *p); と書きます。 *p のことを、「p が指す値」と呼びます。 **ポインタの宣言 [#n0e5a3dc] int i; という宣言文は「i は int型である」と宣言しています。これと同じで int *p; という宣言文は「*p は int型である」、もしくは「pとは、*p が int型になるような型の変数である」と宣言しています。 ちょっと複雑な例を考えましょう。intへのポインタを10個並べた配列 ap が欲しいときはどうすればよいでしょうか? ap[index] はポインタですね。その指す値(int型)は、 *(ap[index]) で得られます。ですから ap の宣言は int *(ap[10]); と書けばよいのです。 次に、intを10個並べた配列へのポインタ pa が欲しいときはどうすればよいでしょうか? *pa は配列ですから、(*pa)[index] は int 型ですね。ですから int (*pa)[10]; と宣言すればよいです。 *関数の引数について [#v202f321] **値渡し [#i83f1e1e] #include <stdio.h> void func(int a) { a = 100; } int main() { int b = 1; func(b); printf("%d", b); } というプログラムを実行すると、"1" と表示されます。決して "100" にはなりません。 具体的に追っていきましょう。&a は 45450721、&b は 6741 だとします。 main関数のなかでは、まず int b = 1; で 6741番目のメモリが 1 になります。次に func(b); では、45450721番目のメモリに 1 がコピーされて func の先頭にジャンプします。 func のなかで、45450721番目のメモリに 100 が代入されます。そうして printf("%d", b); に戻ってきたとき、6741番目のメモリには何が入っているでしょう? 1 ですね。 このように、関数の引数には、呼び出し元の変数の値がコピーされ(「値渡し」)、 関数内部ではその''コピーされたものしかいじれません''。 **関数の引数にポインタを用いると [#oc238e97] #include <stdio.h> void func(int *p) { *p = 100; } int main() { int b = 1; func(&b); printf("%d", b); } を最初から追っていきましょう。&p は 45450721、&b は 6741 だとします。 まず int b = 1; で 6741番目のメモリが 1 になります。つぎに func(&b); で、45450721番目のメモリに 6471 がコピーされて、funcの先頭へジャンプします。 funcのなかで、45450721番目のメモリに格納されている番号(6471番)の メモリに 100 が代入されます。そうして printf("%d", b); に戻ってきたとき、6741番目のメモリには 100 が入っています。 ですから、画面には "100" と表示されることになります。 このように、ポインタを関数の引数に用いると、 関数内で呼び出し元の変数をいじることができるようになります。 *配列 [#w189609e] 以下加筆します