【问题标题】:Generic pointer to pointer指向指针的通用指针
【发布时间】:2016-01-26 23:50:50
【问题描述】:

我知道根据标准void * 是通用指针,而void ** 不是。所以,在我的程序中,我试图转换 void * 而不是直接输入 cast void ** 但我没有得到预期的结果。我想我在这里遗漏了一些非常基本的东西。

   #include <stdio.h>

void check(void **p) 
{
    printf("value:  %d\n", *(int *)*p);
}

int main()
{

    int a[] = {6,2,5,1,8};

    int *p;
    p = a;

    void **val;
    val = (void *)p;

    check(val);


    return 0;
}

我有一个void ** 指针val,它指向int *,但被转换为void *。我将它传递给函数check,它期待void **。在我的printf 中,我首先将*p(即void *)转换为int *,然后取消引用它。我得到一些随机值。我在这里遗漏了什么吗?

【问题讨论】:

  • val = &amp;p; 应该是val = p;
  • 编辑:我之前粘贴了错误的示例。我正在处理两个不同的案例。对此感到抱歉。
  • 嗯你只是void check(void *p) { printf("value: %d\n", *(int *)p); } 没有必要使用void**
  • @BLUEPIXY 因为作者想要一个“void ** 指针val,它指向int *”,val = &amp;p 对他的目的来说是正确的,尽管代码仍然是错误的,因为@不保证 987654344@ 可以与int** 转换。为什么建议用val = p 代替它?通过您的修改,val 不再是指向指针的指针。

标签: c pointers void-pointers


【解决方案1】:

问题在于对printf的调用:

printf("value:  %d\n", *(int *)*p);

main 中,val(即void **)包含int * 的内容。然后将其传递给check,现在称为p。这需要转换为 int * 才能正确读取:

printf("value:  %d\n", *(int *)p);

当然,因为void ** 不是通用指针,所以这样做没有多大意义。最好摆脱无论如何都不会使用的额外间接级别:

void check(void *p) 
{
    printf("value:  %d\n", *(int *)p);
}

int main()
{

    int a[] = {6,2,5,1,8};

    int *p;
    p = a;

    void *val;
    val = p;

    check(val);


    return 0;
}

【讨论】:

  • 我很接近,但我在不应该的地方取消了它的引用。谢谢dbush
  • int** 转换为void** 没有任何意义。
  • @Quentin 在编辑之前的原始问题的上下文中更有意义。我更新了答案以删除对它的引用以避免混淆,并提供了一个更有意义的替代方案。
  • @dbush 感谢您的更正 -- 否决票已反转 :)
【解决方案2】:

val = &amp;p; 更改为val = p;

这可能是一种“错字”,因为您已经正确传递了一次值,后来又取消了它的引用。

编辑:
您可以将:val = (void *)p; 更改为 val = (void *)&amp;p;

【讨论】:

    【解决方案3】:

    正如您自己所说,void** 不是通用指针。它是一个指向void* 类型对象的指针,仅此而已。使用强制转换将其指向 int* 类型的对象是类型双关语。

    在您的情况下,您应该简单地将您的 int* 转换为 void*,然后再次转换回 int*。不涉及void**

    【讨论】:

    • 但是主题启动器想要传递一个指针到指针!他可以通过将int** 转换为void* 来实现。然后,在check 函数中,他应该提取**(int**)p 的值。它之所以有效,是因为任何指针都可以保证在到 void* 的往返过程中幸存下来并返回到原始指针类型。
    • @Ant_222 但里面没有int**。唯一的指针是为check的参数人为创建的。
    • 当你将&amp;p 传递给check() 时,它就是int**
    • @Ant_222 您是否将问题与 user8 的答案混淆了?调用是check(val),其中val 是(转换后的)p
    • 我的意思是当前版本的问题。 check() 函数采用 void**,它是一个指向指针的指针,而程序员使用 int* 调用它,它不是指向指针的指针。如果将val = (void *)p; 替换为val = &amp;p,则可以使代码在某些平台和编译器上运行。 Here 是工作版本。
    猜你喜欢
    • 2016-10-30
    • 2011-08-04
    • 1970-01-01
    • 2018-05-16
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多