【问题标题】:Why a header file is added in the source code where the function is ALREADY defined?为什么在已经定义函数的源代码中添加了一个头文件?
【发布时间】:2019-06-24 11:08:29
【问题描述】:

例如,如果我有以下三个用 C 语言编写的文件:

hello.h

void hello (const char * name);

hello.c

#include "hello.h"
int
main (void)
{
hello ("world");
return 0;
}

hello_fn.c

#include <stdio.h>
#include "hello.h"
void
hello (const char * name)
{
printf ("Hello, %s!\n", name);
}

我知道将#include "hello.h" 行添加到hello.c 告诉编译器hello (const char * name) 的定义将在外部文件(单独编译)期间提供,但是我现在的问题是为什么在 hello_fn.c 包含它自己的定义时将它添加到文件 hello_fn.c hello (const char * name) ,我的意思是它不会从外部提供?

谢谢

【问题讨论】:

  • 如果头文件包含其他信息,比如两个源文件都需要的结构或宏怎么办?它还将确保函数定义与声明匹配。
  • @Someprogrammerdude 在这种情况下,您所说的是 hello_fn.c 中的结构,其他功能 ...etc 需要它,但对于相同的功能 void hello(...).. 不需要?那是正确的...我的意思是我有这种误解,因为我认为我正在阅读的书中的作者只是添加了它而没有任何额外的需要,只是为了那个例子?

标签: c gcc include c-preprocessor header-files


【解决方案1】:

这实际上是一种很好的做法,因为编译器可以根据您的定义(在 hello_fn.c 中)检查您的声明(在标题中)。

否则,就无法确保它们匹配。你可以很容易地说:

void hello (int notCorrect) { ... }

到您的 C 源文件中,它会愉快地独立编译这两个源文件,然后(取决于您在 ... 位中实际执行的操作)在运行时失败。


例如,考虑文件:

hello.c:
    #include <stdio.h>
    #include "hello.h"
    int main(void) { hello(42); }
hello_fn.c:
    #include <stdio.h>
    //#include "hello.h"
    void hello(char *x) { puts(x); }
hello.h:
    int hello(int x);

这编译得很好,因为每个 C 源文件在其声明的内容上是内部一致的。 hello.c/hello.h 对认为 hello 需要一个 inthello_fn.c 认为它需要一个 C 字符串。

运行时我得到一个核心转储(1),因为值42 不是有效的字符串地址。当我取消注释hello_fn.c 中的include 行时,编译器(正确地)抱怨我的声明和定义不一致(因为hello_fn.c/hello.h 对现在不一致)。


最重要的是,标头中可能有 other 内容(尽管在您的示例中不存在),但 only 存在于标头中。这通常是在调用者和被调用者之间共享的声明,例如类型、extern 项目、#define 项目等。在头文件和源文件中单独声明它们没有什么意义。


(1)实际结果可能会有所不同,因为这是未定义的行为。

【讨论】:

  • 是的,我明白了......你的意思是它的添加不会向编译器添加任何进一步的信息,但它会帮助我确保减少可能的拼写错误......编译器将确保为我自动地 ? :D ...谢谢
  • @AbdAllahTalaat:是的 - 标头是将整个程序结合在一起的粘合剂,并提供交叉检查以确保一切正常(或者,至少,错误不是因为不匹配函数的参数或返回类型)。始终在 (a) 定义函数的源文件和 (b) 调用函数的每个源文件中包含(仅)声明函数的标头。总是!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-23
  • 2019-01-12
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多