如何使用空指针(void*)



void实际上不是一个特定的类型。那么系统如何确定内存块的末端从而加密数据块的值呢?当然,如果您知道内存中的数据,您可以将类型从 void 更改为特定类型,但当您不知道时呢?语言设计师提出这个概念的目的是什么?

这主要用于 C 语言,将数据传递给回调函数或构建泛型容器。每当您想要从具体数据类型中抽象时,都会使用它。类型"void *"只能传递指针,有时这就是您所需要的。

但你是对的,如果你想实际访问数据,你必须在某个时候将指针类型转换回具体的数据类型。所以一些代码必须真正记住类型(它必须正确,否则你只会阅读垃圾!但并非所有代码都必须知道类型。有些函数可以将其称为"void *",因此更抽象:例如链表的相同实现可用于包含字符串或矩阵或任何您想要的内容,而无需重新编程每种类型的列表代码。

C++对于回调数据,可以使用继承(接口),对于容器,则可以使用模板来避免潜在的不安全强制转换。

顺便说一句,在 C/C++ 中,在许多情况下,您实际上无法知道"数据块的结束",这对于"void *"指针来说并不特别。这就是为什么有这么多危险的缓冲区溢出。

那么系统如何确定内存块的末端从而加密数据块的值呢?

不能。由您来了解那里的类型,并适当地投射指针以访问它。

但是当你不这样做时呢?

那么你就不能使用void*.

语言设计师提出这个概念的目的是什么?

这是 C 语言的宿醉,它是传递泛型类型的唯一方法。例如,qsort库函数使用它来将指向任意类型的指针传递到用户提供的比较函数;由用户知道真正的类型是什么,并重新投射指针以执行比较。

在C++中,它几乎没有用处 - 有更可靠的方法(包括模板和基于继承的多态性)来支持泛型类型。例如,等效std::sort是一个模板,并始终保留正确的类型。

至于我的经验,我会说它就像一个小丑,它允许您在不知道指针类型的情况下将指针传递给函数。例如,在 C 语言中,链表的"泛型"实现将具有指向数据的 void * 指针,允许添加多种数据类型

它用作占位符。最终,指针将被传递给一个知道实际类型的函数。

一个示例是通用排序函数。它需要一个数组,它可以包含任何类型(所以这是void*),以及一个比较函数。比较函数应适合数组的类型,因此它会在取消引用值之前将void*指针强制转换为正确的type*

这主要是 C 的延续。在C++中,通常为此使用模板。