ポインタのキャストがわかりにくい

この前,callback関数についてちょっと調べようと思ってWikipediaのページのコードを見ていたが,ポインタ変数への代入部分でハマったのでメモする.

コールバックの例のコード (C言語):

#include <stdio.h>

/* Library code */
int traverseWith(int array[], size_t length,
                 int (*callback)(int index, int item, void *param),
                 void *param)
{
    int exitCode = 0;
    for (int i = 0; i < length; i++) {
        exitCode = callback(i, array[i], param);
        if (exitCode) {
            break;
        }
    }
    return exitCode;
}

/* Application code */
int search (int index, int item, void *param)
{
    if (item > 5) {
        *(int *)param = index;
        return 1;
    } else {
        return 0;
    }
}

int main(int argc, char const* argv[])
{
  int index;
  int found;
  int array[6] = {1,2,3,4,5,6};
  int length = sizeof(array) / sizeof(array[0]);
  found = traverseWith(array, length, search, &index);
  if (found) {
      printf("Item %d\n", index);
  } else {
      printf("Not found\n");
  }

  return 0;
}

問題の部分はアプリケーションコードの以下の部分.

    if (item > 5) {
        *(int *)param = index;
        return 1;
    }

*(int *)param = index;ってなんだ...?param(void *)型の変数だから*をつけてポインタの参照先にindexの値を代入しているんだろうが,(int *)がわからん...ポインタのポインタ?でもparamの値は&indexintの番地だし...

しばらく考えて分からなかったので,*(int *)param = index;の左辺を適当に変えてコンパイルしてみることにした.

結果,(int *)は元が(void *)である変数paramのキャストで,頭の*がポインタの参照先を示す記号であることがわかった.
よってindexが代入されるメモリ番地はmain内のindex変数用に確保されている領域の番地なので,main内のindex変数にsearch関数の結果である配列のインデックスが格納される.