在这个问题上,有人在评论中建议我不要使用malloc的结果。即,我应该这样做:
int *sieve = malloc(sizeof(*sieve) * length);
而不是:
int *sieve = (int *) malloc(sizeof(*sieve) * length);
为什么会这样?
在这个问题上,有人在评论中建议我不要使用malloc的结果。即,我应该这样做:
int *sieve = malloc(sizeof(*sieve) * length);
而不是:
int *sieve = (int *) malloc(sizeof(*sieve) * length);
为什么会这样?
当前回答
void指针是泛型指针,C支持从void指针类型到其他类型的隐式转换,因此不需要显式类型转换。
然而,如果您希望相同的代码在不支持隐式转换的C++平台上完美兼容,则需要进行类型转换,因此这一切都取决于可用性。
其他回答
这取决于编程语言和编译器。如果在C中使用malloc,则无需键入cast,因为它会自动键入cast。然而,如果您使用的是C++,那么应该键入cast,因为malloc将返回void*类型。
在C语言中,可以将空指针分配给任何指针,这就是为什么不应该使用类型转换的原因。如果您想要“类型安全”分配,我可以推荐以下宏函数,这些函数我总是在C项目中使用:
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)
有了这些,你可以简单地说
NEW_ARRAY(sieve, length);
对于非动态数组,第三个必须的函数宏是
#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
这使得阵列环路更加安全和方便:
int i, a[100];
for (i = 0; i < LEN(a); i++) {
...
}
在C语言中,您得到了从void*到任何其他(数据)指针的隐式转换。
返回的类型为void*,可以将其转换为所需类型的数据指针,以便可以取消引用。
这就是GNU C库参考手册所说的:
您可以将malloc的结果存储到任何指针变量中强制转换,因为ISO C会自动将类型void*转换为另一个必要时的指针类型。但演员阵容在上下文中是必要的而不是赋值运算符,或者如果您可能希望代码运行在传统C。
事实上,ISO C11标准(第47页)是这么说的:
如果分配成功,则返回的指针将适当对齐它可以分配给指向任何类型对象的指针基本对齐要求,然后用于访问这样的对象或此类对象的数组(直到空间被显式释放)