为什么要对void指针进行类型转换?

30

作为一个C语言新手,我对于void指针仅有的实用性是它可以在给定的指针中存储不同的数据类型,因此在进行内存分配时我没有将指针进行强制类型转换。

我看到一些代码示例有时会使用void指针,但它们会被强制类型转换。这有什么用处呢?为什么不直接创建所需类型的指针而非void指针呢?


6
可以举个例子吗? - Oliver Charlesworth
7
你不需要使用 void* 强制转换,因为语言已经定义了从 void* 自动转换到任何其他指针类型的规则,但并不是所有程序员都知道这一点(甚至包括遗憾的是并非所有的 C 书籍作者)。 - Fred Foo
1
更准确地说,C标准定义了void *和所有数据指针类型之间的隐式兼容性。函数指针不在游戏中(但是,如果您的系统是POSIX,并且为什么会有任何理智的程序员使用任何非POSIX系统,则函数指针也与void *兼容)。 - user529758
1
这可能与此处相关:https://dev59.com/dHRB5IYBdhLWcg3wgHWr - milleniumbug
9
应该使用“code”,而不是“codes”来描述编程中的代码。 - user405725
显示剩余2条评论
2个回答

22
在C语言中,将void指针强制转换为其他类型存在两个原因。
  1. 如果您想访问指针指向的内容(例如:*(int*)p = 42
  2. 如果您实际上是在使用C和C++的共同部分编写代码,而不是“真正”的C。另请参见Do I cast the result of malloc?
原因1很明显。第二个原因是因为C++不允许从void指针隐式转换为其他类型,而C允许这样做。

2
但是第二个参数无效:不应该使用C++编译器编译C代码。 - user529758
6
@H2Co3:没错,但有时候你会在宏定义或内联函数中的头文件中定义代码,这些代码旨在在包含那些头文件的 C 和 C++ 代码中使用。 - Adam Rosenfield
2
@H2CO3 然而,有些人确实这样做。我试图解释这种现象,而不是为其辩护。 - wolfgang
1
第三个原因:你被一个愚蠢的编码指南所迫。s/隐式转换/隐式转换/ - undur_gongor
1
第三个原因:告诉查看您代码的人,该内存区域是哪种类型,因为 a->b = malloc(sizeof(*a->b)) 没有提供任何信息,而 a->b = (struct Monster*)malloc(sizeof(*a->b)) 则提供了明确的信息。 - xryl669
显示剩余2条评论

16

如果你想引用void指针的值,你需要将其转换为其他类型,例如,当你作为函数参数获取一个void指针并确定它是一个整数时:

void some_function(void * some_param) {
    int some_value = *some_param; /* won't work, you can't dereference a void pointer */
}

void some_function(void * some_param) {
    int some_value = *((int *) some_param); /* ok */
}

4
不需要使用这种写法,更易读的方法是int *tmp = param; int val = *tmp; - user529758
@H2CO3,你必须判断指针是否为void类型。就像Guillaume的例子中一样。 - user1944441
3
@Armin 你不一定要这样做,我再说一遍——如果你将指针分配给一个临时变量,就可以避免使用 cast。 - user529758
@H2CO3 但是如果你不使用临时变量,就必须这样做,就像他的例子中所示。 - user1944441
1
@Armin 是的,但这不是我要说的 - 我更倾向于认为这并非全球必然。 - user529758

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接