空指针的目的是什么?

What is the purpose of void pointers?

为什么需要 void 指针,只要可以将任何指针类型转换为任何指针类型,即:

char b = 5; 
int*a = (int*)&b;//both upcasting

int b = 10;
char*a = (char*)b;//and downcasting are allowed

?

此外,为什么在使用 malloc/calloc/realloc 时不需要转换?

void 指针对于创建通用 API 非常有用。您可能会想到 qsort 函数,它可用于对任何类型的数组进行排序。如果 API 不知道指针的 具体 类型,则可以使用 void 指针。

void qsort(
   void *base,
   size_t number,
   size_t width,
   int (__cdecl *compare )(const void *, const void *)
);

关于分配函数,也是一样的。 C 运行时不知道有效对象的类型。但这不是问题,因为用户可以使用通用指针 void.

所以 void 指针被认为是通用指针,对多态性非常有用,这就是为什么 C 语言将转换为 void 可选。

“只要可以转换任何指针类型,为什么还需要 void 指针”。

alloc 函数将不得不使用诸如 char 之类的公分母。但是,如果必须强制转换为我们真正需要的任何内容,那将是令人困惑的。 “空”只是意味着“一堆字节”。

one could cast any pointer type to any pointer type

不完全是。 void * 被定义为将任何 对象指针 1 转换为 void * 并以等效值再次返回。它不需要任何转换。

在不太常见的架构中,一些其他指针的大小和范围可能小于 void *。在其他指针类型之间进行转换可能会丢失必要的信息。

void * 提供通用的 object 指针类型。

void *p = any_object_pointer; // No casts required
any_object_pointer = p;       // No casts required

char * 可以替代 void *,除了与其他对象指针之间的转换需要强制转换。


OP 的 char b = 5; int*a = (int*)&b; 存在未定义行为的风险,因为 int * 的对齐需求可能超过 char *


1 函数指针可能比void*宽。 void *和其他指针是对象指针。 C 缺少真正通用的指针类型。