C语言函数指针 Function pointer in C

435 阅读19分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

General

A pointer to function in C is one of the most important pointer tools which is often ignored and misunderstood by the people. Generally, people face the problem with function pointer due to an improper declaration, assignment and dereferencing the function pointer.

Misunderstanding of the fundamental concept of function pointers can create issues in the project. This issue can waste a lot of your time and can be the cause of project failure. The problem with a pointer to a function is that it is one of the most difficult topics in C language. Only a few people understand the proper utilization of pointer to function in C.

So In this blog post, I will explain the basic concept of a function pointer and how you can use a function pointer in C programming. So let us come on the topics.

C语言中的函数指针是最重要的指针工具之一,经常被人们忽略和误解。 通常,由于不正确的声明,分配和取消引用功能指针,人们会遇到功能指针的问题。

对函数指针的基本概念的误解会在项目中造成问题。 此问题可能会浪费大量时间,并且可能是项目失败的原因。 指向函数的指针的问题在于,它是C语言中最困难的主题之一。 只有少数人了解C语言中对函数的指针的正确使用。

因此,在这篇文章中,我将解释函数指针的基本概念以及如何在C编程中使用函数指针。 因此,让我们来谈谈这些话题。

What is a function pointer or pointer to function?

A function pointer is similar to the other pointers but the only difference is that it stores the address of a function instead of a variable. In the program whenever required we can invoke the pointed function using the function pointer. So using the function pointer we can provide the run time binding in C programming which resolves the many problems.

函数指针与其他指针相似,但唯一的区别是它存储函数的地址而不是变量。 在程序中,只要需要,我们都可以使用函数指针来调用指向的函数。 因此,使用函数指针,我们可以在C编程中提供运行时绑定,从而解决了许多问题。

function pointer

How to declare function pointer in C?

The syntax for declaring function pointers are very straightforward. It seems difficult in the beginning but once you are familiar with function pointer then it becomes easy. Its declaration is almost similar to the function declaration, it means you need to write return type, argument list, and function pointer name.  Let us see the syntax of the function pointer declaration.

声明函数指针的语法非常简单。 一开始似乎很困难,但是一旦您熟悉了函数指针,它就会变得很容易。 它的声明与函数声明几乎类似,这意味着您需要编写返回类型,参数列表和函数指针名称。 让我们看看函数指针声明的语法。

Function_return_type(*Function_Pointer_name)(Function argument list);

Here is an example :

示例:

//It can point to function which takes an int as an argument and return nothing.
void ( *fpData )( int);//It can point to function which takes a const char * as an argument and return nothing.
void( *pfDisplayMessage) (const char*);

Note:  The function pointer name is preceded by the indirection operator ( * ).

Braces have a lot of importance when you declare a pointer to function in C programming. If in the above example, I remove the braces, then the meaning of the above expression will be changed. It becomes the declaration of a function that takes the const character pointer as arguments and returns a void pointer.

注意:函数指针名称的前面是间接运算符(*)。

当您声明C编程中的函数的指针时,括号非常重要。 如果在上面的示例中删除了括号,那么以上表达式的含义将被更改。 它成为以const字符指针作为参数并返回空指针的函数的声明。

void *pfDisplayMessage(const char*);

List of some function pointers

A function pointer must have the same signature to the function that it is pointing to. In a simple word, we can say that the function pointer and its pointed function should be the same in the parameters list and return type.

So there can be a lot of possibility of a function pointer in C. In the below section, I am listing some function pointers and I want you to write the explanation of these function pointers in the comment box.

函数指针必须具有与其指向的函数相同的签名。 简而言之,我们可以说函数指针及其指向的函数在参数列表和返回类型中应该相同。

因此,在C中有很多函数指针的可能性。在下面的部分中,我列出了一些函数指针,并且希望您在注释框中写下这些函数指针的说明。

void (*fpData)(void);
int  (*fpData)(int);
int  (*fpData)(char *);
int* (*fpData)(char *);
int  (*fpData)(int, char *);
int* (*fpData)(int, int *, char *);
int* (*fpData)(int , char, int (*paIndex)[3]);
int* (*fpData)(int , int (*paIndex)[3] , int (* fpMsg) (const char *));
int* (*fpData)(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));
int* (*fpData[2])(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));
int* (*(*fpData)(const char *))(int (*paIndex)[3] , int (* fpMsg) (const char *), int (* fpCalculation[3]) (const char *));

Initialization of function pointer in C

We have already discussed that a function pointer is similar to normal pointers. So after the declaration of a function pointer, we need to initialize it like normal pointers. A function pointer is initialized to the address of a function but the signature of function pointer should be the same as the function.

我们已经讨论过,函数指针与普通指针相似。 因此,在声明函数指针之后,我们需要像普通指针一样对其进行初始化。 函数指针被初始化为函数的地址,但函数指针的签名应与函数相同。

Let consider an example,

Before using the function pointer we need to declare it and the prototype must be similar to the function which addresses you want to store.  In the below example, I want to store the address of a function (AddTwoNumber) which takes two integers as an argument and returns an integer.

So below I am creating a function pointer that takes two integers as an argument and returns an integer.

在使用函数指针之前,我们需要对其进行声明,并且原型必须类似于您要存储的地址的函数。 在下面的示例中,我想存储一个函数的地址(AddTwoNumber),该函数将两个整数作为参数并返回一个整数。

所以下面我创建一个函数指针,该函数指针将两个整数作为参数并返回一个整数。

//declaration of function pointer
int (* pfAddTwoNumber) (int, int);

Now its time to initialize the function pointer with function address. There is two way to initialize the function pointer with function address. You can use the address-of operator ( &) with function name or you can use directly function name (Function name also represents the beginning address of the function).

现在该用函数地址初始化函数指针了。 有两种使用函数地址初始化函数指针的方法。 您可以在函数名称中使用地址运算符(&),也可以直接使用函数名称(函数名称也代表函数的起始地址)。

pfAddTwoNumber = &AddTwoNumber;
            or
pfAddTwoNumber = AddTwoNumber;

If you want like another pointer you can initialize the function pointer at the time of declaration, like the below code. Some times it is useful and saves your extra line code.

如果您想要另一个指针,则可以在声明时初始化函数指针,如下面的代码。 有时它很有用,并节省了额外的行代码。 

int (* pfAddTwoNumber) (int, int) = AddTwoNumber;

Let's see an example that shows the declaration and initialization of function pointer. It also explains how to function pointer is used to invoke the pointed function.

让我们看一个显示函数指针的声明和初始化的示例。 它还说明了如何使用函数指针来调用指向的函数。

#include <stdio.h>
// A function with an const char pointer parameter
// and void return type
void DisplayMessage(const char *msg)
{
    printf("Message  =>>  %s\n", msg);
}
int main()
{
    // pfDisplayMessage is a pointer to function DisplayMessage()
    void ( *pfDisplayMessage) (const char *) = &DisplayMessage;
    // Invoking DisplayMessage() using pfDisplayMessage
    (*pfDisplayMessage)("Hello Yanfeng Technology");
    return 0;
}

Output:  Message =>> Hello Yanfeng Technology

Some important concept related to pointer to function

1) Memory allocation and deallocation for function pointer:

Dynamic memory allocation is not useful for function pointers. We create the function pointer only to point to a function. So if you allocate the dynamic memory for the function pointer then there is no importance to create the function pointer.

动态内存分配对于函数指针没有用。 我们创建函数指针只是为了指向一个函数。 因此,如果为函数指针分配动态内存,那么创建函数指针就没有任何意义。

// Not useful expression
void (*pfData) (int)  = malloc(sizeof(pfData));

2) Comparing function pointers:

We can use the comparison operators (== or != ) with function pointer. These operators are useful to check that the function pointer is pointing to a valid memory or not. Before calling a function pointer in the program you must check its validity and it is very good practice to check the validity of function pointer.

When we compare two function pointers then we have to remember that two pointers of the same type compare equal if and only if they are both null, both points to the same function or both represent the same address

In your program, if the function pointers are not initialized by the valid address and your application wants to execute the function pointer then the application might be crashed. In the case of drivers, you might face BSOD (Blue screen of death ) or system hangs issues.

So whenever you create function pointer in your program then at the time of creation you must initialize it NULL. Also before executing the function pointer, you must check its validity by comparing it with the null pointer ( != NULL ).

我们可以将比较运算符(==或!=)与函数指针一起使用。这些运算符对于检查函数指针是否指向有效内存很有用。在程序中调用函数指针之前,必须检查其有效性,并且检查函数指针的有效性是一种很好的做法。

当我们比较两个函数指针时,我们必须记住,当且仅当两个指针都为null,两个指向同一函数或都表示相同地址时,两个相同类型的指针才会相等

在您的程序中,如果未通过有效地址初始化函数指针,而您的应用程序要执行该函数指针,则该应用程序可能会崩溃。对于驱动程序,您可能会遇到BSOD(蓝屏死机)或系统挂起问题。

因此,无论何时在程序中创建函数指针,都必须在创建时将其初始化为NULL。同样,在执行函数指针之前,必须通过将其与空指针(!= NULL)进行比较来检查其有效性。         

For Example,

Here, pfLedOnOff is a function pointer, which is called to make led On or Off.

在这里,pfLedOnOff是一个函数指针,调用该指针可使led变为On或Off。

if( pfLedOnOff!= NULL)
{
    // calling of function function
    (*pfLedOnOff) (iLedState);
}
else
{
    retrun Invalid;
}

3) Assigning function address to a function pointer:

There is two way to assign the address of the function to a pointer to function. You can use the address-of operator ( &) with function name or you can use directly function name (Function name also represents the beginning address of the function).

有两种方法可以将函数的地址分配给函数指针。 您可以在函数名称中使用地址运算符(&),也可以直接使用函数名称(函数名称也代表函数的起始地址)。

//Assigning function address to the function pointer
Function_Pointer = Function_Name;
                 or
//Assigning function address to the function pointer
Function_Pointer = &Function_Name;

4) Calling a function using the function pointer:

After assigning the function address to the function pointer, you can call the function using the function pointer. Bellow, we are describing the function calling by function pointer in a few steps. So let see the mentioned steps to how to use a pointer to function for calling a function.

将函数地址分配给函数指针后,可以使用函数指针来调用函数。 在下面,我们将分几步描述通过函数指针进行的函数调用。 因此,让我们看一下上面提到的有关如何使用指针来调用函数的步骤。

  • Like another pointer, you need to dereference the function pointer using the indirection operator ( *).  Let us consider the below statement,
  • 与其他指针一样,您需要使用间接运算符(*)解引用函数指针。 让我们考虑以下陈述,
	
*Function_Name
  • The second step is to cover the function pointer with braces.
  • 第二步是用括号覆盖函数指针。
	
(*Function_Name)
  • The third step to pass the argument list in function pointer if available. If there is no argument list then left argument braces empty.
  • 第三步,在可用的函数指针中传递参数列表。 如果没有参数列表,则左参数括号为空。
//Function pointer which has argument list
(*Function_Name)(ArgumentList);
 
or
//Function pointer without argument list
(*Function_Name)();

Let’s see an example, for better understanding. In this example code, I am calling a function using the function pointer. This function is used to add the value of two integers.

让我们看一个例子,以更好地理解。 在此示例代码中,我使用函数指针调用函数。 此函数用于将两个整数的值相加。

#include <stdio.h>
#include <stdlib.h>
 
//function used to add two numbers
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}
 
int main(int argc, char *argv[])
{
    int iRetValue = 0;
    //Declaration of function pointer
    int (*pfAddTwoNumber)(int,int) = NULL;
    //initialize the function pointer
    pfAddTwoNumber = AddTwoNumber;
 
    //Calling the function using the function pointer
    iRetValue = (*pfAddTwoNumber)(10,20);
 
    //display addition of two number
    printf("\n\nAddition of two number = %d\n\n",iRetValue);
 
    return 0;
}

OutPut:

Explanation of the above program:

In the above program first I am declaring a function pointer pfAddTwoNumber and initializing it with NULL. It can store the address of a function that takes two integers as an argument and returns an integer.

首先在上面的程序中,我声明一个函数指针pfAddTwoNumber并将其初始化为NULL。 它可以存储以两个整数作为参数并返回一个整数的函数的地址。

//Declaration of function pointer
int(*pfAddTwoNumber)(int,int) = NULL;

After the declaration of the function pointer next step is to initialize it with function address.

在声明函数指针之后,下一步是使用函数地址对其进行初始化。

pfAddTwoNumber = AddTwoNumber;

Now we can call the function using the function pointer with the help of indirection operator ( * )and braces.

现在我们可以在间接操作符(*)和括号的帮助下使用函数指针来调用函数。

//Calling the function using the function pointer
iRetValue = (*pfAddTwoNumber)(10,20);
 
//or
//Calling the function using the function pointer
iRetValue = pfAddTwoNumber(10,20);

Note:  You can omit the indirection operator at the time of function call using the function pointer.

注意:您可以在调用函数时使用函数指针省略间接操作符。

5) Function pointer as arguments

We can pass the function pointer as an argument into the function. Let’s take an example to understand how to pass a function pointer in a function and what its benefits.

In the below example code, I am creating a function ArithMaticOperation that takes three arguments two integers and one function pointer. This function will invoke the passed function using the function pointer which performs the arithmetic operation on the passed integer variable.

The benefit is that using one function user can perform multiple arithmetic operations. Like addition, subtraction, multiplication, and division of two numbers.

我们可以将函数指针作为参数传递给函数。 让我们举一个例子来了解如何在函数中传递函数指针以及它的好处。

在下面的示例代码中,我正在创建一个函数ArithMaticOperation,该函数接受三个参数,两个整数和一个函数指针。 该函数将使用函数指针调用传递的函数,该函数指针对传递的整数变量执行算术运算。

好处是使用一个功能,用户可以执行多个算术运算。 像两个数的加法,减法,乘法和除法。

#include <stdio.h>
typedef  int (*pfunctPtr)(int, int); /* function pointer */
//function pointer as arguments
int ArithMaticOperation(int iData1,int iData2, pfunctPtr Calculation)
{
    int iRet =0;
    iRet = Calculation(iData1,iData2);
    return iRet;
}
/*function add two number*/
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}
/*function subtract two number*/
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}
/*function multiply two number*/
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}
int main()
{
    int iData1 = 0;
    int iData2 = 0;
    int iChoice = 0;
    int Result = 0;
    printf("Enter two Integer Data \n\n");
    scanf("%d%d",&iData1,&iData2);
    printf("Enter 1 for Addition \n\n");
    printf("Enter 2 for Subtraction \n\n");
    printf("Enter 3 for Multiplication \n\n");
    printf("User choice :");
    scanf("%d",&iChoice);
    switch(iChoice)
    {
        case 1:
            Result = ArithMaticOperation(iData1,iData2,AddTwoNumber);
            break;
        case 2:
            Result = ArithMaticOperation(iData1,iData2,SubTwoNumber);
            break;
        case 3:
            Result = ArithMaticOperation(iData1,iData2,MulTwoNumber);
            break;
        default:
            printf("Enter Wrong Choice\n\n");
    }
    printf("\n\nResult  = %d\n\n",Result);
    return 0;
}

OutPut:

6) Return a function pointer from the function

Yes, we can return function pointer from the function. See the below code where I am returning a function pointer from the function. In the example code, I am using a typedef for defining a type for a function pointer. 

是的,我们可以从函数中返回函数指针。 请参阅下面的代码,其中我从函数中返回函数指针。 在示例代码中,我使用typedef定义函数指针的类型。

#include <stdio.h>
/* type declartion of function pointer */
typedef  int (*pfunctPtr)(int, int);
 
/*function add two number*/
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}
 
/*function subtract two number*/
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}
 
/*function multiply two number*/
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}
 
//Return function pointer
pfunctPtr ArithMaticOperation(int iChoice)
{
    //function pointer
    pfunctPtr pArithmaticFunction = NULL;
    switch(iChoice)
    {
        case 1:
            pArithmaticFunction = AddTwoNumber;
            break;
        case 2:
            pArithmaticFunction = SubTwoNumber;
            break;
        case 3:
            pArithmaticFunction = MulTwoNumber;
            break;
    }
    return pArithmaticFunction;
}
 
int main(void)
{
    int iData1 = 0;
    int iData2 = 0;
    int iChoice = 0;
    int Result = 0;
    pfunctPtr pArithmaticFunction = NULL; //function pointer
    printf("Enter two Integer Data \n\n");
    scanf("%d%d",&iData1,&iData2);
    printf("Enter 1 for Addition \n\n");
    printf("Enter 2 for Subtraction \n\n");
    printf("Enter 3 for Multiplication \n\n");
    scanf("%d",&iChoice);
    pArithmaticFunction = ArithMaticOperation(iChoice);
    //verify the pointers
    if(pArithmaticFunction != NULL)
    {
        Result = (*pArithmaticFunction) (iData1,iData2);
        printf("Result  = %d\n\n",Result);
    }
    else
    {
        printf("Please enter the valid choice\n");
    }
    return 0;
}

OutPut:

7) Use of array of function pointers

We can create an array of function pointers like another pointer. The array of function pointers offers the facility to access the function using the index of the array.

Let us see an example where we are creating an array of function pointers and initializing it with functions. The signature of the function pointer and function must be the same. In this example, each function takes two integers and returns one integer. So let’s see the code,

我们可以像其他指针一样创建一个函数指针数组。 函数指针数组提供了使用数组索引访问函数的便利。

让我们看一个示例,其中我们将创建一个函数指针数组并使用函数对其进行初始化。 函数指针和函数的签名必须相同。 在此示例中,每个函数采用两个整数并返回一个整数。 因此,让我们看一下代码,

#include <stdio.h>
#include <stdlib.h>
 
//Add two number
int AddTwoNumber(int iData1,int iData2)
{
    return (iData1 + iData2);
}
 
//Subtract two number
int SubTwoNumber(int iData1,int iData2)
{
    return (iData1 - iData2);
}
 
//Multilply two number
int MulTwoNumber(int iData1,int iData2)
{
    return (iData1 * iData2);
}
 
// Main function
int main(int argc, char *argv[])
{
    int iRetValue = 0;
    //Declaration of array of function pointer
    int (*apfArithmatics [3])(int,int) = {AddTwoNumber,SubTwoNumber,MulTwoNumber};
    //Calling the Add function using index of array
    iRetValue = (*apfArithmatics [0])(20,10);
    //display addition of two number
    printf("\n\nAddition of two number = %d\n\n",iRetValue);
    //Calling the subtract function using index of array
    iRetValue = (*apfArithmatics[1])(20,10);
    //display subtraction of two number
    printf("\n\nsubtraction of two number = %d\n\n",iRetValue);
    //Calling the multiply function using index of array
    iRetValue = (*apfArithmatics[2])(20,10);
    //display multiplication  of two number
    printf("\n\nmultiplication of two number = %d\n\n",iRetValue);
    return 0;
}

OutPut:

8) Use of typedef with the function pointer

Using a typedef, we can make the declaration of function pointer easy and readable. The typedef is very helpful when we create an array of the function pointer or a function returns a function pointer. Let us see the example,

使用typedef,我们可以使函数指针的声明易于理解。 当我们创建函数指针的数组或函数返回函数指针时,typedef非常有用。 让我们看一个例子,

//typedef of array of function pointers
typedef int(*apfArithmatics[3])(int,int);

Now, apfArithmatics is a type of array of a function pointer and we can create a variable using this created type. Let us see the example where we have created a variable and initializing it by three functions AddTwoNumber, SubTwoNumber, and MulTwoNumber.

现在,apfArithmatics是函数指针数组的一种类型,我们可以使用此创建的类型创建变量。 让我们看一下创建变量并通过三个函数AddTwoNumber,SubTwoNumber和MulTwoNumber对其进行初始化的示例。

apfArithmatics aArithmaticOperation = { AddTwoNumber,SubTwoNumber,MulTwoNumber };

Some times in the code we need to typecast the address using the function pointer. It also becomes easy using the typedef.

某些时候,我们需要在代码中使用函数指针对地址进行类型转换。 使用typedef也变得容易。

void *pvHandle = NULL;
int (*pf)(int) = (int (*)(int)) pvHandle;

Now using typedef,

现在用typedef,

typedef int(*pf)(int);
pf JumptoApp = (pf)pvHandle;

9) function pointers in the structure

C is not an object-oriented language, so it does not contain the member functions like C++. In short, In C language we can’t create the function in structure the C language. But using the function pointer we can provide these features. These function pointer will treat like the member function and we can also support polymorphism in C.

C不是一种面向对象的语言,因此它不包含C ++之类的成员函数。 简而言之,在C语言中,我们无法在C语言的结构中创建函数。 但是使用函数指针,我们可以提供这些功能。 这些函数指针将像成员函数一样对待,我们也可以在C中支持多态。

struct SERVER_COM
{
    int iLenData;
    void (*pfSend)(const char *pcData,const int ciLen);
    int (*pfRead)(char *pData);
} GATEWAYCOM;

10) Function pointer as a callback function

For windows, in a kernel-mode driver (KMDF), we use a lot of call back functions for the plug and play and device preparation. Each callback function is invoked by the operating system at specific events but we need to register to call back function using the function pointer.

Let’s take an example, suppose there is a callback function MyUsbEvtDevicePrepareHardware. In this callback function, the driver does whatever is necessary to make the hardware ready to use. In the case of a USB device, this involves reading and selecting descriptors.

对于Windows,在内核模式驱动程序(KMDF)中,我们使用许多回调函数进行即插即用和设备准备。 每个回调函数都由操作系统在特定事件下调用,但是我们需要使用函数指针进行注册以回调函数。

让我们举个例子,假设有一个回调函数MyUsbEvtDevicePrepareHardware。 在此回调函数中,驱动程序会执行使硬件准备就绪可以使用的所有必要操作。 对于USB设备,这涉及读取和选择描述符。

// callback function
NTSTATUS
MyUsbEvtDevicePrepareHardware (
    _In_ WDFDEVICE Device,
    _In_ WDFCMRESLIST ResourceList,
    _In_ WDFCMRESLIST ResourceListTranslated
)
{
    //Code as per the requirements
}

Function pointer use to register the above call-back function.

函数指针用于注册上述回调函数。

NTSTATUS (*pfPrepareHardware) (
    _In_ WDFDEVICE Device,
    _In_ WDFCMRESLIST ResourceList,
    _In_ WDFCMRESLIST ResourceListTranslated
);

We know that the name of the function is the beginning address of the function, so we can initialize the function pointer using the function name.

我们知道函数的名称是函数的开始地址,因此我们可以使用函数名称来初始化函数指针。

pfPrepareHardware = MyUsbEvtDevicePrepareHardware;

Now we can use pfPrepareHardware for the registration of MyUsbEvtDevicePrepareHardware.

现在,我们可以使用pfPrepareHardware来注册MyUsbEvtDevicePrepareHardware。

Advantage of function pointers in C:

There are a lot of advantages to the function pointers. Below we have mentioned some advantages of a function pointer. If you know more advantages of the function pointer, you can write in the comment box.

  • A function pointer can point to a function of the same signature and it can invoke the pointed function whenever required in the program. 
  • A function pointer can pass as an argument in function so we can create a generic function that performs the operation as per the user choice. Like the qsort function, it can sort the numbers in increasing or decreasing order.
  • Using the function pointer we can jump from one application to another.
  • A function pointer helps to access the function of the DLL in windows. 
  • A Function pointer provides the run time binding (polymorphism). 
  • Using the function pointer, you can create a state machine in C. 
  • You can replace the nested switch with the array using the function pointer. 

函数指针有很多优点。下面我们提到了函数指针的一些优点。如果您知道函数指针的更多优点,则可以在注释框中编写。

  • 函数指针可以指向具有相同签名的函数,并且可以在程序中需要时调用该指针函数。
  • 函数指针可以作为函数中的参数传递,因此我们可以创建一个通用函数,根据用户的选择执行操作。像qsort函数一样,它可以按递增或递减的顺序对数字进行排序。
  • 使用函数指针,我们可以从一个应用程序跳转到另一个应用程序。
  • 功能指针有助于在Windows中访问DLL的功能。
  • 函数指针提供运行时绑定(多态)。
  • 使用函数指针,您可以在C中创建状态机。
  • 您可以使用函数指针将嵌套switch替换为数组。