この前,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の値は&index
でint
の番地だし...
しばらく考えて分からなかったので,*(int *)param = index;
の左辺を適当に変えてコンパイルしてみることにした.
結果,(int *)
は元が(void *)
である変数param
のキャストで,頭の*
がポインタの参照先を示す記号であることがわかった.
よってindex
が代入されるメモリ番地はmain
内のindex
変数用に確保されている領域の番地なので,main
内のindex
変数にsearch
関数の結果である配列のインデックスが格納される.
PREVIOUSexecコマンドについて
NEXTenvコマンドについて