C中的函数指针

时间:2020-02-23 14:32:04  来源:igfitidea点击:

C语言中的函数指针是指向函数的指针。

通过允许我们在函数中引用可执行代码,C语言为我们提供了一种使某些语句更快执行的方法。

此引用涉及函数指针,该函数指针指向内存(内存)中的此代码。

由于我们通过变量调用此函数,因此这种调用称为对该函数的间接调用。

让我们通过说明如何引用简单的swap()函数来理解这一点。

如果我们要创建一个引用swap()函数的函数指针,它将指向可执行代码,该代码以汇编语言显示。

因为我们直接引用了较低级别的代码,所以这将使整体执行速度更快。

现在我们已经涵盖了概念,让我们看一下如何为交换函数实际编写函数指针。

定义函数指针

在定义函数指针之前,让我们先分解一下所有函数的组成。

任何函数都将具有返回类型,传递给它的参数和名称,例如:

int function_name(char arg1, int arg2);

函数指针只是指向此类函数,因此我们可以定义如下函数指针:

int (*function_ptr)(char, char);

这就是说,function_ptr是一个函数指针,指向一个带有2个char参数并返回int的函数。

请注意括号(* function_ptr)。
这是因为我们必须明确指定它是一个指针。
否则,编译器可能会认为我们指向的是一个返回int *并抛出错误的函数。

同样,对于这样定义的函数:

char* str_concat(char* a, char* b);

函数指针的定义方式如下:

char* (*function_ptr_2)(char*, char*);

现在,我们已经定义了函数指针,现在,我们通过指向函数名称来引用函数。

function_ptr = &function_name;
function_ptr_2 = &str_concat;

请注意,由于函数无论如何都作为指针隐式传递,因此您无需显式提及引用与号(&),因此以下代码仍然有效。

function_ptr = function_name;
function_ptr_2 = str_concat;

直接初始化

另外,我们可以像其他任何指针一样直接在声明过程中指向该函数。

int (*function_ptr)(char, char) = function_name;
char* (*function_ptr_2)(char*, char*) = str_concat;

现在我们已经开始初始化指针,现在让我们看看它的实际作用!

使用函数指针

这真的很简单!我们只需要通过传递适当的参数来取消引用我们的函数指针,它将运行它所指向的可执行代码。
而已!

return_value = (*function_ptr)(arg1, arg2);

同样,您无需明确提及取消引用星号(),因为无论如何函数都是作为指针隐式传递的。
但是,如果这样做,则必须明确提及括号(
function_ptr)(arg1,arg2),因为函数调用的优先级高于取消引用。

return_value = function_ptr(arg1, arg2);

如果函数不带参数,则可以将" void"传递给参数列表。

让我们为我们的swap()函数执行此操作。

#include <stdio.h>

void swap(int* a, int* b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

int main() {
  int a = 20;
  int b = 10;
  //swap(&a, &amp;b);
  
  //Using function pointers
  void (*swap_ptr)(int*, int*) = swap;
  printf("Dereferencing the function pointer...\n");
  swap_ptr(&a, &amp;b);

  printf("a = %d, b = %d\n", a, b);
  return 0;
}

另一个例子

为了完成本文,我们将向您展示一个完整的示例。

这是一个简单的计算器程序,利用函数指针轻松处理个案。
优雅,不是吗?

#include <stdio.h>

double add(double a, double b) {
  return a + b;
}

double sub (double a, double b) {
  return a - b;
}

double mul(double a, double b) {
  return a * b;
}

double div (double a, double b) {
  return a/b;
}

double zero(double a, double b) {
  return 0.0;
}

double calculator(double a, double b, char option) {
  double result = 0.0;
  double (*funct_ptr)(double, double);
  if (option == 'A')
      funct_ptr = add;
  else if (option == 'S')
      funct_ptr = sub;
  else if (option == 'M')
      funct_ptr = mul;
  else if (option == 'D')
      funct_ptr = div;
  else
      funct_ptr = zero;
  result = funct_ptr(a, b);
  return result;
}

int main() {
  printf("%lf\n", calculator(10, 5, 'A'));
  printf("%lf\n", calculator(10, 5, 'S'));
  printf("%lf\n", calculator(10, 5, 'M'));
  printf("%lf\n", calculator(10, 5, 'D'));
  return 0;
}

输出

15.000000
5.000000
50.000000
2.000000

使功能指针指向多个其他功能代码的另一种方法是使用功能指针数组。
看看下面的示例代码。

#include <stdio.h>

double add(double a, double b) {
  return a + b;
}
double sub (double a, double b) {
  return a - b;
}
double mul(double a, double b) {
  return a * b;
}
double div (double a, double b) {
  return a/b;
}
double zero(double a, double b) {
  return 0.0;
}

int main() {
  double (*funct_ptr[])(double, double)={add,sub,mul,div};
  printf("%lf\n", funct_ptr[0](5,6));
  printf("%lf\n", funct_ptr[1](5,6));
  printf("%lf\n", funct_ptr[2](5,6));
  printf("%lf\n", funct_ptr[3](5,6));
  return 0;
}

11.000000                                                                                                                                     
-1.000000                                                                                                                                     
30.000000                                                                                                                                     
0.833333