在 C 中,您可以转换 malloc 返回的 void 指针。 C 会为您执行此操作,但您也可以是显式的。
malloc 返回一个 void * 或 void 指针,然后程序员可以将这个返回值转换为其他指针类型。或者程序员可以依靠 C 来进行类型转换。 C 使用强制类型转换的类型转换预计不会改变。
但是,依赖于 C 编译器的 C 代码可能晦涩难懂且难以阅读。
开发程序员可以帮助最终必须阅读代码的维护程序员。
向malloc 的返回值添加显式强制转换有助于那些将拥有
阅读代码并确定作者的意图。这是显式转换 malloc 返回的 void 指针的真正好处。这种编程实践确实
不要误导编译器或使用一些可能会改变的神秘编译器功能。
以下三个示例突出了这种编程实践。在第一个例子中,
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 编译器。