C 函数指针数组
名字有点绕口,其实更应该翻译为指针函数数组.
记录下对Head-First C这一节的理解,几乎每天班车上都会咪两眼,几乎每次都是看不懂,敲一敲的时候才有些明白.
通俗点讲,这功能解决的是,具有同种签名的方法的数组式调用. 还是不够通俗,书上讲的很通俗:分手信生成器.
对号入座,这是士兵结构体,包含名字以及回信内容类型
enum response_type {DUMP,SECOND_CHANCE,MARRIAGE,LAW_SUIT}; typedef struct { char *name; enum response_type type; }response;
回信内容所调用的方法:
void dump(response r) { printf("Dear %s,\n",r.name); puts("我們分手吧"); } void second_chance(response r) { printf("Dear %s,\n",r.name); puts("再給你一次機會"); } void marriage(response r) { printf("Dear %s,\n",r.name); puts("我們結婚吧"); }
// //函数指针数组 // // //定義說明: // //void 必须是void类型 //(*replies[]) 数组声明,注意是指针数组,需要用* //(response) 函数接收的参数类型,若有多个,应该是:类型,类型。。。 //{dump,second_chance,marriage} 函数列表,dump,second_chance,marriage是函数名,注意不是枚舉值,枚舉值是大寫的 // // //调用方法: //(replies[r[i].type])(r[i]) // //其實就是: //函數名(參數列表) // // //函數名: //(replies[r[i].type]) // //r是struct类型,type是枚举类型,枚举类型从0开始 //所以上面的这句如果直接写死的话可以写为: //(replies[0]), //也就是说r[i].type取得了一个索引,这个索引决定了要调用的方法的索引: //{dump,second_chance,marriage} //{0,1,2} //r[0].type=dump,也就是调用dump方法, //然后为dump方法准备传入参数:r[i] // //参数列表: //例如:dump(response r)接收struct response的类型,所以为其准备的参数r[i]就是这种类型 void (*replies[])(response)={dump,second_chance,marriage,law_suit};
int main() { response r[]= { {"Mike",DUMP}, {"Geroge",MARRIAGE}, {"Vincent",DUMP}, {"Galleleo",SECOND_CHANCE}, {"Furler",MARRIAGE}, {"T-BAG",LAW_SUIT} }; int i,len=0; GET_ARRAY_LEN(r,len); for(i=0;i<len;i++) { /* //这是常见的使用switch的方法,如果要加一种类型,可能修改的地方比较多 switch(r[i].type) { case DUMP: dump(r[i]); break; case SECOND_CHANCE: second_chance(r[i]); break; case MARRIAGE: marriage(r[i]); break; } */ (replies[r[i].type])(r[i]); } return 0; }
http://lison.cc