配列のポインタは次のように表せます。
int (* p)[2]
これはint型が2個の配列のポインタ、pを表します。
配列が現れる例として多次元配列があります。その名の通り添字が増えて多次元になります。
まずはmain関数から見て行きましょう。22行目を見てください。
int main(void){ int working_time[12][31] = { { 0 } }; const int64_t time_sum = calc_annual_working_time(working_time, 12);
2次元配列も宣言・定義の仕方や初期化の仕方は普通の配列と大差ありません。
sum_array関数は1次元配列(普通の配列)を合計するごくごくありきたりな関数です。問題はcalc_annual_working_time関数です。
2つの関数のプロトタイプ宣言を見比べてみましょう。
int sum_array(const int *in_array, const size_t array_num);
int64_t calc_annual_working_time(const int (* working_time)[31]);
1次元配列を受け取るsum_array関数はint const* in_arrayのように受け取っていますが、 2次元配列を受け取るcalc_annual_working_time関数はconst int (* working_time)[31]となっています。
ところで、なぜint **working_timeのように書けないのでしょうか? int **working_timeとした場合、 working_time[0]にはintのポインタがあるという意味になりますが、 実際にはintが31個並んだ配列があります。似ているようで異なるものです。
関数のポインタは次のように表せます。配列のポインタと似ていますね。
void (* p)(void)
これは値を取らず、返さない関数へのポインタ、pを表します。構造体に関数ポインタをもたせることによって、 データとコードに関連をもたせることが出来ます。これは構造化プログラミングや、 オブジェクト指向プログラミングという考え方につながるものです。
次に例を示します。