2013-08-25 4 views
8

Also ich folge in Head First C und wir sind in einem Kapitel, wo wir lernen, mehrere Dateien zusammen zu kompilieren. Einer von ihnen ist encrypt.c.Warum muss ich eine .h-Headerdatei in die gleichnamige .c-Datei einfügen?

#include "encrypt.h" 


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

Die encrypt.h Datei wiederholt die erste Zeile mit einem Semikolon am Ende, also warum brauche ich es? Ich verstehe, warum ich Header-Dateien benötigen würde, um das Problem der Verwendung einer Funktion zu beheben, bevor es definiert ist, so dass ich verstehen konnte # einschließlich es in einer Datei, die encrypt.c verwendet, aber warum sollte ich es innerhalb encrypt.c? Ist das nur einer dieser Gründe?

+0

Sie können eine Funktion nicht verwenden, bevor sie definiert wurde. Sie können die Kopfzeile für die Funktion deklarieren und sie dann verwenden, nachdem sie definiert wurde. Aber eine Headerdatei gewährt Ihnen keinen Superuser, da Sie damit eine nicht deklarierte Funktion verwenden können. – smac89

+3

Nicht relevant in diesem speziellen Beispiel, aber Header-Dateien definieren auch oft 'typedef's und' struct's und alle Arten von Dingen, die die in diesem Header deklarierten Funktionen verwenden möchten. –

+0

Ich habe auch einige andere. Dieses Buch hat Fehler, aber sie alle tun es. – punstress

Antwort

16

Wenn der Inhalt von encrypt.c in ihrer Gesamtheit angezeigt wird, dann brauchen Sie nicht die Header. Aber es ist immer noch eine gute Idee, es zu schließen, weil:

  1. Wenn eine Funktion in der Datei ein anderes verwendet, dann ist die Reihenfolge der Definition ist wichtig, weil die Angerufene vor dem Anrufer festgelegt werden muss. Es ist sogar möglich, zwei Funktionen A und B zu verwenden, von denen jede die andere aufruft. In diesem Fall kann der Code nicht ohne mindestens eine Vorwärtsdeklaration kompiliert werden. Das Einbeziehen des Headers mit den Vorwärtsdeklarationen löst diese Probleme.
  2. Die Verwendung des Headers, genau wie Ihr Client-Code, ist eine gute Möglichkeit, den Compiler auf Diskrepanzen zwischen den Signaturen in den Forward-Deklarationen und den tatsächlichen Funktionsdefinitionen hinweisen zu lassen. Unerkannt kann diese Art von Problem zu "interessantem" Verhalten zur Laufzeit und zu viel Haarziehen führen.
+1

Ich mag deinen zweiten Punkt. Das Buch brachte deinen ersten Punkt von Funktionen hervor, die sich gegenseitig aufrufen, also ruft ping pong und pong ping an, und ich verstehe, wie der Header das lösen würde, aber ich dachte, hier haben wir nur eine Funktion, nur um zu bekommen ich in der Gewohnheit? – punstress

+1

@punstress: Im Wesentlichen ist es. Und es ist eine gute Angewohnheit, hineinzugehen. ;-) – Jon

+0

@Jon Im Wesentlichen ist es eine gute Übung, die Schnittstelle immer von der Implementierung zu trennen, oder? – NlightNFotis

6

Sie haben recht, wenn das alles encrypt.h erklärt, müssen Sie es nicht in der .c Datei enthalten.

Sie tun es meistens für Konsistenz.

+0

Ich dachte, es wäre so etwas, danke. – punstress

4

Stellen Sie sich vor, dass Sie encrypt.c zu void encrypt(char *message, int i) { }

ändern, wenn Sie nicht enthalten encrypt.h Sie nicht, dass die anderen bemerken Dateien in Ihrer Anwendung wurden nicht aktualisiert, um den neuen Parameter zu übergeben. Wenn Sie gleichzeitig encrypt.h und encrypt.c aktualisieren, kann der Compiler nach Ihnen suchen.

+0

Ich habe es gerade vom letzten Jahr gelesen, und ich mag deinen Punkt. Danke. – punstress

1

Es ist guter Stil. Manchmal teilt C-Datei mit Funktionsimplementierung und C-Datei mit Funktionsverwendung gemeinsame Deklarationen - Typen/Strukturen. Dies teilt Deklarationsstellen in der H-Datei. Für z.

0

Dann fügen Sie den Header in eine andere * .c-Datei ein, die der Compiler auf diese Weise kennt, die sonst nirgendwo die Funktionsdefinition ist.

Das ist wie:

#include <stdio.h> 

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

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

Jetzt ist der Compiler nicht weiß, was mit afun() in der Hauptfunktion zu tun. Weil es nicht definiert wurde. Es wird also zu einem Compilerfehler führen.

So fügen Sie die Erklärung am Anfang oder bevore der ersten Nutzung:

#include <stdio.h> 

void afun(void); 

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

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

Kennen der Compiler die Deklaration von afun kennt und hofft anythere sonst die Funktion definiert ist. Mit Header-Dateien ist es möglich, vorkompilierten C-Code zu verwenden. Das einzige, was der Compiler benötigt, ist die Deklaration der Funktion.

+1

Das OP sagte "Ich verstehe, warum ich Header-Dateien benötigen würde, um das Problem der Verwendung einer Funktion zu beheben, bevor es definiert ist" in ihrem ursprünglichen Beitrag ... –

+0

Ja würde ich zeigen: Mit Header-Dateien ist es möglich, vorkompilierte c -Code. – Alex44

Verwandte Themen