【配列とポインタ】第3回 間接演算子は関数である
今まで見てきたように、間接演算子*の作用は、以下のようにまとめられると思います。
char型配列の配列arrが以下のようにあるとき、
+------+------+------+------+------+ arr | arr0 | arr1 | arr2 | … | arrN | +------+------+------+------+------+
式中の「arr」は、先頭要素arr0へのポインタ(型は「配列へのポインタ」)に展開されます。
+------+------+------+------+------+ arr | arr0 | arr1 | arr2 | … | arrN | +------+------+------+------+------+ ******** ↑ arr
さらに「*arr」は、arr0の先頭要素へのポインタ(型は「char型へのポインタ」)に展開されます。
arr0 arr1 arr2 arrN +--------+--------+--------+-----+--------+ arr |c0|c1|c2|c0|c1|c2|c0|c1|c2| … |c0|c1|c2| +--------+--------+--------+-----+--------+ *** ↑ *arr
最後に「**arr」は、arr0の先頭要素「c0」(型は「char型」)に展開されます。
つぎは、アドレス演算をしてみます。
式中の「arr+2」は、arr2へのポインタに展開されます。
+------+------+------+------+------+ arr | arr0 | arr1 | arr2 | … | arrN | +------+------+------+------+------+ ******** ↑ (arr+2)
さらに、間接演算子「*」をつけると、arr2の要素「c2」へのポインタ(型は「char型へのポインタ」)に展開されます。
arr0 arr1 arr2 arrN +--------+--------+--------+-----+--------+ arr |c0|c1|c2|c0|c1|c2|c0|c1|c2| … |c0|c1|c2| +--------+--------+--------+-----+--------+ *** ↑ *((arr+2)+2)
最後に「*(*((arr+2)+2))」は、「c2」(型は「char型」)に展開されます。
まとめると、
間接参照式 | 間接参照で展開される値 |
---|---|
*<配列型変数へのポインタ> | 先頭部分配列へのポインタ |
*<配列以外の型の変数へのポインタ> | その変数の値 |
*<関数ポインタ> | 関数の返却値 |
演算子「*」を関数として考えれば、
オペランド | 返却値 |
---|---|
配列型変数 | その先頭要素へのポインタ |
上記以外の型の変数へのポインタ | その変数の値 |
関数ポインタ | 関数の返却値 |
…という、一種の関数としてとらえることもできると思います。「+」演算子が、左オペランドと右オペランドを持つ関数であり、その返却値は「左オペランドと右オペランドを加算した値」であるように。