C语言函数指针(指向函数的指针)的声明、赋值、调用

一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是函数指针。

函数指针的定义形式为:

retrunType(*pointerName)(param list); //数据类型(*指针变量名)();
//注意与二维数组的指针的定义区别开(int (*p)[4] = a;)

returnType 为函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表。参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称,这一点和函数原型非常类似。

注意()的优先级高于*,第一个括号不能省略,如果写作returnType *pointerName(param list);就成了函数原型,它表明函数的返回值类型为returnType *
比如

int *fun(int a,int b); //返回值是int类型指针的函数
int (*p)(int a,int b); //一个指向函数的指针

【实例1】用指针实现对函数的调用

#include <stdio.h>

//返回两个数中较大的一个
int max(int a, int b){
    return a>b ? a : b;
}

int main(){
    int x, y, maxval;
    //定义函数指针
    int (*pmax)(int, int) = max;  //也可以写作int (*pmax)(int a, int b)
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);
    maxval = (*pmax)(x, y);
    printf("Max value: %d\n", maxval);

    return 0;
}

运行结果:
Input two numbers:10 50↙
Max valu:50
第 14 行代码中pmax 是一个函数指针,在前面加 * 就表示对它指向的函数进行调用。

【实例2】

#include  <stdio.h>
double f1(double  x)
{  return  x*x;  }
double f2(double x, double y)
{  return  x*y;  }
double fun(double  a, double  b)
{

  double (*f)();
  double  r1, r2;

  f = f1 ;   //函数指针的赋值
  //f=&f1;   //第二种赋值方法

  r1 = f(a); //函数指针第一种调用方法,也可以写成 r1=(*f)(a);

  f = f2 ; 
  r2 = (*f)(a, b); //函数指针第二种调用方法,也可以写成 r2=f(a,b);
  return  r1 + r2;
}
void main()
{ double  x1=5, x2=3, r;
  r = fun(x1, x2);
  printf("\nx1=%f,  x2=%f,  x1*x1+x1*x2=%f\n",x1, x2, r);
}

运行结果:
x1=5.000000, x2=3.000000, x1x1+x1x2=40.000000
double(*f)();代表一个指向函数的指针变量; f=f1; 表示把函数f1赋值给f;

注意:
(1)在给函数指针变量赋值时,只需给出函数名而不必给出参数值,因此直接令 f=f1 即可;
(2)注意上面代码的注释部份,赋值和调用的方法都有两种,两种都是可以的。

对于函数指针的赋值:函数名是一个地址,可以将他赋值给一个指向函数的指针。前面加了&符号其意义是一样的。比如定义一个数组arr[],arr表示这个数组的首地址,但&arr同样表示他的首地址。
对于函数指针的调用:比如你定义一个字符串指针char *str, 输出str 他并不是输出了地址,而是输出存在该地址的值。

C语言函数指针(指向函数的指针)的声明、赋值、调用

上一篇:Java学习之项目加入日志文件log4j和logback


下一篇:二分查找-数组