【问题标题】:Cast from (void**) to (int*) and viceversa从 (void**) 转换为 (int*) 反之亦然
【发布时间】:2020-10-24 10:03:32
【问题描述】:

我做了一个函数 f,它以 (void*) 作为输入,将其转换为 (int*) 并打印值。

#include <stdlib.h>
#include <stdio.h>

void    f(void* p)
{
    int *pi = (int*)p;
    printf("%d\n", *pi);
}

int main()
{
    int x = 1;
    int *px = &x;
    void    *pv = (void*)px;
    f(pv);
    
    return 0;
}

是否可以实现一个功能:

void f2(void** pp);

这样它就可以执行函数 f? 的“相同”操作?我的目标是学习如何将 (int*) 转换为 (void**),反之亦然。


编辑:@tadman 代码的错误和警告(我做错了)

fvv.c: In function ‘f2’:
fvv.c:10:12: warning: initialization of ‘int *’ from incompatible pointer type ‘int **’ [-Wincompatible-pointer-types]
   10 |  int *pi = (int**)p;
      |            ^
fvv.c:12:17: error: invalid type argument of unary ‘*’ (have ‘int’)
   12 |  printf("%d\n", **pi);
      |   

EDIT2

fvv.c: In function ‘main’:
fvv.c:19:5: warning: passing argument 1 of ‘f2’ from incompatible pointer type [-Wincompatible-pointer-types]
   19 |  f2(&px);
      |     ^~~
      |     |
      |     int **
fvv.c:7:16: note: expected ‘void **’ but argument is of type ‘int **’
    7 | void f2(void** p)

【问题讨论】:

  • 你为什么要转换成void**这样奇怪的东西?
  • 你好@tadman 我想学习如何做,因为我需要了解一些其他的库函数......并且因为我喜欢学习一种语言提供的所有可能性。跨度>
  • 您确定要在不同的间接级别之间“转换”吗?例如之间的转换void**int ** 会稍微不那么令人担忧。
  • 这有帮助吗,它实际上不是重复的,但似乎密切相关:stackoverflow.com/questions/58280538/…

标签: c pointers casting void-pointers


【解决方案1】:

你可以采取任何你想要的间接级别,直到公然、完全荒谬的 (void*******),但我不确定这为什么会有用:

void f2(void** p)
{
    // Note you must maintain the same level of indirection
    int **pi = (int**)p;

    // Since this is a ** pointer, it requires ** to fully de-reference
    printf("%d\n", **pi);
}

要调用它,您需要一个指向指针的指针:

int x = 1;
int *px = &x;
f2((void**) &px);

在 C 语言中,指向指针的指针通常被解释为以下两种情况之一:

  • 二维数组
  • 一个可变指针参数

这些都不适用。

话虽如此,在 C 语言中并没有太多关于可以转换和不能转换的规则。如果你想这样做,C 不会妨碍你,即使生成的代码没有意义或在执行时会立即崩溃。

您可以将int* 转换为void** 并再转换回来,C 不会在意,但您应该有一个非常好的理由来做这样的事情。通常任意指针几乎总是被指定为void*,因为它可以被重铸成你想要的任何,这就足够了。

例如,当指针实际上是 int** 时,您可以将 void* 指定为参数,您会经常看到这种情况,例如 thread_create 采用 void* arg 参数。这不仅限于指针,您可以随心所欲。

【讨论】:

  • 非常感谢您的回答@tadman 我编辑了我的答案以报告编译器的输出警告和错误。你能帮我避免警告和错误吗?
  • 您不能将转换为 int** 的内容分配给 int*,类型必须匹配。我在原始答案中打错了字,但不久前已更正。
  • 简单修复,相应编辑。值得注意的是,您打开了所有编译器警告真是太好了。这将帮助您更快地发现问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 2016-03-21
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多