【配列とポインタ】第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型」)に展開されます。

まとめると、

間接参照式 間接参照で展開される値
*<配列型変数へのポインタ> 先頭部分配列へのポインタ
*<配列以外の型の変数へのポインタ> その変数の値
*<関数ポインタ> 関数の返却値

演算子「*」を関数として考えれば、

オペランド 返却値
配列型変数 その先頭要素へのポインタ
上記以外の型の変数へのポインタ その変数の値
関数ポインタ 関数の返却値

…という、一種の関数としてとらえることもできると思います。「+」演算子が、左オペランドと右オペランドを持つ関数であり、その返却値は「左オペランドと右オペランドを加算した値」であるように。