为什么我需要在同名的.c文件中包含.h头文件?

时间:2013-08-25 21:01:58

标签: c

所以我在Head First C中跟随我们,我们正在学习将多个文件组合在一起的章节。其中一个是encrypt.c

#include "encrypt.h"


void encrypt(char *message)
{
  char c;
  while (*message) {
   *message = *message ^ 31;
   message++;
  }
}

encrypt.h文件在结尾处以分号重复第一行,那么为什么需要它呢?我理解为什么我需要头文件来修复在定义之前使用函数的问题,所以我可以理解#include它在使用encrypt.c的文件中,但为什么我需要它encrypt.c ?这只是其中一个“因为”原因吗?

6 个答案:

答案 0 :(得分:17)

如果encrypt.c的内容完整显示,那么您 标题。但是包含它仍然是一个好主意,因为:

  1. 如果文件中的一个函数使用另一个函数,则定义的顺序很重要,因为必须在调用者之前定义被调用者。甚至可以有两个函数A和B,每个函数调用另一个函数,在这种情况下,如果没有至少一个前向声明,你就无法编译代码。包含带前向声明的标题可以解决这些问题。
  2. 与客户端代码一样使用标头是让编译器指出前向声明中的签名与实际函数定义之间的差异的好方法。如果未被发现,这种问题可能会在运行时产生“有趣”的行为并导致大量的毛发拉动。

答案 1 :(得分:6)

您是对的,如果全部encrypt.h声明,则您不需要将其包含在.c文件中。

你主要是为了保持一致。

答案 2 :(得分:4)

想象一下,您将encrypt.c更改为void encrypt(char *message, int i) { }

如果您不包含encrypt.h,您将不会注意到应用程序中的其他文件尚未更新以传递新参数。如果您同时更新encrypt.h和encrypt.c,编译器可以为您进行检查。

答案 3 :(得分:1)

这是很好的风格。 有时,具有函数实现的C文件和具有函数用法的C文件共享公共声明 - 类型/结构,此共享声明放置在H文件中。 对于前。

[enc.h]
typedef enum {S,F} Res;
EN encode();

[enc.c]
#include "enc.h"
Res encode() { ... }

[other.c]
Res res;
res = encode();

答案 4 :(得分:0)

正在对功能进行原型设计

http://en.wikipedia.org/wiki/Function_prototype

答案 5 :(得分:0)

然后将头文件包含在另一个* .c文件中,编译器以这种方式知道其他任何地方都是函数定义。

这就像:

#include <stdio.h>

int main (void)
{
   afun();
   return 0;
}

void afun (void)
{
   printf("hello\n");
}

现在编译器不知道如何处理main函数中的afun()。因为它是定义的。所以它会导致编译错误。

因此,您可以在开头添加声明,或者在第一次使用时添加声明:

#include <stdio.h>

void afun(void);

int main (void)
{
   afun();
   return 0;
}

void afun (void)
{
   printf("hello\n");
}

知道编译器知道afun的deklaration并希望其他任何函数都被定义。使用头文件,可以使用预编译的c代码。编译器唯一需要的是函数的消除。