2013-08-25 123 views
8

所以我在Head First C中继续学习,并且我们正在学习将多个文件一起编译的章节。其中之一是encrypt.c为什么我需要在同名的.c文件中包含.h头文件?

#include "encrypt.h" 


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

encrypt.h文件上重复,并在最后一个分号的第一行,所以我为什么需要它?我明白为什么我需要头文件来解决在定义函数之前使用函数的问题,所以我可以理解#include在使用encrypt.c的文件中,但为什么我需要它在encrypt.c之内?这仅仅是那些“因为”原因之一吗?

+0

在定义之前,不能使用函数。您可以声明该函数的标题,然后在定义它之后使用它。但是头文件不会授予您超级用户,因为它允许您使用未声明的函数。 – smac89

+3

在这个特定的例子中不相关,但是头文件通常还定义了'typedef'和'struct'以及在这个头文件中声明的函数可能要使用的所有类型的东西。 –

+0

我也有其他人。这本书有缺点,但都是。 – punstress

回答

16

如果encrypt.c的内容全部显示,那么您不需要需要的标题。但它仍然是一个好主意,包括它的原因是:

  1. 如果文件中的一个函数使用另一个,则定义事项的顺序,因为被叫方必须是调用之前定义。甚至可能有两个函数A和B,每个函数调用另一个函数,在这种情况下,如果没有至少一个前向声明,就不能获得编译代码。包含正向声明的头部解决了这些问题。
  2. 像使用客户端代码一样使用头文件是让编译器指出前向声明中的签名与实际函数定义之间差异的好方法。如果未检测到这种问题,可能会导致运行时出现“有趣”的行为,并导致大量的拉毛。
+1

我喜欢你的第二点。这本书提出了你的第一个相互呼叫的功能点,所以ping把pong和pong叫做ping,并且我明白这个标题将如何解决这个问题,但是我认为,在这里我们只有一个功能,只是为了得到我有这种习惯吗? – punstress

+1

@punstress:本质上是。这是一个很好的习惯。 ;-) – Jon

+0

@Jon从本质上讲,总是将接口与实现分开是一个好习惯,对吧? – NlightNFotis

6

你说得对,如果这全是encrypt.h声明,你不需要将它包含在.c文件中。

你主要是为了一致性。

+0

我以为是这样的,谢谢。 – punstress

4

试想一下,你改变encrypt.c到void encrypt(char *message, int i) { }

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

+0

只是从去年重读这一点,我喜欢你的观点。谢谢。 – punstress

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(); 
0

然后您在一个又一个的* .c文件以这种方式,在其他地方是函数定义编译器知道头。

这IST,如:

#include <stdio.h> 

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

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

现在,编译器不知道如何处理afun()的主要功能做。因为它没有被定义。所以它会导致编译器错误。

所以你在开始或bevore第一次使用添加声明:

#include <stdio.h> 

void afun(void); 

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

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

了解编译器知道afun的deklaration和anythere其他希望函数定义。使用头文件可以使用预编译的c代码。编译器唯一需要的是函数的折衷。

+1

OP说:“我明白了为什么我需要头文件来解决定义之前使用函数的问题”,在她的初始文章中...... –

+0

是的,我会显示: 使用头文件可以使用预编译的c -码。 – Alex44