The Magical Use of Function Pointers and Arrays of Function Pointers

 

The author encountered such a problem in the process of developing a software. The previous module passed me binary data. The input parameters were char* buffer and int length. The buffer is the first address of the data, and the length represents the length of this batch of data. The characteristics of the data are: the length is indeterminate, the type is indeterminate, the type of the data is identified by the first byte (buffer[0]), and there are 256 (28) possibilities in total. My task is to have to deal with every possible data type, and my module contains several functions, and in each function, I have to do similar processing. In the usual way, the following code would be written:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];

    switch( nStreamType )
    {
       case 0:
           function1();
           break;
       case 1:
       ... ...
       case 255:
           function255();
           break;
     }
}

 If I write in this way, I have to make so many judgments in each of my functions, the code written must be very long, and every time I process, I have to make many judgments before I can find the correct process. function, the execution efficiency of the code is not high. In response to the above problem, I thought of using the method of function pointer array to solve this problem.

  The concept of function pointers was mentioned in the classic tutorial of Mr. Tan Haoqiang's C language programming. In most cases, we can't use it and ignore its existence. The function name is actually a pointer, pointing to the entry address of the function, but it is different from ordinary pointers such as int* and double*. See the following example to understand the concept of function pointers:
int funtion( int x, int y ) ;
void main ( void ) 
{
    int (*fun) ( int x, int y );
    int a = 10, b = 20;
    function( a, b );
    fun = function;
    (*fun)( a, b );
     ...
}
  Statement 1 defines a function function, whose input is two integer numbers, and the return is also an integer number (input parameters and return values ​​can be any other data types); Statement 3 defines a function pointer, and The difference between int* or double* defining pointers is that the definition of function pointers must also point out the input parameters, indicating that this is a function pointer, and *fun must also be enclosed in a pair of parentheses; statement 6 assigns the function pointer to funtion, provided that The condition is that the input parameters and return values ​​of *fun and function must be consistent. Statement 5 directly calls the function function(), statement 7 calls the function pointer, and the two are equivalent.

  Of course, the advantages of function pointers cannot be seen from the above examples, the main purpose is to introduce the concept of function pointer arrays. We can know from the above example that since the function name can be saved through the function pointer, it must be possible to define an array to save several function names, which is the function pointer array. The prerequisite for using the array of function pointers correctly is that the functions that need to be saved through the array of function pointers must have the same input and output values. 

 In this way, the problem I am facing at work can be solved as follows:

First define 256 handler functions (and their implementations).

void funtion0( void );
……..
void funtion255(void );

Second, define an array of function pointers and assign values ​​to the array.
void (*fun[256])(void);

fun[0] = function0;
.......
fun[255] = function();
Finally, the MyFunction() function can be modified as follows:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];
    (*fun[nStreamType])();
}

  As long as 2 lines of code are needed, 256 case statements are completed, reducing the workload when writing code, using nStreamType as an array Subscripting, calling the function pointer directly, is also higher than the case statement in terms of code execution efficiency. If such processing is required in multiple functions, the array of function pointers can better reflect its advantages.

Reprinted: https://blog.csdn.net/u010925447/article/details/74295692
The author encountered such a problem in the process of developing a software. The previous module passed me binary data. The input parameters were char* buffer and int length. The buffer is the first address of the data, and the length represents the length of this batch of data. The characteristics of the data are: the length is indeterminate, the type is indeterminate, the type of the data is identified by the first byte (buffer[0]), and there are 256 (28) possibilities in total. My task is to have to deal with every possible data type, and my module contains several functions, and in each function, I have to do similar processing. In the usual way, the following code would be written:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];

    switch( nStreamType )
    {
       case 0:
           function1();
           break;
       case 1:
       ... ...
       case 255:
           function255();
           break;
     }
}

 If I write in this way, I have to make so many judgments in each of my functions, the code written must be very long, and every time I process, I have to make many judgments before I can find the correct process. function, the execution efficiency of the code is not high. In response to the above problem, I thought of using the method of function pointer array to solve this problem.

  The concept of function pointers was mentioned in the classic tutorial of Mr. Tan Haoqiang's C language programming. In most cases, we can't use it and ignore its existence. The function name is actually a pointer, pointing to the entry address of the function, but it is different from ordinary pointers such as int* and double*. See the following example to understand the concept of function pointers:
int funtion( int x, int y ) ;
void main ( void ) 
{
    int (*fun) ( int x, int y );
    int a = 10, b = 20;
    function( a, b );
    fun = function;
    (*fun)( a, b );
     ...
}
  Statement 1 defines a function function, whose input is two integer numbers, and the return is also an integer number (input parameters and return values ​​can be any other data types); Statement 3 defines a function pointer, and The difference between int* or double* defining pointers is that the definition of function pointers must also point out the input parameters, indicating that this is a function pointer, and *fun must also be enclosed in a pair of parentheses; statement 6 assigns the function pointer to funtion, provided that The condition is that the input parameters and return values ​​of *fun and function must be consistent. Statement 5 directly calls the function function(), statement 7 calls the function pointer, and the two are equivalent.

  Of course, the advantages of function pointers cannot be seen from the above examples, the main purpose is to introduce the concept of function pointer arrays. We can know from the above example that since the function name can be saved through the function pointer, it must be possible to define an array to save several function names, which is the function pointer array. The prerequisite for using the array of function pointers correctly is that the functions that need to be saved through the array of function pointers must have the same input and output values. 

 In this way, the problem I am facing at work can be solved as follows:

First define 256 handler functions (and their implementations).

void funtion0( void );
……..
void funtion255(void );

Second, define an array of function pointers and assign values ​​to the array.
void (*fun[256])(void);

fun[0] = function0;
.......
fun[255] = function();
Finally, the MyFunction() function can be modified as follows:

void MyFuntion( char* buffer, int length )
{
    __int8 nStreamType = buffer[0];
    (*fun[nStreamType])();
}

  As long as 2 lines of code are needed, 256 case statements are completed, reducing the workload when writing code, using nStreamType as an array Subscripting, calling the function pointer directly, is also higher than the case statement in terms of code execution efficiency. If such processing is required in multiple functions, the array of function pointers can better reflect its advantages.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324936913&siteId=291194637