如果这是一个初学者的问题,我很抱歉,但在C中工作了一段时间之后,我最后想要确切了解一个函数可用的文件/函数类型。
我知道我们可以使用#include宏明确包含其他文件,如下所示:
#include bar.c
但是同一目录中的文件呢?假设我们有以下文件结构:
src-
|
a.c
b.c
让我们说a.c有函数“foo()”而b.c有“bar()”
即使没有在头文件中明确包含b.c,我也可以在a.c中调用bar()吗?
在子目录中如下所示:
src-
|
a.c
|
someFolder-
|
b.c
我仍然可以访问a.c中的bar()吗?
基本上,函数的范围究竟是如何定义的(不包括在标题中)?
答案 0 :(得分:2)
您将范围与链接混淆。
如果标识符在给定上下文中对编译器可见,则术语范围描述。 C语言已知的最广泛的范围是文件范围,这意味着标识符在预处理之后从声明到翻译单元末尾的点可见。您可以通过声明标识符来显示/知道任何标识符,但是使标识符可见并不意味着引用标识符是指它在另一个文件中引用的内容。
术语链接描述了两个标识符如何引用相同的东西。链接有三个级别:没有链接,每个带名称的标识符指的是不同的东西。使用内部链接,同一翻译单元中的每个标识符指的是同一个东西。使用外部链接, whol程序中的每个标识符都指向相同的内容。对于两个翻译单元中的两个标识符来引用相同的内容,您需要声明它们都具有外部链接。
这与声明的获取方式无关。在公共头文件中编写int foo()
与在两个源文件中写入相同的行没有区别。在任何一种情况下,除非明确声明与foo()
类型说明符具有内部链接,否则所有标识符都引用相同的static
,因为函数具有外部链接。
它也与源代码的布局无关。只要所有翻译单元都链接到同一个二进制文件,您就可以在每个翻译单元中调用所有具有外部链接的函数。
答案 1 :(得分:1)
取决于您是否将这些链接到一个二进制文件中。
如果是链接 - 则是,可以使用隐式声明调用函数。
这种情况下的常见模式是制作包含所有声明的标题文件,包括*.c
文件通常不是首选文件,因为#include
只是文本内容的文本内容
答案 2 :(得分:1)
#include
(预处理程序指令,而不是宏,BTW)具有可搜索的目录列表。
如果使用#include "something.h"
表单(与包含系统标题的尖括号形式相比),则列表中的第一个目录是包含文件的目录。
尽管#include
执行简单的文本包含,因此技术上可以包含任何文本文件,但几乎不会包含c
个文件。
在C中,你通常将c文件分别编译成目标文件并将它们链接在一起,你所做的包括头文件,这些头文件由声明组成,声明表示当前编译单元否则不能使用的其他目标文件的接口。 ;见。
查看http://www.cs.bu.edu/teaching/c/separate-compilation/或其他有关该主题的文章。
答案 3 :(得分:0)
正斜杠“/”应该适用于这种情况。
如果您可以毫无问题地包含foo.h
,这意味着目录(例如,C:\DIRFOO
)是在编译器的“include”指令中预定义的。因此,可以通过bar.h
包含子目录中的另一个文件(例如C:\DIRFOO\DIRBAR
)(例如#include <DIRBAR/bar.h>
)。