【问题标题】:Why does #include "stdio.h" work? [duplicate]为什么#include "stdio.h" 有效? [复制]
【发布时间】:2012-11-20 23:42:50
【问题描述】:

可能重复:
What is the difference between #include <filename> and #include “filename”?

为什么我写以下代码编译器不报错:

#include "stdio.h"

不应该吗

#include <stdio.h>

相反,因为 stdio.h 实际上存储在库文件夹中,而不是在翻译单元的文件夹中?为什么它仍然有效?

【问题讨论】:

  • "..." 在本地查找首先,然后在其他地方查找。
  • 不,应该是#inlcude &lt;cstdio&gt;
  • @111111,这不是问题的重点,是吗?
  • @aleguna 这就是为什么它是一个评论

标签: c++ include


【解决方案1】:

"" 和 &lt;&gt; 之间的区别不大。两者都在实现定义的位置1、2 中搜索标题。不同之处在于,如果对"" 的搜索失败,则搜索就像使用&lt;&gt; 一样进行。 (§16.2)

基本上,这意味着如果&lt;&gt; 找到具有特定名称的标头,"" 不会找不到具有相同名称的标头3。


1 这些实现定义的位置对于两种形式不必相同。

2 不要求其中一个搜索库文件夹,另一个搜索 TU 的文件夹。允许编译器搜索整个文件系统,如果需要,甚至可以在 Google 上搜索。

3 但这并不意味着它们总能找到相同的标头。

【讨论】:

  • 但是有一个要求,如果 #include "xxx" 失败,编译器会重新处理它,就像它是 #include &lt;xxx&gt;。
  • @James 这就是我想要的第三句话的意思。你认为我应该改写它,还是你错过了?
  • +1 用于搜索源文件 :-)
  • 我认为“位置”被如此松散指定的重要原因是标题“文件”不必是实际文件,更不用说在实际文件系统中了。您可以通过某种版本控制或诸如此类的方式编写符合要求的 C++ 实现,只要它能够确定标称“文件”包含哪些字节即可。当然,在实践中,这两个位置都依赖于命令行选项。
  • @SteveJessop,是的,如果能够 include 来自 mercurial 或任何 vcs 的同一文件的不同修订版,那不是很好。.. %) #include "MyClass.h.99fdadcf54"
【解决方案2】:

这是因为包含语法是如何定义的。

#include &lt;cstdio&gt;表示编译器应该包含标准库cstdio

#include "cstdio" 表示编译器应尝试查找文件“cstdio”,主要查看当前目录并使用标准库的位置作为后备。

【讨论】:

  • #include &lt;&gt; 或 #include "" 是否首先查看当前目录或完全由实现定义。
【解决方案3】:

"" 与 &lt;&gt; 仅更改查找顺序。

所以

#include "stdio.h"

预编译器将从翻译单元的目录开始查找,然后移动到预定义的“包含”目录

而

#include <stdio.h>

其他方式

【讨论】:

  • @CharlesBailey 但在实践中,通常认为“...”包含应首先查看包含包含文件的目录。 (另一方面,我认为任何编译器都不会在当前目录中查找包含,除非您将其传递给 -I. 或者它正在读取的文件位于当前目录中。)
  • @CharlesBailey,我在哪里说过 current 目录?
  • @aleguna:抱歉,对于“当前目录”,请阅读“包含正在编译的翻译单元的初始源文件的目录”。我很懒。
  • 无论#include &lt;&gt; 或#include "" 是否查看包含正在编译的翻译单元的初始源文件的目录或包含包含正在解释的包含指令的源文件的目录,要么首先或者完全由实现定义。
  • @CharlesBailey,理论和标准参考都很好。但它实践了所有主流 [预] 编译器的工作方式,正如我所描述的那样。而且我确信问题是关于现实世界的行为,而不是关于标准中的内容
猜你喜欢
  • 2011-04-20
  • 2023-01-02
  • 2010-09-25
  • 2015-04-30
  • 2018-04-12
  • 1970-01-01
  • 2015-05-31
  • 2013-10-05
  • 1970-01-01
相关资源
最近更新 更多