test.c
:
#include "file.h"
在上面的语句中,将搜索哪些目录?
我想将搜索test.c
所在的目录,对吧?
但这就是全部吗?
BTW,使用头文件有什么好处? Java不需要头文件......答案 0 :(得分:8)
#include <header_name>
:标准包含文件:首先查看标准路径(系统包括编译器的路径设置)#include "header_name"
:首先查看当前路径,然后查看包含路径(项目特定查找路径)使用头文件的好处是为其他人提供库的接口,而无需实现。 Java不需要它,因为java字节码或jar能够描述自己(反射)。 C代码不能(还)这样做。
在Java中,您只需要jar并拥有正确的use语句。在C中,您(大多数时候)需要一个头文件和一个lib文件(或头文件和dll)。
另一个原因是编译c代码的方式。编译器编译转换单元(包含所有包含头的c / cpp文件),第二步中的链接器链接整个内容。不得编译声明,这样可以节省时间并避免为链接器必须清理的每个编译单元生成无用的代码。
这只是一个普遍的想法,我不是编译专家,但应该有所帮助。
答案 1 :(得分:2)
它由您的编译器控制。例如,gcc具有-I
选项以指定包含路径。
C和C ++原型是必需的,因此编译器(与链接器不同)可以确保使用正确的参数调用函数。 Java的不同之处在于编译器使用二进制.class文件(与C不同的是标准字节码格式并保留所有类型信息)来检查调用是否有效。
答案 2 :(得分:0)
在#include
之后使用引号指示预处理器在包含#include语句的文件的同一目录中查找包含文件,然后在包含(#include)该文件的任何文件的目录中查找。然后,预处理器沿/ I编译器选项指定的路径搜索,然后沿INCLUDE环境变量指定的路径搜索。
如果使用尖括号形式,它指示预处理器首先沿/ I编译器选项指定的路径搜索包含文件,然后,从命令行编译时,沿INCLUDE环境变量指定的路径
答案 3 :(得分:0)
strace 或 truss 等可能会有所帮助。例如,使用单行foo.c
创建文件#include "foo.h"
。然后在CYGWIN上,命令:
strace /usr/bin/gcc-4.exe foo.c | grep 'src_path.*foo.h,' | sed 's/.*src_path //;s/foo.h.*//'
产生
foo.c:1:22: error: foo.h: No such file or directory
/home/Joe/src/utilities/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include/
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed/
/usr/include/
/usr/include/w32api/
我真的很惊讶这个名单太短了:上次我做这个练习,十五年前在SunOS 4上,搜索路径有十几个目录。
显然,第一个目录是foo.c所在的位置。有关环境变量CPATH
和C_INCLUDE_PATH
,请参见http://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html。但这些都没有在我的机器上设置。 (无论如何,我不清楚CYGWIN是否使用它们。)
编辑: 最简单的解决方案是使用cpp -v
(不 gcc -v) 。它给出了:
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=i686'
/usr/lib/gcc/i686-pc-cygwin/4.3.4/cc1.exe -E -quiet -v -D__CYGWIN32__ -D__CYGWIN__
-Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../..
/include/w32api -idirafter
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api -
-mtune=generic -march=i686
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/include"
ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/lib/../../include/w32api"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/include-fixed
/usr/include
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../include/w32api
End of search list.
答案 4 :(得分:0)
C ++标准并没有真正说明应该搜索哪些目录。这就是C ++标准描述遇到#include "somefile.h"
时会发生什么的结果:
表单
的预处理指令# include "q-char-sequence" new-line
导致替换它 指令由整个内容组成 由...标识的源文件 指定序列之间的“ 分隔符。命名的源文件是 在一个搜索 实现定义的方式。如果这 搜索不受支持,或者如果 搜索失败,指令是 重新处理就像读了
# include <h-char-sequence> new-line
具有相同的包含序列 (包括&gt;字符,如果有的话)来自 原始指令。
确切地说,搜索哪些目录受到特定C ++实现的支配。