在include指令中使用尖括号和引号有什么区别?
#包括<文件名>#包括“文件名”
在include指令中使用尖括号和引号有什么区别?
#包括<文件名>#包括“文件名”
当前回答
感谢您的回答,特别是Adam Stelmaszczyk和piCookie,以及aib。
与许多程序员一样,多年来,我一直使用“myApp.hpp”格式作为应用程序特定文件,使用<libHeader.hpp>格式作为库和编译器系统文件(即/I和INCLUDE环境变量中指定的文件)的非正式约定,认为这是标准。
然而,C标准规定搜索顺序是特定于实现的,这会使可移植性变得复杂。更糟糕的是,我们使用了jam,它可以自动找出包含文件的位置。可以为包含文件使用相对路径或绝对路径。即
#include "../../MyProgDir/SourceDir1/someFile.hpp"
旧版本的MSVS需要双反斜杠(\\),但现在不需要了。我不知道什么时候变了。为了与'nix兼容,只需使用正斜杠(Windows将接受这一点)。
如果您真的担心这个问题,请使用“./myHeader.h”作为源代码所在目录中的包含文件(我当前的大型项目中有一些重复的包含文件名--这确实是一个配置管理问题)。
为了方便起见,这里复制了MSDN说明)。
引用的表单预处理器按以下顺序搜索包含文件:在与包含#include语句的文件相同的目录中。在当前打开的include文件的目录中,按以下相反顺序他们被打开了。搜索从父包含文件的目录开始继续向上通过任何祖父母包含文件的目录。沿着每个/I编译器选项指定的路径。沿着INCLUDE环境变量指定的路径。角钢支架形式预处理器按以下顺序搜索包含文件:沿着每个/I编译器选项指定的路径。在命令行上进行编译时,沿着INCLUDE环境变量指定的路径进行编译。
其他回答
“<filename>”在标准C库位置搜索而“filename”也会在当前目录中搜索。
理想情况下,您可以使用<…>对于标准C库,“…”表示您编写的当前目录中的库。
这里的一些好答案引用了C标准,但忘记了POSIX标准,特别是c99(例如C编译器)命令的特定行为。
根据开放组基础规范第7版,
-I目录更改搜索名称不是绝对路径名的标头的算法,以便在查找通常位置之前先查找由目录路径名命名的目录。因此,名称用双引号(“”)括起来的头应首先在文件的目录中搜索#include行,然后在-I选项中命名的目录中,最后在通常的位置搜索。对于名称用尖括号(“<>”)括起来的标题,只能在-I选项中命名的目录中搜索标题,然后在通常的位置搜索标题。应按照指定的顺序搜索-I选项中命名的目录。实现应在单个c99命令调用中支持至少十个此选项的实例。
因此,在符合POSIX的环境中,使用符合POSIX标准的C编译器,#include“file.h”可能会被搜索/首先是文件.h,其中。是包含#include语句的文件所在的目录,而#include<file.h>可能会首先搜索/usr/include/file.h,其中/usr/include是系统定义的头的常用位置(POSIX似乎没有定义)。
#include <file>
包含默认包含目录所在的文件。
#include "file"
在编译文件的当前目录中包含文件。双引号还可以指定到其他位置的完整文件路径。
带有尖括号的#include将搜索“依赖于实现的位置列表”(这是一种非常复杂的方式来表示“系统头”)以查找要包含的文件。
带引号的#include将只搜索文件(并且,“以依赖于实现的方式”,bleh)。这意味着,在正常的英语中,它将尝试应用你扔给它的路径/文件名,而不会预先设置系统路径或篡改它。
此外,如果#include“”失败,则标准会将其重新读取为#include<>。
gcc文档有一个(特定于编译器的)描述,虽然它是特定于gcc而非标准的,但它比ISO标准的律师式描述更容易理解。
简单的通用规则是使用尖括号来包含编译器附带的头文件。使用双引号包含任何其他头文件。大多数编译器都是这样做的。
1.9-头文件更详细地解释了预处理器指令。如果你是一个新手程序员,那么这个页面应该可以帮助你理解所有这些。我从这里学到了这一点,我一直在工作中遵循这一点。