### 函数指针

对于 C++语言来说，函数名实际上是指向函数的长指针。理解这一点，就可以定义一个普通的函数指针，使其指向某一类型的函数。

例如，下面的代码定义了一个指向具有两个整型参数的函数指针。

int (*ptfun)(int,int);

也可以使用 typedef 定义一个函数指针类型，然后定义该类型的变量。例如：

typedef int (*ptfun)(int,int);

ptfun fun;

当定义了一个函数指针后，可以将已经定义的函数（函数的返回值、参数个数、参数类型必须与函数指针定义的形式相同）赋值给函数指针，通过函数指针调用指向的函数。

例如，使用函数指针调用函数。其程序代码如下：

typedef int (*ptfun)(int,int); //定义一个函数指针类型

int sum(int x,int y) //定义一个求和函数

{

return x + y;

}

ptfun fun; //定义一个函数指针变量

fun = sum; //将函数 sum 赋值给函数指针变量

int ret = fun(10,20); //通过函数指针变量调用 sum 函数

对于函数指针来说，它指向的函数必须与函数指针定义的函数形式相同，即返回值类型相同、参数类型相同、参数个数相同。这与函数重载是不同的，函数重载不以函数的返回值类型为依据，但是函数指针则不同，如果将上面的 sum 函数的返回值类型修改为 double 类型，则上述代码将无法编译。

说明：在程序中使用函数指针的好处是增强程序的灵活性。

例如，编写一个通用的函数，实现两个数的加、减、乘、除操作。

示例，使用函数指针指向不同的函数。

typedef int (*ptfun)(int,int); //定义一个函数指针

int Invoke(int x,int y,ptfun fun) //定义一个通用的功能函数

{

return fun(x,y);

}

int sum(int x,int y) //定义求和函数

{

return x + y;

}

int sub(int x,int y) //定义减法函数

{

return x - y;

}

int mul(int x,int y) //定义乘法函数

{

return x * y;

}

int divi(int x,int y) //定义除法函数

{

return x / y;

}

int main(int argc, char* argv[]) //主函数

{

ptfun pfun; //定义函数指针变量

pfun = sum; //为函数指针变量赋值

int ret = Invoke(20,10,pfun); //调用 Invoke 函数

pfun = mul; //为函数指针变量赋值

ret = Invoke(20,10,pfun); //调用 Invoke 函数

return 0;

}

上述代码的 main 函数中，同样的“Invoke(20,10,pfun);”语句，由于 pfun 指向了不同的函数，因此 Invoke 函数实现的功能也不相同。如果用户的程序有改动，例如需要实现两个数的求余运算，只需要再编写一个求余函数，将其赋值给 pfun 函数指针，Invoke 函数不需要进行任何改动。

对于指针变量来说，用户可以定义指针数组，对于函数指针，用户也可以定义函数指针数组。例如，下面的代码定义了一个函数指针数组。

int (*ptfun[4])(int,int);

下面列举一个示例，通过遍历函数指针数组来调用不同的函数。其程序代码如下：

int sum(int x,int y) //定义求和函数

{

return x + y;

}

int sub(int x,int y) //定义减法函数

{

return x - y;

}

int mul(int x,int y) //定义乘法函数

{

return x * y;

}

int divi(int x,int y) //定义除法函数

{

return x / y;

}

int main(int argc, char* argv[]) //主函数

{

int (*ptfun[4])(int,int); //定义函数指针数组

ptfun[0] = sum; //为数组中的元素赋值

ptfun[1] = sub;

ptfun[2] = mul;

ptfun[3] = divi;

for(int i=0; i<4; i++) //利用循环遍历数组

{

int ret = ptfun[i](30,10); //调用当前函数指针指向的函数

printf("%d\n",ret); //输出结果

}

return 0;

}

执行上述代码，效果如图 1 所示。

图 1 函数指针数组