【问题标题】:What's the difference between void* and void**?void* 和 void** 有什么区别?
【发布时间】:2010-06-11 22:56:59
【问题描述】:

这个特殊的属性是void*也可以分配一个指向指针的指针,然后强制回滚,接收到原来的值。

我在某处读到了这一行。这是否意味着void*void** 相同? 有什么区别?

编辑

void* 可以保存任何指针。那么void** 需要什么?

【问题讨论】:

  • 当您需要取消引用它并找出它所指向的 void* 是什么时,您需要 void**,或者甚至将 void* 更改为其他东西。您不能取消对 void* 的引用,或者不应该戴上重型护目镜。
  • 好吧,如果你想这样想的话,除了void*之外,还需要什么指针类型?

标签: c++ c pointers


【解决方案1】:

一个点指向一个黑洞。

指向黑洞的东西的其他点。


它们并不是一回事,但指针可以转换为void *。您可以将int * 转换为void *,因为它是一个指针。 void ** 仍然是一个指针(它只是指向一个指针),并且由于它是一个指针,您可以将它转换为 void *。这有意义吗?

也就是说,我认为我从未使用过void **,但如果您需要void *s 的数组,那么类型将是void **。 (在 C 语言中)void * 通常用于保存指向某些用户数据的指针 - 但您不会提前知道该数据的类型。如果你有一个数组,那么void **

由于您也将其标记为 C++:前面的情况并不真正适用:您可以使用 std::vector<void *>。真的,void * 可能有问题 - 抽象基础可能更适合您的目的。 void * 主要在 C 语言中很有用。

【讨论】:

  • 我使用 void ** 作为函数的参数,该函数调用传递给它的函数指针。在这种特殊情况下,指挥棒是可变的。
  • void*s 的数组实际上是void*[n]
  • @FredOverflow:严格来说,是的。当我写这篇文章时,我更多地考虑动态分配的数组,或者一个大小未知的数组。
【解决方案2】:

void** 是指向 void* 的指针。 void* 可以来回转换为任何指针类型(包括 void**)。所以你可以这样做:

char* -> void*
void* -> void**
void** -> void*
void* -> char*

你可以这样做:

char* -> void**
void** -> char*

所以它们不一样。

【讨论】:

    【解决方案3】:

    void * 可以保存任何指针。由于没有实际的 void 对象,void * 始终是指向其他类型的指针。

    void ** 是指向 void 的指针,或者是 void * 的地址,即指向 void 的指针的地址。这是一个实际的类型,没有任何魔法属性。

    但由于void * 可以保存任何指针,它也可以保存例如void **

    void **f(int x) {
       static void *y;
       static int *iy;
       y = &x;
       iy = &x;
       // return &iy; // not ok
       return &y; // ok
    }
    

    【讨论】:

    • 请记住,相反,一个 void** 可以容纳一个 void*,并不能保证。
    • 好点,实际上我想说的是。这就是为什么试图将void * 放入void ** 的返回行被注释掉并带有not ok 注释。
    【解决方案4】:

    如果你想存储一些指针或任何东西,你可能会使用 void*。

    但是,如果你想编写一个能够初始化这个魔术指针的函数,那么你需要将这个参数作为 void** 传递给这个函数

    void   fun1();
    int    fun2(int);
    double fun3(long);
    bool   fun4(int, long, double);
    
    
    int rand(void** pp)
    {
      switch(time()%4)
      {
        case 0: *pp = fun1; return 0;
        case 1: *pp = fun2; return 1;
        case 2: *pp = fun3; return 2;
        case 3: *pp = fun4; return 3;
      }
    }
    
    int main()
    {
        void* pointer;
        int funId;
    
        funId = rand(&pointer);
    
        setCallback(pointer, funId);
    }
    

    【讨论】:

    • 正确的想法,但是您将函数指针与数据指针混淆了——这是非标准的。改为使用这四种不同的结构类型,然后就可以了。
    【解决方案5】:

    一个主要区别是您以粗体引用的规则不适用于 void**。

    【讨论】:

      【解决方案6】:

      void* 是一个指针(或指向未知类型数组开头的指针)。 void* 是指向指针地址的指针(或指向二维数组开头的指针)。

      此外,如果您使用 C(而不是 C++)编写,则没有引用参数,只有值或指针。

      例如

      // By value C and C++
      void MyFunction(int a)
      {
      }
      
      // By pointer C and C++
      void MyFunction(int* a)
      {
      }
      
      // By reference C++ only
      void MyFunction(int& a)
      {
      }
      

      如果你想要一个修改指针地址的函数(例如 void* ptr;)
      并使调用代码受更改影响,
      那么你需要通过引用传递指针传递 ptr 到 (void*&) 并在函数内使用 ptr
      或将指针传递给指针 (void**) 并传递 &ptr 并在函数内部使用 *ptr。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-16
        • 2017-12-05
        • 2012-08-09
        • 1970-01-01
        • 1970-01-01
        • 2018-03-16
        • 2017-05-02
        相关资源
        最近更新 更多