在 C 中,您可以强制转换由malloc
. C 为您执行此操作,但您也可以是明确的。
malloc
返回一个void *
或 void 指针,然后程序员可以将此返回值转换为其他指针类型。或者程序员可以依靠 C 来进行类型转换。C 使用强制类型转换的类型转换预计不会改变。
但是,依赖于 C 编译器的 C 代码可能晦涩难懂且难以阅读。开发程序员可以帮助最终必须阅读代码的维护程序员。
为返回的值添加显式转换malloc
有助于必须阅读代码并确定作者意图的人。这是显式转换返回的 void 指针的真正好处malloc
。这种编程实践不会误导编译器或使用一些可能会改变的神秘编译器功能。
以下三个示例突出了这种编程实践。在第一个示例中,
malloc
(在 中定义<stdlib.h>
)被显式转换并执行了一些琐碎的工作。
#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
在第二个示例中,唯一的区别是<stdlib.h>
注释掉了。代码仍然运行并产生相同的结果。现在,为什么这个工作的“为什么”是相当直接的。当 C 没有找到函数的原型时,它假定该函数返回一个int
,但malloc
返回一个 void 指针。在这种情况下,显式转换已告诉 C 编译器以及源的碳单元,malloc
应将返回的值转换为字符指针。
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
最后一个(是的)示例不发出演员表,也不包括<stdlib.h>
. Eclipse 编辑器和编译器都抱怨这个代码(他们应该这样做)。编译器消息是
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
源代码是:
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// compiler displays a "warning" and prints abc at the console
}
将示例 3 更改为包含不会导致任何警告,并且程序会按预期运行。但是,示例 2 和示例 3 都缺少显式转换,并且在以这种样式编写的代码的整个生命周期中,与显式使用支持的转换相比,这样的代码将更昂贵并且更容易被人错误更改(因此产生额外费用) C 编译器。