繁体   English   中英

如何取消引用指向int指针的n级void指针

[英]How to dereference a n-levels void pointer to an int pointer

我正在尝试实现以下功能:

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

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

  • n = 0value = (int)(p);
  • n = 1value = *(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;

会更好。

我不确定你想要完成什么,但我怀疑有更好的方法。

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

所以你可以将(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不大于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>子句。

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

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

IDEONE: 演示

它可以让你避免与大theoretiaclly可能的堆栈溢出问题n秒(我不知道为什么你会需要提领1000+层次深的指针,但我不知道为什么你需要摆在首位这一功能,所以让我们保持函数安全)并避免不必要的函数调用开销(是的,它可能会被编译器优化,但为什么不首先以最佳方式编写它?)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM