为什么要包含stdlib.h?

4

C函数malloc()stdlib.h中定义。

如果我们不包含这个文件,它应该会出现错误,但是这段代码仍然可以正常工作,只是会有一些警告。

我的问题是,如果malloc()可以在没有这个头文件的情况下工作,那么为什么我们需要包含它呢?请帮助我澄清我的概念。

# include <stdio.h>

int main()  
{
    int a, b, *p;
    p = (int*)malloc(sizeof(int)*5);
    for(a=0;a<5;a++)p[a]=a*9;
    for(b=0;b<5;b++)printf("%d ",p[b]); 
}

11
不要对malloc()的返回值进行强制类型转换 - https://dev59.com/dHRB5IYBdhLWcg3wgHWr - gnud
4
@WTP: C++和C99明确规定,如果在main函数结尾处没有明确的return语句,则相当于执行return 0; - Armen Tsirunyan
2
"这段代码运行良好,只有一个小警告" -- 没有这种事情! - Cody Gray
2
编译代码时,你应该真正使用“-Werror”。这样,“小警告”就会变成应该有的错误,从而导致编译失败。 - ThiefMaster
5个回答

12

在C语言中,不幸的是,你不需要对函数进行预声明。如果编译器遇到一个新的函数,它会为其创建一个隐式声明("嗯,这就是它的使用方式,那我就假设参数的类型是什么..")。

不要依赖这个"特性",一般来说也不要写出带有警告的代码。


4
C99不允许隐式函数声明。 - Christoph
隐式声明与参数类型的假设无关,只涉及返回类型。而这是 int。仅有原型与“普通”声明相比有助于处理参数类型。 - Jens Gustedt
@Christoph:虽然从技术上讲是正确的,但一些编译器(特别是GCC)仍然允许隐式函数声明,即使在C99模式下操作,出于兼容性的考虑。 - Adam Rosenfield
1
这是一个罕见的场合,每个人都是正确的。gcc允许这种情况出现是为了向后兼容(“不破坏旧代码”),但你可以通过使用“-std=c99 -pedantic-errors”来强制编译时错误。 - Karoly Horvath

6

请注意警告信息。它指出该内容是无效的。编译器可能会对您过于友好。在Clang中,这可以工作,但在其他编译器中可能不行。

至少将其包含在内以抑制警告。不必要的警告很烦人。任何程序都应该将警告视为错误进行编译(我总是启用此功能)。


我总是以无警告的方式编码。我的问题是为什么它只给出警告而不是错误?我原本期望会出现错误。 - schrodinger
我猜编译器认为:“这段代码只是为了尝试一些东西,我不应该因为这个愚蠢的事情而失败。”编译器知道函数提供的哪些参数,因为编译器制造商已经将其硬编码到编译器中。调用另一个库中的函数可能会导致错误。 - user142019
我认为因为它是一个外部库,所以处理这个问题取决于编译器,而不像语法错误那样。如果你想把警告变成错误,可以使用带有-Werror选项的编译器(最好是gcc -Wall -Werror)。 - pwaring
1
@schrodinger:出于历史原因(即支持旧代码),这可能不是一个错误;您可以使用“-Werror”标志确保无警告编译;还应该增加警告级别,包括至少使用标志“-std=c99 -pedantic -Wall -Wextra”。 - Christoph

3

看起来这是你的编译器的“魔法”。不包含必要的头文件可能在你的编译器上(我猜你用的是微软的)可以工作,但它不一定会在其他地方编译(包括同一编译器的未来版本)。编写符合标准、可移植的代码。


编译器详情: tendua@Rhythm:~$ gcc --version gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 版权所有 (C) 2010 自由软件基金会。 这是自由软件;请查看源代码以了解复制条件。 - schrodinger
@schrodinger:嗯,我只是“猜测”它是由微软开发的。 :) - Armen Tsirunyan
编译器不一定是Microsoft,gcc也可以让你不使用stdlib.h,尽管它会产生一个警告,即使没有指定-Wall。我同意你应该编写可移植的代码,并包括stdlib.h是其中的一部分。 - pwaring

3

stdlib.h是通用标准头文件之一,包括动态内存分配函数和其他标准函数。

例如,如果您想在程序执行结束时显示一条消息,则需要使用getch()函数。此函数从键盘读取一个字符,从而给用户阅读显示的信息的时间。

getch()函数需要包含stdlib头文件。


2

在C语言中,没有原型时不会生成错误的原因是出于历史原因。早期人们经常不打算为函数编写原型,因为指针和整数通常具有相同的大小,并且当传递小于整数的积分类型作为参数时,它们会被提升为整数(而浮点数很少用于系统编程)。

如果他们在任何时候更改了编译器以在未原型化函数时生成错误,则会破坏许多程序并且不会得到广泛接受。

随着64位寻址,我们现在进入了一个整数和指针大小不相同的时期,如果您不为返回指针的函数(如malloc())编写原型,则程序很可能崩溃。

在gcc中,始终为自己的程序设置以下选项:-Werror -Wstrict-prototypes


你也可以只添加 -std=c99 - Jens Gustedt
@Jens:不要忘记加上“-pedantic”。 - Christoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接