Why does #include “stdio.h” work?
Possible Duplicate:
What is the difference between #include and #include"filename"?
当我写下面的代码时,编译器为什么不抱怨呢?
不应该是
相反,因为stdio.h实际上存储在库文件夹中,而不是翻译单元的文件夹中?为什么它还能工作?
- "..."首先在本地查找,然后在其他地方查找。
- 不,应该是#inlcude 。
- stackoverflow.com/questions/21593/…
- @这不是问题的关键,是吗?
- @阿勒冈那就是为什么这是一个评论
- @这是有争议的。如果我想要一个C头,那么将其指定为C头似乎是最合理的解决方案。(如果我不关心C,那么应该是,这样我就可以使用一些没有完全损坏的东西。)
- JAMESKANZE,虽然总体上我同意,但在C++中使用EDCOX1的3个理由是有原因的(对于一个EDCOX1,4是线程安全的)。更进一步地说,在这样一个问题上,我非常肯定,OP不知道cstdio是首选。
""和<>的差别不大。两者都在实现定义的位置1、2中搜索头。不同之处在于,如果对""的搜索失败,则搜索的执行方式就像使用<>一样。(16.2)
基本上,这意味着如果<>找到具有特定名称的头,""不会找不到具有相同名称3的头。
1对于这两个表单,这些实现定义的位置不必相同。
2不要求其中一个搜索库文件夹和另一个搜索tu的文件夹。如果需要,编译器可以搜索整个文件系统,甚至谷歌也可以搜索它。
3但这并不意味着他们总是找到相同的标题。
- 不过,有一个要求是,如果#include"xxx"失败,编译器会像处理#include 一样重新处理它。
- @詹姆斯,这就是我想说的第三句话。你认为我应该重新措辞,还是你错过了?
- +1对于谷歌源文件:—)
- 我认为之所以如此松散地指定"places",重要的原因是头"files"不必是实际的文件,更不用说在实际的文件系统中了。你可以在某种版本控制或什么东西上写一个符合标准的C++实现,只要它能计算出标称"文件"包含的字节。当然,在实践中,这两个位置都依赖于命令行选项。
- @史蒂文杰索普,是的,能从Mercurial或任何风投那里对同一个文件进行不同的修订不是很好吗?%)埃多克斯1〔5〕
- @阿列冈:嗯,就个人而言,我会坚持结帐然后编译。我怀疑委员会所想到的更像是一个IDE,它可以编译您的源代码,而不必碰到文件系统。毫无疑问,过去不止一个人用emacs lisp编写了C编译器:—)
- @SteveJessop另一个可能的好方法是在编译器中神奇地实现标准库头,这样它们就不会泄漏任何信息;严格地说,只有标准要求在头中定义的符号才会出现:不包括和获取std::size_。在简单的C++,但是你可以很容易地用神奇的非C++文件头来完成,而这些文件头实际上只是预设的编译器状态的一部分。不幸的是,每个人都采取了简单的方法,并跳过文件系统中的某个C++文件。
- @马丁霍夫南德斯:这确实非常有用,尤其是在编写可移植代码时。我不确定您是否真的需要非书面的C++标准头文件,是否有一个只列出头文件应该定义的符号的pragma,加上一些编译器的魔力来启用"在文件结束之前不要泄漏除此之外的符号"模式?能够检查头以准确地查看其中包含哪些重载、宏和模板定义是很好的。我不一定喜欢仅仅为了阅读标准的标题而学习新语言。
- @史蒂夫,哦,我想这也行。
""和<>只改变查找顺序。
所以用
预编译程序将从翻译单元的目录开始查找,然后移动到预定义的"include"目录。
反之
还有别的路吗
- @但是在实践中,通常认为"…"include应该首先在包含include文件的目录中查找。(另一方面,我认为任何编译器都不会在当前目录中查找include,除非您将其传递给-I.,或者它正在读取的文件在当前目录中。)
- @Charlesbailey,关于当前目录,我在哪里说的?
- @Aleguna:抱歉,对于"当前目录"的"读取"目录,它包含正在编译的翻译单元的初始源文件。我太懒了。
- 无论是#include <>还是#include""查找包含正在编译的翻译单元的初始源文件的目录,还是包含正在解释的include指令的源文件的目录,都是完全定义的实现。
- @查尔斯巴利,理论和参考标准都很好。但它实践了所有主流[预]编译器的工作方式,如我所描述的。我相信问题是关于真实世界的行为,而不是标准中的内容
- 无论"xxx.h"和"xxx.hpp"是指相同的还是不同的文件,都要定义实现。在实践中,通常有既定的实践,我们希望编译器遵循它们。
- @阿列冈:是的,这正是促使我评论的原因。你说"会"没有"一般"这样的资格,所以我评论澄清。
- 在实际操作中,#include"stdio.h"并不总是在tu的目录中第一个查找。它很可能首先在包含像james提到的#include指令的文件目录中查找(我认为这是更常见的)。它确实会影响间接包含的行为方式,如果您的源代码需要在行为不同的实现之间可移植,那么它可能会导致一些混乱。所以查尔斯的评论与现实世界的行为非常相关。不仅仅是一些假设的实现的行为与这个答案所说的不同。
这是因为如何定义include语法。
#include 意味着编译器应该包含标准库cstdio。
#include"cstdio"意味着编译器应该尝试查找文件"cstdio",主要在当前目录中查找,并使用标准库的位置作为回退。
- 无论是#include <>还是#include""首先查看当前目录,还是完全定义了实现。