【问题标题】:How to dereference a n-levels void pointer to an int pointer如何将 n 级 void 指针取消引用到 int 指针
【发布时间】:2023-03-18 11:38:01
【问题描述】:

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

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

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

  • 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 的指针int 就像我在代码中所做的那样。

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

提前致谢!

【问题讨论】:

  • 到底是什么让你遇到了这个问题?
  • 是的,指向int 的指针与指向void 的指针大小相同。这是一个很好的古怪问题;我希望上帝这是为了好玩,而您实际上并没有将其用于某事。
  • 更有趣的问题是如何创建指向整数的 n 级指针。
  • 一个厨子糟蹋汤
  • 别担心,这只是为了好玩!实际上,我只是想知道一种方法。

标签: c++ c pointers void-pointers


【解决方案1】:

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

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

IDEONE:demo

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

【讨论】:

    【解决方案2】:

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

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

    因此您可以将 (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);
    }
    

    【讨论】:

      【解决方案3】:

      这假设您的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 中,您可以将static_cast&lt;X&gt;reinterpret_cast&lt;X&gt; 子句替换为(X)

      【讨论】:

        【解决方案4】:

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

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

        会更好。

        【讨论】:

        • 我相信递归调用会更好:foo(*((void**)p), n - 1)
        猜你喜欢
        • 2014-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-25
        • 1970-01-01
        • 2011-06-17
        相关资源
        最近更新 更多