Function pointer usage details

What is a function pointer

When the compiler is compiling, it will allocate a storage space for the functions in the program to store the functions. This storage space is located in the code segment of the memory. Its first address is called the address of the function, and the function name also indicates this address. . Since it is an address, we can define a pointer variable to represent it, and this pointer variable is a function pointer.

How to define pointer variable? Although it also points to an address, the pointer variable pointing to a function is defined differently from the pointer variable pointing to a variable. A function pointer is defined as follows:

int(*pFunc)(int, int);

This statement defines a pointer variable p pointing to the function. The function pointer: defines a pointer variable pFunc, which can point to a function whose return value type is int (the first int) and has two integer parameters. pFunc is of type int(*)(int, int).


To sum up, the function pointer is defined as:

Function return value type (* pointer variable name) (function parameter list);

"Function return value type" means that the pointer variable can point to a function with what type of return value; "function parameter list" means that the pointer variable can point to a function with what parameter list. In this parameter list, only the parameter type of the function needs to be written.

We see that the definition of a function pointer is to change the "function name" in the "function declaration" to "(*pointer variable name)". But what needs to be noted here is: the parentheses at both ends of "(*pointer variable name)" cannot be omitted, and the parentheses change the priority of the operator. If the parentheses are omitted, it is not defining a function pointer but a function declaration, that is, declaring a function whose return type is a pointer.

It should be noted that the function pointer variable does not have ++ and -- operations.

How to call a function with a function pointer

As an example:

int Func(int x);
int (*pFunc)(int x);
pFunc = Func; /*Assign the first address of the Func function to the function pointer*/

The function Func does not take parentheses and does not take parameters when assigning values. Since the function name Func represents the first address of the function, it can be directly assigned, so the pointer variable pFunc points to the first address of the function Func().

Use the following program to further understand the usage of function pointers:

# include <stdio.h>

int Max(int x, int y)
{
    return x > y ? x : y;
}

int main(void)
{
    int(*p)(int, int);  // 定义一个函数指针
    int a, b, c;
    p = Max;  // 把函数Max赋给指针变量p, 使p指向Max函数

    printf("please enter a and b:");
    scanf("%d%d", &a, &b);

    c = (*p)(a, b);  // 通过函数指针调用Max函数, 或c = p(a, b); 

    printf("a = %d\nb = %d\nmax = %d\n", a, b, c);

    return 0;
}

operation result:

please enter a and b:3 4
a = 3
b = 4
max = 4

Two points to note in use:

(1) If a function pointer is used to accept a function without parameters, then its meaning is initialization. At this time, the function pointer should be executed again to obtain the desired result.

(2) Use a function pointer to inherit a function with parameters, which means to inherit its return value, and the return value should also be a function address in theory.

The procedure is as follows:

 The function execution result is:

a = 2
b = 3
 

(3) How to use function pointers as function parameters

This is also a relatively common usage scenario, and the usage method is as follows:

// 定义函数指针
typedef void (*handle_rpc)(const void *recv, void **ret, unsigned short *ret_size);

// 函数声明
void reg_rpc_proc(int type, handle_rpc callback, int log_type);

// 函数定义
void reg_rpc_proc(int type, handle_rpc callback, int log_type)
{
    ....
    g_handle_rpc_msg[type] = callback;  // 传给全局函数指针数组,调用该全局变量时填入函数参数
}

// 调用带有函数指针参数的函数
reg_rpc_proc(MSG_TYPE_DISKFULL, disk_full_proc, RCVMSG_DISK);

// disk_full_proc为函数指针指向函数,函数形式和函数指针一样,定义如下
void disk_full_proc(const void *rcv_msg, void **ret_buf, uint16_t *ret_size)
{
    ....
}

Guess you like

Origin blog.csdn.net/hhhlizhao/article/details/128856314