C++基础之函数指针

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Africa_South/article/details/102296439

1.简介

函数指针 本身是一个指针变量,与指向整数的指针int* a类似,只不过它指向的是一个函数。
C语言编译的时候,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。
在这里插入图片描述
其一般有两个用途:调用函数和做函数的参数。

2. 用法

2.1 声明

数组指针 的声明一样,函数指针的声明也需要括号 (因为算符优先级的关系)。
下面的例子展示了如何声明函数指针。这个声明定义了一个指向函数的指针,该函数具有两个 int 类型的参数和 int 类型的返回值:

int* a[5]; // 指针数组,指向一个含有5个int*指针变量的数组
int (*a)[5]; // 数组指针,指向一个数组,数组含有5个int变量
int* add(int,int); // 声明的一个一般函数原型,不是指针定义
int (*add) (int,int); // 函数指针

注意:

  • 无论声明与否,函数名都被隐式地转换成函数指针;
  • 即C语言中函数名本身就是一个函数指针
2.2 函数调用
double (*funcPtr) (double, double); // 声明
double ans;
funcPtr = pow;   // 使得funcPtr指向幂函数pow()

ans = (*funcPtr)(1.0,2.0);  // 解引用
ans = funcPtr(1.0,2.0);     // 与上面等效

如本例中最后一行所示,当使用指针调用函数时,可以不用间接运算符,因为函数调用运算符的左操作数具有函数指针类型。

也可以在数组中存储函数指针,然后使用数组的索引来调用这些函数。
例如,键盘驱动程序可能使用函数指针数组,数组索引对应到了键盘编码。当用户按下一个键时,程序就会跳到对应的函数。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double Add( double x, double y ) { return x + y; }
double Sub( double x, double y ) { return x - y; }
double Mul( double x, double y ) { return x * y; }
double Div( double x, double y ) { return x / y; }

// 具有5个函数指针的数组,这些函数需要两个double类型参数,返回值为double类型
double (*funcTable[5])(double, double)
          = { Add, Sub, Mul, Div, pow };        // 初始化器列表

// 一个字符串指针数组,用于输出:
char *msgTable[5] = {"Sum", "Difference", "Product", "Quotient", "Power"};

int main()
{
  int i;                                                // 索引变量
  double x = 0, y = 0;

  printf( "Enter two operands for some arithmetic:\n" );
  if ( scanf( "%lf %lf", &x, &y ) != 2 )
    printf( "Invalid input.\n" );

  for ( i = 0; i < 5; ++i )
    printf( "%10s: %6.2f\n", msgTable[i], funcTable[i](x, y) );

  return 0;
}

表达式 funcTable[i](x,y)会调用地址保存在指针 funcTable[i] 中的函数。数组名称和下标不需要被包含在括号内,因为函数调用运算符()和下标运算符 [] 都具有最高的优先级,以及从左至右的结合律。

注意:
采用 typedef 定义简单的类型名称,对于诸如函数指针数组这样的复杂类型,将更容易管理。
例如,可以采用如下形式定义数组 funcTable:

typedef double func_t( double, double );      // 函数类型名称定义为func_t
func_t *funcTable[5] = { Add, Sub, Mul, Div, pow }; // 比上面地可读性高

上诉引自C语言指向函数的指针

2.3 函数参数

函数指针还可以当作一个函数参数传递给另一个函数,即当另一个函数需要调用此函数时,例如
C语言地stdlib.h中实现了一个快排qsort()的库函数,其声明如下

void qsort(
	void* base, // 排序的基地址
	size_t num, // 元素个数
	size_t size,// 元素大小
	int (*comparator) (consr void*, const void*) // 比较准则
);

在实际使用的时,我们需要传递一个比较函数的传递指针给qsort(),例如,当比较元素为整数时:

int cmp(const void* a, const void* b){
	return *(int*) a - *(int *) b;
}

猜你喜欢

转载自blog.csdn.net/Africa_South/article/details/102296439