函数名是什么
函数名和数组名一样表示的都是地址,不同的是函数名是执行函数代码的起始位置,数组是数组第一个元素的地址。
我们可以验证一下,直接打印出函数名的值和函数地址,代码如下:
#include <stdio.h>
void func(); //函数声明
int main(){
func();
printf("func = %d\n",func);
printf("&func = %d\n",&func);
}
void func(){
printf("Hello world\n");
}
函数指针是什么
既然函数名是地址,那么我们就可以使用一个指针来指向一个函数,这时这种类型的指针就称之为函数指针,其实本质上他还是一个指针。
定义方式如下:
函数返回值类型 (*指针变量名)(传入该函数的参数)
如:int (*func) (char)
其实是指一个名为func的函数指针,该指针指向一个返回值类型为int,传入参数为char的函数。
函数指针使用
有了函数指针之后,我们就可以在某种意义上将函数看作一个变量,我们调用函数的方式除了直接使用函数名来调用,还可以通过函数指针解引用来调用函数。
在此,我们借助实现一个有关数组的计算器来帮助大家理解函数指针。
1. 函数指针与指针数组结合使用
1.print_array
函数
功能:打印数组中的元素
注:我们向该函数传入的参数有数组名,和该数组的元素个数,由于数组名是数组中第一个元素的地址,所以我们在函数中使用一个指针来接受它,虽然在函数中我们看到的是int arr[]
,但它其实是为了让读者更容易理解这个参数的意义,本质上还是一个指针。
除此以外,我们还需要注意到指针的算术运算,arr+n
其实是指将该指针指向从arr指向的元素后的第n个元素。
void print_array(int arr[],int n){
int *p = arr;
while(p<arr+n){
printf("%d ",*p++);
}
printf("\n");
}
2. add_array函数
功能:求数组中元素之和
注:++p<arr+n
是指p=p+1;p<arr+n
,也就是说以下这个函数的循环是从数组中的第二个元素开始的,我们在进入循环之前就像数组中的第第一个元素加入我们的求和的结果res
中了。
代码如下:
int add_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res + *p;
}
return res;
}
3. subtract_array函数
功能:将数组中的元素相减
具体代码如下:
int subtract_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res - *p;
}
return res;
}
4. multipy_array函数
功能:将数组中的元素相乘
具体代码如下:
int multipy_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res * *p;
}
return res;
}
5. divide_array函数
功能:将数组中的元素相减
代码如下:
int divide_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res / *p;
}
return res;
}
6. 函数指针的使用
在没有函数指针的时候,我们此时调用这些函数是直接使用函数名来进行调用的。具体如下:
printf("%d\n",add_array(arr,n));
printf("%d\n",subtract_array(arr,n));
printf("%d\n",multipy_array(arr,n));
printf("%d\n",divide_array(arr,n));
但是我们有了函数指针后,我们将这些函数放进指针数组里,如下:
int (*pfunc[4])(int*,int) = {add_array,subtract_array,multipy_array,divide_array};
这时我们就可以直接进行循环调用了,具体代码如下:
for(int i=0;i<4;++i){
printf("%d\n",pfunc[i](arr,n));
}
2. 函数指针作为参数使用
除了以上的操作外,函数指针还可以直接作为参数来进行调用。
我们来定义一个新的函数,如下:
函数功能:使用传给operation函数的函数指针opt来调用opt指向的函数。
来计算我们想要的结果。假如此时该函数指针指向功能为将数组元素相加的函数,那么此时该函数的功能就是将数组中的元素全部相加。
int add(int a,int b){
return a+b;
}
int subtract(int a,int b){
return a-b;
}
int multipy(int a,int b){
return a*b;
}
int divide(int a,int b){
return a/b;
}
int operation(int arr[],int n, int (*opt)(int,int)){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = opt(res,*p);
}
return res;
}
3. 参考代码
1. 代码一
#include <stdio.h>
void print_array(int arr[],int n){
int *p = arr;
while(p<arr+n){
printf("%d ",*p++);
}
printf("\n");
}
int add_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res + *p;
}
return res;
}
int subtract_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res - *p;
}
return res;
}
int multipy_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res * *p;
}
return res;
}
int divide_array(int arr[],int n){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = res / *p;
}
return res;
}
int main(){
int n;
scanf("%d",&n);
int arr[n];
int *p = arr;
while(p<arr+n){
scanf("%d",p++);
}
print_array(arr,n);
printf("%d\n",add_array(arr,n));
printf("%d\n",subtract_array(arr,n));
printf("%d\n",multipy_array(arr,n));
printf("%d\n",divide_array(arr,n));
int (*pfunc[4])(int*,int) = {add_array,subtract_array,multipy_array,divide_array};
for(int i=0;i<4;++i){
printf("%d\n",pfunc[i](arr,n));
}
}
2. 代码二
int add(int a,int b){
return a+b;
}
int subtract(int a,int b){
return a-b;
}
int multipy(int a,int b){
return a*b;
}
int divide(int a,int b){
return a/b;
}
int operation(int arr[],int n, int (*opt)(int,int)){
int *p = arr;
int res = *p;
while(++p<arr+n){
res = opt(res,*p);
}
return res;
}
int main(){
int n;
scanf("%d",&n);
int arr[n];
int *p = arr;
while(p<arr+n){
scanf("%d",p++);
}
int (*opt[4])(int,int) = {add,subtract,multipy,divide};
for(int i=0;i<4;++i){
printf("%d\n",operation(arr,n,opt[i]));
}