如何编程实现任意层级指针解引用?一道面试难题
如何对任意层级的指针进行解引用?
这题确实有点刁钻,我第一次碰到类似的面试题时也愣了半天😅。本质上是要根据输入的层级数n,对应生成n层的指针类型转换和n次解引用操作,下面分两种场景给你拆解:
场景1:编译期已知n的值
如果n是编译时就能确定的常量,我们可以用宏递归来实现自动展开。C语言的宏支持有限的递归(不同编译器限制不同,比如GCC默认是63层),写法大概是这样:
#include <stdio.h> // 更通用的递归宏写法(GCC支持) #define DEREF_N(n, p) \ __builtin_choose_expr(n == 1, \ *(int *)(p), \ DEREF_N(n-1, *(int **)(p)) \ ) // 测试示例 int main() { int a = 1; int *p1 = &a; int **p2 = &p1; int ***p3 = &p2; printf("n=1: %d\n", DEREF_N(1, p1)); // 输出1 printf("n=2: %d\n", DEREF_N(2, p2)); // 输出1 printf("n=3: %d\n", DEREF_N(3, p3)); // 输出1 return 0; }
这个宏会在编译阶段直接把DEREF_N(n, p)展开成你要的*xN(int*xN)p形式,比如DEREF_N(3, p)会变成***(int***)p。
场景2:运行时才确定n的值
如果n是程序运行时输入的变量(比如用户输入的数字),静态宏就无能为力了,这时候可以用循环迭代的方式逐层解引用:
#include <stdio.h> int deref_n(void *p, int n) { // 先把初始指针转换成void**,方便逐层解引用 void **current_ptr = (void **)p; // 迭代n-1次,每次解引用一层 for (int i = 1; i < n; i++) { current_ptr = (void **)*current_ptr; } // 最后一次解引用得到int值 return *(int *)current_ptr; } // 测试示例 int main() { int a = 1; int *p1 = &a; int **p2 = &p1; int ***p3 = &p2; printf("n=1: %d\n", deref_n(p1, 1)); // 输出1 printf("n=2: %d\n", deref_n(p2, 2)); // 输出1 printf("n=3: %d\n", deref_n(p3, 3)); // 输出1 return 0; }
这个方法的核心是用循环逐层“剥开”指针,每次把当前指针解引用后转换成void**,直到到达第n层,最后取出int值。
重要注意事项
- 不管用哪种方法,必须保证
p的实际类型确实是n层指向int的指针链,否则会触发未定义行为(比如内存访问错误、程序崩溃)。 - 编译期宏的递归层数受限于编译器配置,超过限制会编译失败。
- 运行时循环的方法依赖于平台上所有指针类型的大小相同(大部分现代平台都满足,但不是C标准强制要求的)。
内容的提问来源于stack exchange,提问作者Sato




