「这是我参与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来执行的,即输出。
函数参数
从上一节可以看出,函数是可以作为参数的,函数指针&&函数指针参数定义方式如下:
返回类型(*函数参数名)(类型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