编译器是否提供printf和scanf这些函数?

4
我最近正在学习C语言。在这本书中提到:“编译器提供了这些库函数:'printf','scanf'…”。
我不理解。这些函数不是在头文件<stdio.h>中定义吗?
为什么这本书解释这些函数由编译器提供?

那是哪本书?顺便问一下,好问题。 - Cacho Santa
@cacho 这是一本由韩国作者编写的编程书籍。C Express. - nujabes
5个回答

6

printfscanf和其他标准库函数都是C语言的一部分,是作为实现的一部分提供的。

C语言实现由多个组件组成。编译器只是其中之一。库是另一个组件;它包含头文件(通常以源代码文件的形式提供,如stdio.h)和一些包含实际实现库函数代码的目标代码文件。

头文件stdio.h声明这些函数;它不定义它们。例如,printf的声明如下:

int printf(const char *format, ...);

printf的定义是实际执行解析格式字符串、访问参数并将格式化输出发送到stdout的代码。这通常(但不一定)以C语言编写,并作为某种可链接目标代码提供。

对于某些C实现,编译器和库由同一组织提供。对于其他实现,它们可能是分别提供的(例如MinGW将gcc编译器与Microsoft的库结合在一起)。


那么,“编译器提供库函数”是错误的说法吗? - nujabes
它们是分开的东西,对吧?我的意思是,“C库函数”,“编译器”。 - nujabes
C语言的完整实现包括编译器和运行时支持。在许多Unix系统上,C运行时库与编译器有些分开,但编译器必须知道如何创建程序(否则它就没有太大用处),并且必须知道将使用哪个库。但是,编译器与您使用它创建的程序或“默认C库”(甚至不是一个程序 - 它只是一个库)非常明显地是完全独立的程序。 - Jonathan Leffler
@JonathanLeffler:编译器不一定需要知道程序将使用哪个库;这取决于链接器。 - Keith Thompson
然后你会涉及到“编译器是什么”的问题 - 是的,你是对的,而且我也是对的(当然是在我看来),但我们使用的是不同的“编译器”定义,这就是为什么我们都对于我们不同的定义而言正确。 - Jonathan Leffler

5

这些函数是由标准库提供的,标准库是编译器作者通常编写的预编译代码集合(但它确实不是编译器本身的一部分)。

需要注意的是,这些函数仅在头文件中被声明。定义位于已经编译的源文件中。


如果函数已在头文件中声明,为什么还需要再从标准库提供这些函数呢?抱歉,我不理解。 - nujabes
4
头文件只包含函数的原型声明,这就足够让你的文件编译了;函数的具体实现通常已经编译为某个静态或动态库。这避免了每次构建程序时都需要重新编译整个标准库的麻烦。 - Matteo Italia
2
@nujabes:因为头文件不包含实现函数的代码。实现对象文件在标准库中;头文件只是声明了这些函数供您使用。 - Jonathan Leffler
@JonathanLeffler 哦,谢谢你,这很有道理! - nujabes
@MatteoItalia 谢谢!那么“编译器提供库函数”这个说法是错误的,对吗?总结: 库函数只是库函数。 编译器只是翻译这些函数。这是真的吗? - nujabes

1
通过说,“编译器提供这些库函数,'printf','scanf'..”,这本书的作者有点草率。
符合标准的C实现在头文件中提供这些函数的声明,在某种库中提供这些函数的实现。编译器只是C编程环境的一个方面。

谢谢!你说的“某种库”,是指标准库吗? - nujabes
1
@nujabes,不同的编程环境提供支持标准库的不同方式。我不想太具体。 - R Sahu

1
编译器不提供这些函数。编译器的目标是将您的高级语言代码翻译成另一种形式,特别是可执行二进制文件。
标准C库包含stdio.h和stdlib.h中的函数。
编译器会将标准库与您的代码链接起来,以便您的代码可以调用这些函数。
对于几乎所有库来说,您都需要告诉编译器您想要链接哪些库。碰巧的是,对于某些编译器,stdio.h和stlib.h的库(libc) 自动链接,无需指定它们。

默认的 C 库通常提供标准 C 库中的所有 C 函数,但是数学函数 <math.h> 可能除外(这取决于平台)。我从未需要使用 <tgmath.h>,我不确定它们是与数学函数一起还是与其他函数一起。当数学库是单独的时,通常使用 -lm 加载,名称为 libm.a 或类似的名称 - 但库名称和扩展名因平台而异。Mac OS X 将数学函数放在主库中。_ [ ...继续... ] _ - Jonathan Leffler
我不太喜欢谈论“stdio和stdlib库”的术语。虽然有头文件<stdio.h>和<stdlib.h>,但只有一个库(或两个库)——C库(也许还有数学库)。 - Jonathan Leffler
@JonathanLeffler:谢谢。我修改了“stdio和stdlib库”的表述,改为“用于stdio.h和stlib.h的库(libc)”。 - stackoverflowuser2010

1

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