如何将n层void指针解引用为int指针

How to dereference a n-levels void pointer to an int pointer

本文关键字:指针 引用 int void      更新时间:2023-10-16

我想实现以下功能:

int foo(const void *p, unsigned int n);

其中p实际上是一个n级指针,指向一个int值,函数必须返回该值。所以:

  • n = 0: value = (int)(p);
  • n = 1: value = *(int*)(p);
  • n = 2: p是指向int值的指针的指针

等等…

所以,我认为下面的实现可能是正确的:

int foo(const void *p, unsigned int n) {
    if (!n) {
        return (int)p;
    }
    return foo((void*)*((int*)p), n - 1);
}

但是,在这段代码中,我假设指针的大小总是等于int型的大小,我知道这不是真的。然而,由于p始终是指向int型指针的指针(n次),我认为也许我可以像在代码中那样将p转换为指向int型指针。

我的想法正确吗?我在网上找不到类似的问题。

提前感谢!

递归的底部情况是不正确的,因为这假设void*int具有相同的宽度。

if (n == 1) return *(int*)p;

这里假设您的int不大于void*:

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }
  return foo(*static_cast<void**>(p), n - 1);
}

除了n=0的情况,我们可以避免这种假设:

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }
  if (n==1) {
    return *static_cast<int*>(p);
  }
  return foo(*static_cast<void**>(p), n - 1);
}

C中,可以用(X)替换static_cast<X>reinterpret_cast<X>子句。

我不知道你想要达到什么目的,但我怀疑有更好的方法。

无论如何,指向某物的指针与指向另物的指针的指针大小相同,等等。

所以你可以将(void*)强制转换为(void**)。

但是将指针强制转换为int类型可能会丢失信息,因为sizeof(void*)可能是> sizeof(int)

你应该写:

int foo(const void *p, unsigned int n) {
    //if n is 0, then p is already an int, but has been casted to a void*
    //This should probably never happend, so you should assert that n > 0
    //if n is 1, then p is actually a pointer to an int
    if (n == 1) return *(int*)p; 
    //else dereference it (by casting it to a (void**) and *then* dereferencing it)
    return foo(*(void**)p, n-1);
}

一般来说,如果可能的话,最好坚持迭代解决方案,而不是递归解决方案。

int foo(void *p, unsigned int n) {
    for (unsigned int i = 0; i < n; ++i) {
        p = *((void**)p);
    }
    return (int)p;
}

IDEONE:演示

它可以让你避免理论上可能的问题堆栈溢出对于大型n s(我不知道为什么你需要解引用1000+级深指针,但我不知道为什么你首先需要这个函数,所以让我们保持函数的安全),并避免不必要的函数调用开销(是的,它可能会被编译器优化,但为什么不首先优化它?)。