来看这么一段代码:
#include "stdio.h" #include "stdlib.h" #include "string.h" enum response_type { DUMP, SECOND_CHANCE, MARRIAGE }; typedef struct { char *name; enum response_type type; }response; void dump(response r) { printf("Dear %s, \n", r.name); puts("dump function\n"); } void second_chance(response r) { printf("Dear %s, \n", r.name); puts("second_chance function\n"); } void marriage(response r) { printf("Dear %s, \n", r.name); puts("marriage function\n"); } int main() { response r[] = { {"Mike", DUMP}, {"Luis", SECOND_CHANCE}, {"Matt", SECOND_CHANCE}, {"William", MARRIAGE} }; int index; for (index = 0; index < 4; index++) { switch (r[index].type) { case DUMP: dump(r[index]); break; case SECOND_CHANCE: second_chance(r[index]); break; case MARRIAGE: marriage(r[index]); break; default: break; } } return 0; }
这个程序是可以执行的,并且是正确的。但是代码中充斥着大量的函数调用,每次都需要根据r的type来调用函数,看起来像这样:
switch (r.type) { case DUMP: dump(r[index]); break; case SECOND_CHANCE: second_chance(r[index]); break; case MARRIAGE: marriage(r[index]); break; default: break; }
这么一来,如果增加r的第四种类型,那就不得不修改程序中每一个像这样的地方。很快,就有一大堆代码需要维护,而且这样很容易出错。
下面来看,如何通过创建函数指针数组来替代上面的这些代码:
#include "stdio.h" #include "stdlib.h" #include "string.h" enum response_type { DUMP, SECOND_CHANCE, MARRIAGE }; typedef struct { char *name; enum response_type type; }response; void dump(response r) { printf("Dear %s, \n", r.name); puts("dump function\n"); } void second_chance(response r) { printf("Dear %s, \n", r.name); puts("second_chance function\n"); } void marriage(response r) { printf("Dear %s, \n", r.name); puts("marriage function\n"); } void (*replise[])(response) = { dump, second_chance, marriage }; int main() { response r[] = { {"Mike", DUMP}, {"Luis", SECOND_CHANCE}, {"Matt", SECOND_CHANCE}, {"William", MARRIAGE} }; int index; for (index = 0; index < 4; index++) { replise[r[index].type](r[index]); } return 0; }
可以看到,我们这里已经没有了那么一大段的switch代码。但是程序依然是和上边的初始程序一样的运行结果。
就这么一行代码,代替了上面的一大段switch代码!
那么我们现在来看增加r的第四种类型时候的代价:
#include "stdio.h" #include "stdlib.h" #include "string.h" enum response_type { DUMP, SECOND_CHANCE, MARRIAGE, DEAD }; typedef struct { char *name; enum response_type type; }response; void dump(response r) { printf("Dear %s, \n", r.name); puts("dump function\n"); } void second_chance(response r) { printf("Dear %s, \n", r.name); puts("second_chance function\n"); } void marriage(response r) { printf("Dear %s, \n", r.name); puts("marriage function\n"); } void dead(response r) { printf("Dear %s, \n", r.name); puts("dead function\n"); } void (*replise[])(response) = { dump, second_chance, marriage, dead }; int main() { response r[] = { {"Mike", DUMP}, {"Luis", SECOND_CHANCE}, {"Matt", SECOND_CHANCE}, {"William", MARRIAGE}, {"Zeng", DEAD}, }; int index; for (index = 0; index < 5; index++) { replise[r[index].type](r[index]); } return 0; }
对比一下,可以看到,仅仅需要修改3个地方,便能够加入一个对应的函数!维护代价大大的减少了!