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;
}

 

posted @ 2014-03-21 13:31  Lison Liou  Views(237)  Comments(0Edit  收藏  举报