Multi-level pointers, also known as pointers to pointers, refer to a pointer variable whose value is the address of another pointer variable. Function pointers mainly include pointer arrays, pointers to arrays, and pointers to functions. These components are also challenging and error-prone aspects of pointers, which will be explained in detail in this article.
Declaration and Assignment of Multi-level Pointers
In C language, the declaration and assignment of multi-level pointers are similar to pointers, but the declaration of multi-level pointers requires additional <span><span>*</span><span> operator</span></span> symbols. For example, <span><span>int **pp</span></span> represents a double pointer, and <span><span>int ***ppp</span></span> represents a triple pointer, and so on.

For multi-dimensional pointers, the access format is shown below.

As seen in the above image, theoretically, the “&” operator can be used to obtain pointer objects layer by layer, and then the “*” operator can dereference the pointer for data access operations. However, when the number of layers is too many, usage and parsing become inconvenient.
Generally, multi-level pointers are not used beyond three layers; the most common is the use of double pointers, which are pointers to pointers. This section will also explain the commonly used double pointers (pointers to pointers) in detail.
Usage of Double Pointers
Double pointers are more complex than single pointers, but they also have their respective uses. The main uses of double pointers include modifying pointers in function parameters, implementing multi-dimensional arrays, and handling string arrays;
Regarding pointers to pointers, specific examples are shown below.
- Using multi-level pointers for assignment in function parameters.
In function parameters, using pointers to pointers allows for flexible introduction of multiple storage spaces. However, there are two common pitfalls, as follows.
- Do not use local variables for assignment, as local variables will be released after the function execution, leading to errors.
- When assigning addresses stored in pointers, use pointers to pointers; when passing pointers, the internal value is modified, not the address.
- Using multi-level pointers to implement multi-dimensional arrays.

As seen, compared to two-dimensional arrays, using multi-level pointers allows for non-contiguous data rows, providing greater flexibility. However, considering that computers access contiguous addresses more efficiently with CPU cache, it is recommended to prioritize the use of two-dimensional arrays in practical applications.
- Handling String Arrays.

For string arrays, they can be traversed using pointers to pointers, or accessed via array subscripts.
Pointer Arrays
In C language, it supports storing pointers in arrays, where an array object composed of a set of pointer formats is called an array pointer. The format of an array pointer is shown below.
Here, p_array is the pointer array, and its elements are all pointer types, representing an array containing three integer pointers.
Pointer to Array
A pointer to an array is a pointer variable whose value is the address of an array; the specific format is shown below.
A pointer to an array treats the array as an object, allowing for pointer dereferencing. Its address is the same as the array’s starting address, and it can be converted to an array object using * to perform similar array operations. A pointer to an array can be used to access multi-dimensional arrays, as shown in the specific example below.
Function Pointers
Function pointers, also known as pointers to functions, refer to a pointer variable whose value is the address of a function. The usage of function pointers includes the following parts.
<span><span>Type declaration of function pointers is done using the format </span><span>typedef type (*func_ptr)(parameter...)</span><span>.</span></span><span><span>Using type declaration to declare function pointer variables, the above-declared func_ptr can be used as a type declaration pointer, for example, </span><span>func_ptr add_func</span><span>, where add_func is the function pointer variable.</span></span>- Assignment of function pointers can use “=” to assign the function name as the address to the function pointer variable. The format is add_func = add, where add is a function that matches the function pointer type, including return type, number of parameters, and type matching.
- Function pointer invocation allows add_func to be called like a function.
Specific examples are shown below.
For function pointers, a common approach is to combine array pointers to access corresponding functions through a list. Here is a simplified example demonstrating this.
As seen, if id represents the number in protocol parsing and event handling, it can be directly called using the array plus pointer function method, while the code can also uniformly manage supported events and execution functions, which is a common development solution.