【C++】浅谈函数指针

160 阅读2分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。

前言

随着C语言的深入学习,我开始考虑一些深层次功能的实现:变长参数、函数作参、函数数组……

WARNING

这些都是C语言书上很少提及的部分,但是他们却很有用,你甚至可以在STL中看到(sort函数)这些深层思想的算法,今天我们就谈论一下函数作参(函数作为参数)和函数数组吧(以数组的形式保存函数)。

什么是函数指针

在这之前,需要首先知道什么是函数指针。函数指针的定义形象点来说,就是用一个指针变量代替原函数中的函数名位置。 这里我发现了一个有趣的事,函数定义在相邻的位置,他们的函数指针地址是相近的。

#include <stdio.h>
int f1(int n){return n+1;}
int main(){
    printf("f1函数地址:%d\n",&f1);
    return 0;
}

我们得到了如下所示的函数地址:

  • f1函数地址:4199248

可以发现每个函数都有一个地址,那么我们能不能像指针一样用*符调用呢?

#include <stdio.h>
#define t 1
int f1(int n){return n+1;}
void show(int (*f)(int)){
    printf("%d\n",f(t));
}
int main(){
    show(f1);
    return 0;
}

输出为:2

这说明show把f1作为参数是成功调用了函数f1来执行的,即输出f1(t)=t+1f_1(t)=t+1

函数参数

从上一节可以看出,函数是可以作为参数的,函数指针&&函数指针参数定义方式如下:

返回类型(*函数参数名)(类型1 函数参数1,类型2 函数参数2……)

函数参数名可以省略,比如:

int (*f)(int)

等价于:

int (*f)(int n)

函数数组

函数数组就是用指针保存函数,定义方式也与普通数组有所区别。 若有如下4个函数:

int f1(int n){return n+1;}
int f2(int n){return n+2;}
int f3(int n){return n+3;}
int f4(int n){return n+4;}

那么函数数组定义为:

int (*f[4])(int)={f1,f2,f3,f4};

他的调用形式为:

f[i](n)

测试代码:

#include <stdio.h>
#define t 2
int f1(int n){return n+1;}
int f2(int n){return n+2;}
int f3(int n){return n+3;}
int f4(int n){return n+4;}
int (*f[4])(int)={f1,f2,f3,f4};
int main(){
    for(int i=0;i<4;i++)
        printf("函数指针数组f[%d](%d) = %d\n",i,t,f[i](t));
    return 0;
}

输出:

函数指针数组f[0](2) = 3
函数指针数组f[1](2) = 4
函数指针数组f[2](2) = 5
函数指针数组f[3](2) = 6

参考文献

怎样定义函数指针数组