pは変数です。ただし、変数のアドレスを格納する変数です。ポインタとも呼ばれます。
当たり前じゃないの...?
たとえば,配列名aとポインタpaと比べてみましょう。
- ポインタは変数です。
pa=a
やpa++
は意味のある演算です。 - 配列名は変数ではありません。
a=pa
やa++
のような構文は正しくありません。
ポインタへのポインタが許されることもポインタが変数であることの理解が必要です。下の方にある例を見て下さい。
根拠
[K&R,5.1 Pointers and Addresses] に以下の記述があります。
The unary operator & gives the address of an object, so the statement
p = &c;
assigns the address of c to the variable p, and p is said to ``point to'' c.
[2,6.2.1 識別子の有効範囲]に以下の記述があります。
識別子は,次のいずれか一つを表す。
- オブジェクト
...
「ポインタは変数のアドレスを格納する変数」 [K&R,5 Pointers and Arrays]とあります。。
A pointer is a variable that contains the address of a variable.
告白します。よく分かっていないこと...
以下の表現は正しいのかよく分かっていません。
- アドレスはcを指す1。
- 識別子pはcを指す。(もしくは識別子の意味での変数pについて、「変数pはcを指す」。)
- ポインタ変数。
私は、代わりに以下の表現を用いるようにします。
- cのアドレスの値は(16進数表記で)0x00...である。cはこのアドレスを(属性として)もつ2。((pがcを指す場合)pはアドレス値0x00...をもつ。)
- 識別子pで表される(が参照する)変数(配列の要素,オブジェクト)がcを指す3。
- ポインタ。もしくは、変数。
例
例1
「pがcを指す」のcがポインタであっても構わないです。次のコードではxを指すqは変数であり、qを指すqqも変数です。
char x;
char *q;
char **qq;
q = &x;
qq = &q;
一部を下のように取り出してもう一度見てみましょう。qがもつアドレス値を定めていない(もしくはqが指す変数を定めていない)のにqqがqを指せるのはなぜかという疑問を持つ人に少なからずあったことがあります。「pがcを指す」のcは変数であればよく、qはポインタであり、ここでいうポインタは変数ですからcになることができます。qは型"char型へのポインタ"を格納できる変数であるのです。
char *q;
char **qq;
qq = &q;
例2
次のコードは「pがpを指す」例です。自身を指すポインタであり、一見理解するのが難しいように思えます。
void *p;
p = &p;
pは型"void型へのポインタ"をもちます。&pは型"void型へのポインタへのポインタ"をもちます。型void *は汎用ポインタ(generic pointer)であり,キャストなしに別の型のポインタに代入することができます。根拠としては、[K&R,5.4 Address Arithmeticの末尾]に以下のような記述があります。
It is not legal to add two pointers, or to multiply or divide or shift or mask them, or to add float or double to them, or even, except for void *, to assign a pointer of one type to a pointer of another type without a cast.
参考文献
[K&R] Kernighan, B. W. and D. M. Ritchie (1988). The C Programming Lnaguage.
[K&R2J] Kernighan, B. W., Ritchie, D. M., 石田晴久(訳). (1989). プログラミング言語C (第2版): 共立出版.
[2] JIS X 3010:2003 プログラム言語C
-
この表現の使用例:「アドレス(が指すメモリ領域)」@ http://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/mini_python/gen/slides/6-gc.pdf 「アドレスが指す値」@ https://xythos.tokyo-ct.ac.jp/web/j/usr/kosaka/for_students/CIntro/extension/alloc2d.html , 「アドレスが指す先の変数」@http://www.ss.cs.meiji.ac.jp/CCP054.html ↩
-
「変数がアドレスをもつ」という表現について。[K&R2J]の「5.3ポインタと配列」に「配列名のパラメータはポインタ,すなわちアドレスをもつ変数である。」という表現がある。また[K&R]には「the address of a variable」という表現が繰り返しでてくる。このofは帰属を表す前置詞であり、アドレスは変数の属性・性質なのではないかと解釈している。ただし,変数は必ずしもアドレスを(属性として)もつとは限らない。これについては、謎の表現P2.「ポインタはある記憶域を指し示す」も参考にして下さい。 ↩
-
参考文献[2]に次のような説明がある。「識別子は,次のいずれか一つを表す。オブジェクト,関数,構造体[中略]。同一の識別子であっても,プログラム内の異なる位置では異なる実体を表すことがある。」 ↩