2013-08-25 129 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