Function pointer digression
A function is a function
A pointer is a pointer
Pointer function is a function
Function pointers are pointers
The essence of function pointer
The essence of function pointer is pointer, the essence of pointer is address, and the object pointed to by function pointer is a function.
The function pointer is generally used as the parameter of the function. The parameter of the function is one of the four elements of the function. The function includes function name, function return value, function parameter and function body. If we write a function that is often called, such as the I2C start signal often used in I2C communication in MCU, we can pass the name of the start signal function we have implemented as a parameter to a function, and the function name can be assigned to a function pointer variable.
How to declare a pointer?
For example, if we declare a pointer variable pointing to an integer, do we want to emphasize that the type of pointer is int and use int *a; You can declare a pointer and know that it is an int pointer.
How to declare a function pointer?
Obviously, there is a difference between a pointer to a function and a pointer to a data type. Similarly, when we declare a function pointer, we need to explain what the return value type of the function pointed to by the pointer is and what the parameter list of the function is. In a word, whether you declare a pointer or a function, you should make it clear what you want to declare. You should tell me who the pointer points to, whether it is an integer variable or a character variable, or whether it points to a function. If the pointer points to a function, it is a function pointer. When you declare it again, you should clarify the characteristics of the function. Here, the characteristics are the return value type of the function and the list of function parameters, Of course, if you declare a function pointer, the name of the pointer is required.
The declaration method of function pointer is:
Function return value type (* pointer variable name) ([formal parameter list]);
double (*pf)(int);
double (pf)(int) must not be used here; Remove the parentheses on pf. Why? Because when it is removed, it becomes another meaning
double (*pf)(int) //pf is the declared function pointer, pointing to a function with a return value of double Function pointers are pointers Is a pointer variable pointing to a function double *pf (int) //pf is the name of the declared function, and the return value of the function is a double pointer. A pointer function is a function whose return value is a pointer
What's the use of function pointers
This writing method is very convenient when calling a function. You only need to assign the function name to a function pointer variable, and then manage these variables with the structure. The operation of batch functions can be realized by passing parameters through the structure.
typedef struct { void (*Init)(void); void (*Disable)(void); void (*SDAOutPut)(uint8_t pdata); void (*SCLOutPut)(uint8_t pdata); void (*SDAInputConfig)(void); void (*SCLInputConfig)(void); void (*SDAOutputConfig)(void); void (*SCLOutputConfig)(void); uint8_t(*ReadSDAInput)(void); uint8_t(*ReadSCLInput)(void); void (*Delay)(void); uint8_t error; }IIC_PIN; void at24InfoInit(void) { AT24.Disable = at24c128_iicDisable; AT24.Init = at24c128_iicInit; AT24.SDAOutPut = at24c128_SDAOutPut; AT24.SCLOutPut = at24c128_SCLOutPut; AT24.SDAOutputConfig = at24c128_SDAOutputConfig; AT24.SCLOutputConfig = at24c128_SCLOutputConfig; AT24.SDAInputConfig = at24c128_SDAInputConfig; AT24.SCLInputConfig = at24c128_SCLInputConfig; AT24.ReadSDAInput = at24c128_ReadSDAInput; AT24.ReadSCLInput = at24c128_ReadSCLInput; AT24.Delay = at24c128_Delay; IIC_Init(&AT24); }
AT24 is a structure. Through the structure reference, the member variables of the structure can be assigned. The assigned functions have unique functions. For example, here they are some operation functions of the memory
static void at24c128_iicInit(void) { printf("This function is used to configure i2c Pin mode\r\n"); } static void at24c128_iicDisable(void) { printf("This function is used to i2c close\r\n"); } static void at24c128_SDAOutPut(uint8_t pdata) { uint8_t bit; pdata ? (bit = 1) : (bit = 0); printf("This function is used to i2c Pull the data cable up or down. Here is%d\r\n",bit); } static void at24c128_SCLOutPut(uint8_t pdata) { uint8_t bit; pdata ? (bit = 1) : (bit = 0); printf("This function is used to i2c Pull the clock line up or down. Here is%d\r\n",bit); } static void at24c128_SDAInputConfig(void) { // gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_7); printf("This function is used to i2c The data line of is set as pull-up input. If open drain has been set, then NOP\r\n"); } static void at24c128_SCLInputConfig(void) { //gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_6); printf("This function is used to i2c The clock line of is set as the pull-up input. If the open drain has been set, then NOP\r\n"); } static void at24c128_SDAOutputConfig(void) { //gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7); printf("This function is used to i2c The data line of is set to push-pull output. If open drain has been set, then NOP\r\n"); } static void at24c128_SCLOutputConfig(void) { //gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); printf("This function is used to i2c The clock line of is set to push-pull output. If open drain has been set NOP\r\n"); } static uint8_t at24c128_ReadSDAInput(void) { /*return gpio_input_bit_get(GPIOB, GPIO_PIN_7) ? 1 : 0;*/ printf("This function is used to i2c Read out the data line level\r\n"); } static uint8_t at24c128_ReadSCLInput(void) { /*return gpio_input_bit_get(GPIOB, GPIO_PIN_6) ? 1 : 0;*/ printf("This function is used to i2c Read out the clock line level\r\n"); } static void at24c128_Delay(void) { // 4.7us for (uint8_t i = 0; i < 15; i++) { //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //__NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } printf("This function generates 4.7us Delay of\r\n"); }