假设我有两个标题和实现文件,A和B.
乙:
#include "B.h"
void funcFromB(); //prototype
...
void funcFromB()
{
...
}
A :
#include "B.h"
void funcFromB(); //prototype
...
funcFromB(); //will this work correctly?
如果函数未在B(B.h)的标题中定义,那么从A调用 funcFromB()是否正常工作?
答案 0 :(得分:2)
是的,如果B.o链接到A,该函数将正常工作.h文件和.c文件之间没有任何内在联系。为清楚起见,他们应该这样做,但没有什么能迫使他们这样做。根本没有.h文件的要求,但是编码员发现它们对于组织信息和避免重复自己很有用。
答案 1 :(得分:1)
您问题中的代码片段都会编译("工作")和smells
答案 2 :(得分:1)
问题显然在灰色区域,但这是我对它的解释和解决方案。
这是您的B.h
void funcFromB();
即。你有头文件中的函数签名。
我不确定你的A.h
文件究竟是什么,但我认为这对我们的讨论并不重要,所以我们将其留待。
现在,您的B.c
文件将包含方法funcFromB()
的实现。在这种情况下,您不必执行
void funcFromB(); //prototype
以上行不是必需的。当您#include
头文件时,方法签名将可用。这就是你的B.c文件的样子。
#include "B.h"
void funcFromB()
{
...
}
现在,为了能够在A.c
中使用此功能,您需要做的只是
#include "B.h"
funcFromB(); //This will work correctly
这里,函数将从B.h获得函数的签名,并且实现将在编译时从B.c获得。您只需要调用该函数即可。
现在,来到我们在这里做了什么。好吧,我们想要做的是以更好的方式组织我们的代码。为此,我们想要使用一个在不同文件中定义的函数,并在另一个文件中使用它。现在,B.c包含函数的定义。 B.h包含方法签名。如果你想在A.c中使用这个函数,你只需告诉这个编译单元,该函数是如何看的。当您在编译期间稍后将文件链接在一起时,编译器将自己找到方法实现。
干杯。
答案 3 :(得分:0)
在你定义funFromB()函数时,它会工作,最好是在B.c文件中;在这种情况下,只需#include包含funcFromB()原型的B.h文件,用于A.c和B.c中的预处理器(这是你将定义函数的文件)文件,你应该好好去。无需在Ac中重新定义函数,也不需要在(任何).c文件中重新声明原型,只要它在bh文件中声明,并且每个使用该函数的.c文件都包含相应的(B) .h文件。
PS:使用标题是提高可读性的好方法,因此我不会通过在.c文件中声明原型来跳过该部分。如果你想避免使用Headers,你仍然可以只使用一个文件,让我们称之为“master.h'”,你将声明ALL .c文件使用的所有原型,并包括所有your.c文件中的master.h。 标题往往有助于更好地概述文件如何链接到另一个文件,并建立正确的依赖关系