(*ポインタ名)の部分を関数名とみなしてみると、この宣言は関数のプロトタイプ宣言と同じ形であることがわかります。このことを意識すると宣言方法を覚えやすいでしょう。関数へのポインタの宣言時に指定されている戻り値や引数の型と個数は、関数へのポインタに格納する関数の戻り値や引数の型と個数と一致している必要があります。
具体的に例を書くとこうなります。fに戻り値がintでint型の引数を1つとる関数のアドレスが代入できます。
関数へのポインタを宣言する際には、あらかじめtypedefで新しい型名をつけておくと便利です。
このようにtypedefしておくと関数へのポインタの宣言を下記のように簡潔な表現にすることができます。
簡単な関数へのポインタの使用例を書いてみます。標準ライブラリのatexit()は指定の関数をプログラム終了時に呼び出すように登録する関数です。引数に登録したい関数へのポインタを指定します。
もう一つ関数へのポインタの使用例を挙げておきます。コマンドラインから数値を引数として渡すとその数に関係のあることわざ・慣用句を表示するプログラムです。関数へのポインタを格納してあるテーブルを使用することによりswitch文を使用せずに分岐を実現しています。
/*
proverb.c
指定の数に関係することわざ・慣用句を表示する
*/
/* インクルード */
#include <stdio.h>
/* プロトタイプ宣言 */
void proverb0(void);
void proverb1(void);
void proverb2(void);
void proverb3(void);
void proverb4(void);
void proverb5(void);
void proverb6(void);
void proverb7(void);
void proverb8(void);
void proverb9(void);
void proverbOthers(void);
/* typedef */
typedef void (*PROVERB_FUNC)(void);
int main(int argc, char *argv[])
{
int n = 0;
PROVERB_FUNC f[] = {
proverb0, proverb1, proverb2, proverb3, proverb4, proverb5,
proverb6, proverb7, proverb8, proverb9, proverbOthers
};
/* 引数のチェック */
if (argc != 2) {
printf("Usage: %s <number> ¥n", argv[0]);
return 0;
}
/* 引数をintに変換 */
n = atoi(argv[1]);
if ((n < 0) || (n > 9)) {
n = 10;
}
/* 引数に対応する関数テーブル上の関数をコール */
(*f[n])();
return 0;
}
void proverb0(void)
{
printf("%s¥n", "【零の数がつくことわざ・慣用句】");
printf("%s¥n", "零零細細");
}
void proverb1(void)
{
printf("%s¥n", "【一の数がつくことわざ・慣用句】");
printf("%s¥n", "ローマは一日にして成らず");
printf("%s¥n", "一を聞いて十¥を知る");
printf("%s¥n", "一寸先は闇");
printf("%s¥n", "一年の計は元旦にあり");
printf("%s¥n", "一意専心");
printf("%s¥n", "一朝一夕");
printf("%s¥n", "一期一会");
printf("%s¥n", "一石二鳥");
printf("%s¥n", "一言居士");
printf("%s¥n", "一長一短");
printf("%s¥n", "一難去ってまた一難");
printf("%s¥n", "一騎当千");
printf("%s¥n", "大山鳴動して鼠一匹");
printf("%s¥n", "氷山の一角");
printf("%s¥n", "紅一点");
printf("%s¥n", "間一髪");
printf("%s¥n", "鶴の一声");
printf("%s¥n", "一事が万事");
printf("%s¥n", "十¥把一からげ");
printf("%s¥n", "千載一遇");
printf("%s¥n", "千里の道も一歩から");
printf("%s¥n", "百害あって一利なし");
printf("%s¥n", "百聞は一見に如かず");
}
void proverb2(void)
{
printf("%s¥n", "【二の数がつくことわざ・慣用句】");
printf("%s¥n", "一石二鳥");
printf("%s¥n", "二枚舌を使う");
printf("%s¥n", "二番煎じ");
printf("%s¥n", "二足のわらじ");
printf("%s¥n", "二階から目薬");
printf("%s¥n", "人を呪わば穴二つ");
printf("%s¥n", "瓜二つ");
printf("%s¥n", "青二才");
}
void proverb3(void)
{
printf("%s¥n", "【三の数がつくことわざ・慣用句】");
printf("%s¥n", "三度目の正直");
printf("%s¥n", "三日坊主");
printf("%s¥n", "三顧の礼");
printf("%s¥n", "仏の顔も三度まで");
printf("%s¥n", "早起きは三文の徳");
printf("%s¥n", "朝三暮四");
printf("%s¥n", "石の上にも三年");
}
void proverb4(void)
{
printf("%s¥n", "【四の数がつくことわざ・慣用句】");
printf("%s¥n", "四苦八苦");
printf("%s¥n", "四面楚歌");
printf("%s¥n", "朝三暮四");
}
void proverb5(void)
{
printf("%s¥n", "【五の数がつくことわざ・慣用句】");
printf("%s¥n", "一寸の虫にも五分の魂");
printf("%s¥n", "五里霧中");
}
void proverb6(void)
{
printf("%s¥n", "【六の数がつくことわざ・慣用句】");
printf("%s¥n", "六一銀行");
printf("%s¥n", "六根清浄");
printf("%s¥n", "総領の甚六");
}
void proverb7(void)
{
printf("%s¥n", "【七の数がつくことわざ・慣用句】");
printf("%s¥n", "なくて七癖");
printf("%s¥n", "七転び八起き");
printf("%s¥n", "七転八倒");
printf("%s¥n", "親の七光り");
}
void proverb8(void)
{
printf("%s¥n", "【八の数がつくことわざ・慣用句】");
printf("%s¥n", "七転び八起き");
printf("%s¥n", "八つ当たり");
printf("%s¥n", "八方美人");
printf("%s¥n", "八面六臂");
printf("%s¥n", "口八丁手八丁");
printf("%s¥n", "四苦八苦");
printf("%s¥n", "岡目八目");
printf("%s¥n", "当るも八卦当らぬも八卦");
printf("%s¥n", "村八分");
printf("%s¥n", "胸突き八丁");
}
void proverb9(void)
{
printf("%s¥n", "【九の数がつくことわざ・慣用句】");
printf("%s¥n", "九死に一生を得る");
printf("%s¥n", "九牛の一毛");
}
void proverbOthers(void)
{
printf("%s¥n", "【数のつくことわざ・慣用句(その他)】");
printf("%s¥n", "かわいさ余って憎さ百倍");
printf("%s¥n", "一を聞いて十¥を知る");
printf("%s¥n", "一事が万事");
printf("%s¥n", "五十¥歩百歩");
printf("%s¥n", "人の噂¥も七十¥五日");
printf("%s¥n", "六十¥の手習い");
printf("%s¥n", "十¥人十¥色");
printf("%s¥n", "十¥把一からげ");
printf("%s¥n", "千載一遇");
printf("%s¥n", "千里の道も一歩から");
printf("%s¥n", "悪事千里を走る");
printf("%s¥n", "百害あって一利なし");
printf("%s¥n", "百聞は一見に如かず");
printf("%s¥n", "百里の道は九十¥里が半ば");
printf("%s¥n", "雀百まで踊り忘れず");
printf("%s¥n", "鶴は千年亀は万年");
}
下記のように文字列の中に¥が記述されている箇所があります。これは漢字に対応していないコンパイラのワーニングを回避するためのものです。不要ならば取り除いてください。