You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编程实现任意层级指针解引用?一道面试难题

如何对任意层级的指针进行解引用?

这题确实有点刁钻,我第一次碰到类似的面试题时也愣了半天😅。本质上是要根据输入的层级数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

火山引擎 最新活动