包含C中的库是必需的吗?

时间:2017-04-21 17:46:48

标签: c gcc c11

我是学习C,并做一些测试。

  

Ubuntu 16.01

     

gcc --version

     

gcc(GCC)6.3.0   版权所有(C)2016 Free Software Foundation,Inc。   这是免费软件;查看复制条件的来源。没有   保证;甚至不适用于适销性或特定用途的适用性。

test.c

main() {
    printf("Hello Word.\n");
    printf("pow function : %f \n", pow(10,2));
}

我用这个命令编译:

gcc -std=c11  test.c -o test

test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main() {
 ^~~~
test.c: In function ‘main’:
test.c:4:3: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
   printf("Hello Word.\n");
   ^~~~~~
test.c:4:3: warning: incompatible implicit declaration of built-in function ‘printf’
test.c:4:3: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
test.c:5:35: warning: implicit declaration of function ‘pow’ [-Wimplicit-function-declaration]
   printf("powf function : %d \n", pow(10,2));
                                   ^~~
test.c:5:35: warning: incompatible implicit declaration of built-in function ‘pow’
test.c:5:35: note: include ‘<math.h>’ or provide a declaration of ‘pow’

结束:

./test

Hello Word.
pow function : 100.000000

问:我是否需要使用#include <stdio.h>C standard library中的任何一个?

更改档案:

#include <stdio.h>
#include <math.h>

int main() {
    printf("Hello Word.\n");
    printf("powf function : %f \n", pow(10,2));
    return 0;
 }

编译命令(这种情况没有警告):

gcc -std=c11  test.c -o test

执行输出:

./test

Hello Word.
pow function : 100.000000

在这两种情况下,输出都是相同的。

3 个答案:

答案 0 :(得分:4)

是的,如果您正在拨打printfscanf,则#include <stdio.h> 必须。同样,如果您正在调用pow,则必须#include <math.h>

在C90中,允许调用没有可见声明的函数。假设被调用的函数返回int结果(对于printfscanf都是如此,但对于pow则不是)并且其参数与您的参数匹配#39;重新过世。调用可变参数函数,如printfscanf,没有可见的声明,或者声明不包含, ...,未定义行为。这被称为&#34;隐含int规则&#34;。

C99放弃了这条规则。通过使用-std=c11,您要求编译器符合C11标准,该标准也没有隐式int规则。在C99或C11中,调用没有可见声明的函数是约束违规,需要来自编译器的诊断消息。 (诊断并不一定是致命的;您收到的警告符合条件。)

一个小问题:自己提供声明而不是使用标题提供的声明是合法的。没有充分的理由这样做。

此外,将主函数定义为main()是违反约束的。它应该是int main(void)

如果您正在调用数学函数,许多实现还要求您指定要链接到数学库,通常是在编译器命令行末尾指定-lm。其他人会暗中这样做。您可能没有在程序中遇到这种情况,因为编译器能够在编译时计算pow(10,2),因此它不需要数学库。将一个或两个常量更改为变量,编译器将需要生成实际调用。

应该非常认真地对待C编译器警告。在许多情况下,编制者会发布非致命警告,因为我认为这些警告应被视为致命错误。

对于gcc,请考虑使用-std=c11 -pedantic-errors

答案 1 :(得分:2)

我已经开始了,plzz 仔细阅读

在我们的许多程序中,我们使用了库函数printf()&amp; scanf()的即可。

问题。这些原型在哪里?

Ans。除了提供库函数的代码之外,所有标准C实现都提供了一组带有此信息的.h文件。文件stdio.h包含使用I / O库所需的原型和宏。

KeyPoint:

之前我们不需要这个文件,因为如果没有提供原型,编译器会对函数做出假设。有时这些假设是“安全的”,但通常不是。从现在开始,在任何使用I / O库的程序中包含stdio.h都是一个好主意。

答案 2 :(得分:0)

pow函数返回一个double,并且您尝试使用导致问题的%d打印它。有关其他详细信息,请参阅pow的手册页以及format specifiers的手册页。

请修改您的代码,如下所示:

printf("powf function : %f \n", pow(10,2));