Definition:
The called function is called back. The called function is called a callback function.
Use Cases:
The existing quick sorting algorithm implements the logic of the quick sorting algorithm. However, the quick sorting algorithm must involve data size comparison. To improve the universality of the program, the user can provide a comparison function, in this way, the sorting function calls the caller's function to compare the size.
Application Details:
Callback is implemented by using the function pointer in the C language. The callback is implemented by passing the callback function address to the function to be dropped. Therefore, to implement callback, you must first define the function pointer, such:
Void Func (char * s); function prototype
Void (* pFunc) (char *); // function pointer
We can see that the definition of a function is very similar to that of a function pointer. Generally, to simplify the definition of a variable of the function pointer type and improve the readability of the program, we need to customize the function pointer type.
Typedef void (* pcb) (char *) pcb;
Example of the called function:
Void GetCallBack (pcb callBack)
{
/* Do something */
}
When calling the above function, you need to implement a pcb type callback function by yourself:
Void fCallBack (char * s)
{
/* Do something */
}
Then, you can directly pass fCallBack to GetCallBack as a variable,
GetCallBack (fCallBack)
If different values are assigned to this parameter, the caller will call functions of different addresses. Assign values can occur at runtime, so that you can achieve dynamic binding.
(2) parameter transfer rules
So far, we have only discussed function pointers and callbacks, but have not paid attention to the ansi c/C ++ compiler specifications. Many compilers have several call specifications. For example, in Visual C ++, you can add _ cdecl, _ stdcall, or _ pascal before the function type to indicate its call specifications (default value: _ cdecl ). C ++ Builder also supports the _ fastcall call specification. The call specification affects the given function name generated by the compiler, the order in which parameters are passed (from right to left or from left to right), and the responsibility for Stack cleaning (the caller or the caller is called) and parameter transfer mechanism (stack, CPU register, etc ).
It is important to regard the call specification as part of the function type. Incompatible call specifications cannot be used to assign addresses to function pointers. For example:
// The called function uses int as the parameter and int as the return value.
_ Stdcall int callee (int );
// Call a function with the function pointer as the parameter
Void caller (_ cdecl int (* ptr) (int ));
// Illegal operation of the called function address in p's Enterprise Image Storage
_ Cdecl int (* p) (int) = callee; // Error
The pointer p and callee () types are incompatible because they have different call specifications. Therefore, the caller's address cannot be assigned to the pointer p, although the two have the same return value and parameter column.
(3) Application Example
In many parts of the standard library functions in C language, callback functions are used to allow users to customize the processing process. Such as common quick sorting functions and binary search functions.
Quick Sort function prototype:
Void qsort (void * base, size_t nelem, size_t width, int (_ USERENTRY * fcmp) (const void *, const void *));
Binary Search function prototype:
Void * bsearch (const void * key, const void * base, size_t nelem,
Size_t width, int (_ USERENTRY * fcmp) (const void *, const void *));
Fcmp is a callback function variable.
The following is a specific example:
# Include <stdio. h>
# Include <stdlib. h>
Int sort_function (const void * a, const void * B );
Int list [5] = {54, 21, 11, 67, 22 };
Int main (void)
{
Int x;
Qsort (void *) list, 5, sizeof (list [0]), sort_function );
For (x = 0; x <5; x ++)
Printf ("% I \ n", list [x]);
Return 0;
}
Int sort_function (const void * a, const void * B)
{
Return * (int *) a-* (int *) B;
}