struct node{
int w;
int x;
}
struct node *item;
- 请解释这些陈述之间的区别。
我读作不需要 malloc 之后的类型转换。为什么会这样?
1)
item = malloc(sizeof(*item));
2)
item = malloc(sizeof(struct node));
3)
item = (struct node *) malloc(sizeof(struct node));
最佳答案
在功能上,这三个都是等效的。
在风格上,1 是首选选项(至少对我和其他一些 C 程序员而言)。请注意,sizeof
是运算符,而不是函数,只有当操作数是类型名称时才需要括号。因此,您可以编写 sizeof *item
而不是 sizeof (*item)
- 除了可读性之外,parens 不会损害任何其他内容。还要注意 sizeof
不会尝试评估它的参数(它不会尝试取消引用 item
);它所做的只是计算结果类型所需的字节数,并且是在编译时而不是运行时进行的。
就 C 而言,您应该不强制转换 malloc
的结果。从 1989 年的标准开始,它不再是必需的; malloc
返回一个 void *
,可以将其分配给任何其他指针类型,而无需显式转换1。
在 C89 标准下,如果您忘记包含 stdlib.h
或没有声明 ,则转换
。 C89 仍然允许隐式 malloc
的结果可能会抑制有用的诊断范围内的 code>mallocint
声明;如果编译器看到代码中的函数调用没有声明,它会假定该函数返回一个 int
值。如果您停止转换,编译器会提示您试图将整数值分配给指针对象。使用强制转换,编译器会在没有诊断的情况下编译代码,但您会将指针值转换为 int
并再次返回指针,这可能会或可能不会工作。
C99 标准摆脱了隐式 int
声明,所以这不再是问题;不管是否强制转换,如果您忘记包含 stdlib.h
,您将得到一个诊断。出于可读性和可维护性的原因,您仍然应该取消转换;它所做的只是添加无用的视觉困惑。如果您更改目标的声明(从 struct foo *
到 struct bar *
),那么您还必须更新转换,这只是额外的工作,如果您忘记这样做,那就是一个错误。 item = malloc( sizeof *item )
将总是做正确的事情,无需任何进一步维护,无论您对 item
。
C++ 作为与 C 不同的语言,具有不同的规则,不允许允许您在没有显式转换的情况下将 void *
分配给另一个指针类型,因此您 <在这种情况下,em>将 必须转换 malloc
的结果。如果您从 C 迁移到 C++ 并且没有重做所有动态内存管理代码(这是在 C++ 代码中使用 malloc
的唯一借口),这就是一个问题).当然,您不应该在 C++ 中使用malloc
/calloc
/realloc
;使用标准容器之一,或使用 new
运算符。
1 - 在 C89 标准之前,
malloc
、calloc
和 realloc
都返回 char *
,因此,如果目标是不同的指针类型,则需要强制转换。不幸的是,即使不再需要,这个习惯仍然存在
关于c - malloc不同方式的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28751144/