什么是函数指针 ?
函数指针指向的是特殊的数据类型,函数的类型是由其返回的数据类型和其参数列表共同决定的,而函数的名称则不是其类型的一部分。
一个具体函数的名字,如果后面不跟调用符号 ( 即括号 ) ,则该名字就是该函数的指针。
函数指针的声明方法
// 定义函数指针 pf
int (*pf)(const int &, const int &); (1)
上面的 pf 就是一个函数指针,指向所有返回类型为 int ,并带有两个 const int& 参数的函数。注意 *pf 两边的括号是必须的,否则上面的定义就变成了:
int *pf(const int &, const int &); (2)
而这声明了一个函数 pf ,其返回类型为 int * , 带有两个 const int& 参数。
用 typedef 定义函数指针类型
// 定义函数指针类型 cmpFun
typedef int (*cmpFun)(const int &, const int &); (3)
这样, cmpFun 就成了一种数据类型,可以用它来声明和定义形如 (1) 式中的 pf 那样的函数指针,比如:
cmpFun pf = 0;
cmpFun pf = someFunction;
举个例子来说明一下:
#include <iostream>
#include <string>
using namespace std;
// 定义函数指针 pf
int (*pf)(const int &, const int &);
// 定义函数指针类型 cmpFun
typedef int (*cmpFun)(const int &, const int &);
// 具体函数
int intCompare(const int & aInt, const int & bInt)
{
if (aInt == bInt) return 0;
if (aInt > bInt)
{
return 1;
}
else
{
return -1;
}
}
int main(void )
{
int aInt = 1;
int bInt = 2;
pf = intCompare;
// pf = &stringCompare; // 和上面一句是完全一样的
// 使用 pf
if (pf(aInt, bInt) == 0)
{
cout << "two integers are equal" << "." << endl;
}
else if (pf(aInt, bInt) > 0)
{
cout << aInt << " is greater than " << bInt << "." << endl;
}
else
{
cout << aInt << " is less than " << bInt << "." << endl;
}
cout << "------------------------" << endl;
// 用函数指针类型 cmpFun 声明并初始化一个函数指针 pf2
cmpFun pf2 = intCompare;
// 使用 pf2
if (pf2(aInt, bInt) == 0)
{
cout << "two integers are equal" << "." << endl;
}
else if (pf(aInt, bInt) > 0)
{
cout << aInt << " is greater than " << bInt << "." << endl;
}
else
{
cout << aInt << " is less than " << bInt << "." << endl;
}
return 0;
}
函数指针作为参数
函数指针可以作为一个函数的参数,如下两种办法可以做到这一点:
(a) int plusFun(int &, int &, int (const int &, const int &) );
(b) int plusFun(int &, int (*)(const int &, const int &) );
以上两个方式做到的是类似的事情: (a) 中的 plusFun 函数的第三个参数就是一个函数指针, (b) 中的第二个参数也是一个函数指针。下面我们分别定义前面声明的两个 plusFun 函数。
(a) 中的 plusFun 定义如下:
// 函数指针作为参数:错误的做法
//int plusFun(int& aInt, int& bInt, int paf(const int& cInt, const int& dInt))
//{
//
// return aInt + bInt + paf(cInt, dInt);
//}
// 函数指针作为参数:正确的做法
int plusFun(int & aInt, int & bInt, int paf(const int &, const int &))
{
int cInt = 2;
int dInt = 1;
return aInt + bInt + paf(cInt, dInt);
}
调用 plusFun 的代码:
…
pf = intCompare;
…
// 函数指针作为参数
int aaInt = 3;
int bbInt = 4;
cout << plusFun(aaInt, bbInt, pf) << endl;
(b) 中的 plusFun 定义如下:
// 函数指针作为参数:错误的做法
//int plusFun(int& aInt, int(*paf2)(const int& bInt, const int& cInt))
//{
// return aInt + paf2(bInt, cInt);
//}
// 函数指针作为参数:正确的做法
int plusFun(int & aInt, int (*paf2)(const int &, const int &))
{
int bInt = 1;
int cInt = 2;
return aInt + paf2(bInt, cInt);
}
调用 plusFun 的代码:
…
cmpFun pf2 = intCompare;
…
// 函数指针作为参数
int aaInt = 3;
cout << plusFun(aaInt, pf2) << endl;
函数指针作为返回值
一个函数的返回值可以是一个函数指针,这个声明形式写起来有点麻烦:
// 函数指针作为返回值
int (*retFunPointer(int ))(const int &, const int &);
上面的声明的含义:
a) retFunPointer 是一个函数,该函数有一个 int 类型的参数;
b) retFunPointer 返回值是一个函数指针,它指向的是带有两个 const int& 类型参数,且返回类型为 int 的函数。
retFunPointer 的定义:
// 函数指针为返回值
int (*retFunPointer(int aInt))(const int &, const int &)
{
cout << aInt << endl;
// pf 已经在前面定义过了
return pf;
}
调用代码示例:
// 函数指针作为返回值, retFunPointer 返回一个 cmpFun 类型的函数指针
cmpFun pf3 = retFunPointer(aaInt);
int result = pf3(aaInt, bbInt);
cout << result << endl;
包含上面所有情况的完整代码
#include <iostream>
#include <string>
using namespace std;
// 定义函数指针 pf
int (*pf)(const int &, const int &);
// 定义函数指针类型 cmpFun
typedef int (*cmpFun)(const int &, const int &);
// 函数指针作为参数
int plusFun(int &, int (const int &, const int &));
int plusFun(int &, int (*)(const int &, const int &));
// 函数指针作为返回值
int (*retFunPointer(int ))(const int &, const int &);
// 具体函数
int intCompare(const int & aInt, const int & bInt)
{
if (aInt == bInt) return 0;
if (aInt > bInt)
{
return 1;
}
else
{
return -1;
}
}
// 函数指针作为参数:错误的做法
//int plusFun(int& aInt, int& bInt, int paf(const int& cInt, const int& dInt))
//{
//
// return aInt + bInt + paf(cInt, dInt);
//}
// 函数指针作为参数:正确的做法
int plusFun(int & aInt, int & bInt, int paf(const int &, const int &))
{
int cInt = 2;
int dInt = 1;
return aInt + bInt + paf(cInt, dInt);
}
// 函数指针作为参数:错误的做法
//int plusFun(int& aInt, int(*paf2)(const int& bInt, const int& cInt))
//{
// return aInt + paf2(bInt, cInt);
//}
// 函数指针作为参数:正确的做法
int plusFun(int & aInt, int (*paf2)(const int &, const int &))
{
int bInt = 1;
int cInt = 2;
return aInt + paf2(bInt, cInt);
}
// 函数指针为返回值
int (*retFunPointer(int aInt))(const int &, const int &)
{
cout << aInt << endl;
// pf 已经在前面定义过了
return pf;
}
int main(void )
{
int aInt = 1;
int bInt = 2;
pf = intCompare;
// pf = &stringCompare; // 和上面一句是完全一样的
// 使用 pf
if (pf(aInt, bInt) == 0)
{
cout << "two integers are equal" << "." << endl;
}
else if (pf(aInt, bInt) > 0)
{
cout << aInt << " is greater than " << bInt << "." << endl;
}
else
{
cout << aInt << " is less than " << bInt << "." << endl;
}
cout << "------------------------" << endl;
// 用函数指针类型 cmpFun 声明并初始化一个函数指针 pf2
cmpFun pf2 = intCompare;
// 使用 pf2
if (pf2(aInt, bInt) == 0)
{
cout << "two integers are equal" << "." << endl;
}
else if (pf(aInt, bInt) > 0)
{
cout << aInt << " is greater than " << bInt << "." << endl;
}
else
{
cout << aInt << " is less than " << bInt << "." << endl;
}
cout << "------------------------" << endl;
// 函数指针作为参数
int aaInt = 3;
int bbInt = 4;
cout << plusFun(aaInt, bbInt, pf) << endl;
cout << plusFun(aaInt, pf2) << endl;
cout << "------------------------" << endl;
// 函数指针作为返回值, retFunPointer 返回一个 cmpFun 类型的函数指针
cmpFun pf3 = retFunPointer(aaInt);
int result = pf3(aaInt, bbInt);
cout << result << endl;
return 0;
}