【问题标题】:include library in C is required? [closed]需要在 C 中包含库吗? [关闭]
【发布时间】:2024-04-13 04:40:04
【问题描述】:

我正在学习 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 &lt;stdio.h&gt;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

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

【问题讨论】:

  • 这在多个方面显然不是有效的 C。 “Hello world”是any C书的第一个例子,那么你发现了什么?仅通过反复试验来学习 C 是一个非常糟糕的主意。
  • 警告 (test.c:4:3: warning) 告诉您存在问题,而下一行 (test.c:4:3:note) 会告诉您需要做什么来解决它。下一个块 (test.c:5:35:warning' and test.c:5:35:note`) 为不同的功能重复这些相同的指令。您是否阅读了邮件中的文字?它们不只是为了填满屏幕上的空白空间;他们拥有非常有用的信息,但前提是您实际阅读消息才能获得它。
  • 我对问题进行了更新。

标签: c gcc c11


【解决方案1】:

是的,如果您呼叫printfscanf,那么#include &lt;stdio.h&gt;强制性。同样,如果您要调用pow,则#include &lt;math.h&gt; 是强制性的。

在 C90 中,允许调用没有可见声明的函数。假设被调用函数返回一个int 结果(printfscanf 是这样,但pow 不是这样),并且它的参数与您传递的参数相匹配。调用 variadic 函数,如 printfscanf,没有可见的声明,或使用不包含 , ... 的声明,具有未定义的行为。这被称为“隐式int 规则”。

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

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

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

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

应该非常认真地对待 C 编译器警告。在许多情况下,编译器会针对那些在我看来应该被视为致命错误的事情发出非致命警告。

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

【讨论】:

    【解决方案2】:

    这是我的草稿,请仔细阅读

    在我们的许多程序中,我们使用了库函数 printf() 和 scanf()

    问题。这些问题的原型在哪里?

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

    关键点:

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

    【讨论】:

      【解决方案3】:

      pow 函数返回一个双精度值,而您尝试使用导致问题的%d 打印它。有关详细信息,请参阅 pow 的手册页和 format specifiers

      请修改您的代码如下:

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

      【讨论】:

      • 感谢您的点击,但问题仍然相同。
      最近更新 更多