定义一个指向函数的指针变量,用来存放某一个函数的起始地址,这就意味着此指针变量指向该函数。
int (*p)(int ,int);
定义p是一个指向函数的指针变量,它可以指向函数的类型为整型且有两个整型参数的函数,p的类型用int(* )(int ,int)表示。
double (*pf)(int);//pf points to a function that returns double
double *pf(int); //pf() a function that returns a pointer-to-double
double pam(int);
double (*pf)(int);
pf=pam;//pf now points to the pam() function
double x=pam(4);//call pam() using the function name
double y=(*pf)(4);//call pam() using the pointer pf
// double y=pf(4); is ok
用函数求得a和b中的大者
#include<stdio.h>
int main()
{
int max(int ,int);//函数声明
int (*p)(int,int);//定义指向函数的指针变量p
int a,b,c;
p=max;//使p指向max函数
printf("please enter a and b:");
scanf_s("%d,%d",&a,&b);
c=(*p)(a,b);//通过指针变量调用max函数,等价于c=max(a.b)
printf("a=%d,b=%d\nmax=%d\n",a,b,c);
return 0;
}
int max(int x,int y)
{
int z;
if(x>y) z=x;
else z=y;
return(z);
}
定义指向函数的指针变量一般形式为
类型名 (*指针变量名)(函数参数表列)
定义返回指针值的函数的一般形式为
*类型名 函数名(参数表列)**int *a(int x, int y)
例8.25 有a个学生,每个学生有b门课程的成绩,要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。//设学生3人,课程为4门
#include<stdio.h>
int main()
{
float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}}
float *search(float(* pointer)[4],int n);//
float *p;
int i,k;
printf("please enter the number of student:");
scanf_s("%d",&k);
printf("The score of No.%d are:\n",k);
p=search(score,k);//
for(i=0;i<4;i++)
{
printf("%5,2f\t",*(p+i));//输出score[k][0]~score[k][3]的值
}
printf("\n");
return 0;
}
float *serach(float (* pointer)[4],int n)//形参pointer是指向一维数组的指针变量,pointer的类型是float(*)[4],是指向包含4个元素的一维数组的指针变量。
{
float *pt;
pt=*(pointer+n);//pt的值是&score[k][0]
return(pt);
}
注:多维数组a[3][4]
a+1代表序号为1的行的首地址。a[1]的值是&a[1][0];
a[0] equals to *(a+0)
a[i][j] equals to *(a[i]+j) or
* ( *(a+i)+j)
Tips:
pa(它是数组名,表示地址)和&pa之间的差别。大多数情况下,pa都是数组第一个元素的地址,即&pa[0]。因此它是单个指针的地址。但是&pa是整个数组(即三个数组块)的地址。从数字上,pa和&pa的值相等,但是类型不同。pa+1为数组中下一个元素的地址,而&pa+1为数组pa后面一个12字节内存块的地址(这里假定地址为4个字节)。另一个差别就是,要得到第一个元素的值,只需要对pa解除一次引用,但需要对&pa解除两次引用:
**&pa==*pa==pa[0]
C++ primer plus P246
//artfupt.cpp –an array of function pointers
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<array>
#include<vector>
const double* f1(const double ar[], int n);
const double* f2(const double [], int n);
const double* f3(const double *, int n);
int main()
{
using namespace std;
double av[3] = { 111.1, 222.2, 333.3 };
//pointer to a function
const double* (*p1)(const double*, int) = f1;
auto p2 = f2;
cout << "Using pointers to function:\n";
cout << "Address Value\n";
cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl;
cout << p2(av, 3) << ": " << *p2(av, 3) << endl;
//pa an array of pointers
//auto doesn't work with list initialization
const double* (*pa[3])(const double*, int) = {f1,f2,f3};
//but auto does work for initializing to a single vlaue
//pb a pointer to first element of pa
auto pb = pa;
cout << "Using an array of pointers to function:\n";
cout << "Address Value\n";
for (int i = 0; i < 3; i++)
cout << pa[i](av, 3) << ": " << *pa[i](av, 3) << endl;
cout << "Using a pointer to pointers to function:\n";
cout << "Address Value\n";
for (int i = 0; i < 3;i++)
cout << pb[i](av, 3) << ": " << *pb[i](av, 3) << endl;
//a pointer to an array of function pointers
cout << "Using pointers to an array of pointers:\n";
cout << "Address Value\n";
auto pc = &pa;
cout << (*pc)[0](av, 3) << ": " << *(*pc)[0](av, 3) << endl;
const double *(*(*pd)[3])(const double*, int) = &pa;
cout << (*pd)[1](av, 3) << ": " << *(*(*pd)[1])(av, 3) << endl;
system("pause");
return 0;
}
const double* f1(const double ar[], int n){
return ar;
}
const double* f2(const double *ar, int n){
return ar + 1;
}
const double* f3(const double *ar, int n){
return ar + 2;
}
使用typedef进行简化
typedef const double *(*p_fun)(const double*,int);//p_fun now a type name
p_fun p1=f1;//p1 points to function f1()