空指针的目的是什么?
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 缺少真正通用的指针类型。
为什么需要 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 缺少真正通用的指针类型。