指向函数的指针---恶补之三

定义一个指向函数的指针变量,用来存放某一个函数的起始地址,这就意味着此指针变量指向该函数。
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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值