函数指针重要概念:
- 与数据项类似,函数也有地址,函数的地址是存储其机器语言代码内存的开始地址。该特性对程序而言,可以将另一个函数的地址作为参数的函数,它允许在不同的时间传递不同的函数地址,这意味着可以在不同的时间使用不同的函数;
- 声明函数指针时,必须同时指定函数的返回类型和参数列表;
- 若对于函数指针
double (*funcPtr)(int)
而言可以通过两种方法调用,一是:double y = (*funcPtr)(5)
,二是double y = funcPtr(5)
; []
的优先级比*
优先级高,通常使用如double (*funcPtr[3])(const double *, int)= {f1, f2, f3}
表示三个函数指针的数组。创建一个指向整个数组的指针可用如下形式表示double (*(*ptr)[3]))(const double *, int)
,ptr
是一个指针,指向一个包含三个元素的数组,这些元素有该声明的其他部分描述;- 对于数组
int pa[3] = {0, 1, 2};
而言,pa
与&pa
的区别。在大多数情况下,pa都是数组第一个元素的地址,即&pa[0]
,从数字上说,pa
和&pa
相同,但他们的类型不同,&pa的类型为int(*)[3]
,一种差别是pa+1
为指向下一个元素的地址,而&pa+1
为数组pa后面加上一个12字节内存块的地址(假定地址为4字节),另一个差别就是要得到第一个元素,只需要对pa
解除一次引用,但需要对&pa
解除两次引用,即**&pa == *pa == pa[0]
;
#include <iostream>
using namespace std;
double betsy(int);
double pam(int);
void estimate(int lines, double (*pf)(int));
int main()
{
int code;
cout << "How many lines of code do you need?" << endl;
cin >> code;
cout << "Here's Bytes's estimate:\n";
estimate(code, betsy);
cout << "Here's Pam's estimate:\n";
estimate(code, pam);
}
double betsy(int lines)
{
return 0.05 * lines;
}
double pam(int lines)
{
return 0.01 * lines;
}
void estimate(int lines, double (*pf)(int))
{
cout << lines << " lines will take ";
cout << (*pf)(lines) << " hour(s)" << endl;
}
输出:
#include <iostream>
using namespace std;
const double* func1(const double arr[], int n);
const double* func2(const double [], int n);
const double* func3(const double *, int n);
int main()
{
double arr[3] = {1.i11, 2.22, 3.33};
const double* (*ptr1)(const double *, int) = func1;
//const double* (*ptr2)(const double *, int) = func2;
auto ptr2 = func2; //after c++11
cout << "Usage pointers to functions:\n";
cout << "Address Value\t:\tValue\n";
cout << (*ptr1)(arr, 3) << "\t:\t" << *(*ptr1)(arr, 3) << endl;
cout << ptr2(arr, 3) << "\t:\t" << *ptr2(arr, 3) << endl;
const double* (*ptrA[3])(const double *, int) = {func1, func2, func3};
cout << "\nUsing an array of pointers to functions:\n";
cout << "Address Value\t:\tValue" << endl;
for(int i = 0; i < 3; i++)
{
cout << ptrA[i](arr, 3) << "\t:\t" << *ptrA[i](arr, 3) << endl;
}
//auto ptrB= ptrA;
const double* (**ptrB)(const double *, int) = ptrA;
cout << "\nUsing a pointer to a pointer to a function:\n" << endl;
cout << "Address Value\t:\tValue\n";
for(int i = 0; i < 3; i++)
{
cout << ptrB[i](arr, 3) << "\t:\t" << *ptrB[i](arr, 3) << endl;
}
cout << "\nUsing pointer to an array of pointers:\n";
cout << "Address Value\n";
//const double* (*(*ptrC)[3])(const double *, int) = &ptrA;
auto ptrC = &ptrA;
cout << (*ptrC)[0](arr, 3) << "\t:\t" << *(*ptrC)[0](arr, 3) << endl;
const double* (*(*ptrD)[3])(const double *, int) = &ptrA;
const double *ptrDp = (*ptrD)[1](arr, 3);
cout << ptrDp << "\t:\t" << *ptrDp << endl;
cout << (*(*ptrD)[2])(arr, 3) << "\t:\t" << *(*(*ptrD)[2])(arr, 3) << endl;
return 0;
}
const double* func1(const double *arr, int n)
{
return arr;
}
const double* func2(const double *arr, int n)
{
return arr + 1;
}
const double* func3(const double *arr, int n)
{
return arr + 2;
}
注意对const double* (*(*ptrC)[3])(const double *, int) = &ptrA;
和const double* (**ptrB)(const double *, int) = ptrA;
的理解:
()
的优先级比*
高,如const double* f1(const double *, int);
表示返回值类型为const double*
的函数;