2010-08-14 13 views
33

Ich verstehe nicht ganz, wie die Dinge in C-Source-und Header-Dateien getrennt werden sollen. Ich sehe oft viele Projekte mit zwei Gruppen von Dateien mit demselben Namen (ohne die Erweiterung, die Quell- und Header-Dateien bezeichnet).Jeder grundlegende Unterschied zwischen Quell- und Header-Dateien in C?

Bisher, von diesem Mangel an Verständnis, wenn ich Bibliotheken geschrieben habe, habe ich alle Klassen-und Klassenmethoden Code in eine Datei, mit Unentschlossenheit in Bezug auf die Wahl der Dateierweiterung.

Was sollte in den Kopfzeilen und was sollte in den Quelldateien sein? Wie implementiere ich diese Trennung?

Antwort

43

Es gibt keinen technischen Unterschied. Der Compiler wird Sie gerne eine .c Datei enthalten, oder kompilieren Sie eine .h Datei direkt, wenn Sie möchten.

Es gibt jedoch einen großen kulturellen Unterschied:

  • Erklärungen (Prototypen) in .h Dateien gehen. Die .h Datei ist die Schnittstelle zu was auch immer in der entsprechenden .c Datei implementiert ist.

  • Definitionen in .c Dateien gehen. Sie implementieren die Schnittstelle in der Datei .h angegeben.

Der Unterschied besteht darin, dass eine .h Datei kann (und in der Regel) #include d in mehrere Übersetzungseinheiten (.c Dateien). Wenn Sie definieren eine Funktion in einer .h Datei, wird es in mehreren .o Dateien enden, und der Linker wird sich über ein mehrfach definiertes Symbol beschweren. Deshalb sollten Definitionen nicht in .h Dateien gehen. (Inline-Funktionen sind die Ausnahme.)

Wenn eine Funktion in einer .c-Datei definiert ist, und Sie wollen es verwenden, um von anderen .c Dateien, eine Erklärung dieser Funktion muss in jedem dieser anderen .c Dateien zur Verfügung steht. Deshalb setzen Sie die Deklaration in eine .h und #include, dass in jedem von ihnen. Sie können auch die Deklaration in jeder .c Datei wiederholen, aber das führt zu einer Menge Code-Duplizierung und einem nicht behebbaren Chaos.

Wenn eine Funktion in einer .c-Datei definiert ist, aber Sie nicht es von anderen .c Dateien verwenden möchten, gibt es keine Notwendigkeit, es im Header zu erklären. Es ist im Wesentlichen ein Implementierungsdetail dieser .c Datei. Nehmen Sie in diesem Fall auch die Funktion static vor, damit es nicht mit identisch benannten Funktionen in anderen Dateien kollidiert.

+0

Leider, obwohl der Standard nichts vorschreibt, hängen die meisten Compiler, die ich verwendet habe, zu einem gewissen Grad von der Dateierweiterung ab. Versuchen Sie Folgendes: Erstellen Sie zwei Dateien, die (sagen wir '' int main() {return 0;} ') namens' header.c' und 'header.h' enthalten und versuchen Sie diese mit gcc zu kompilieren.(Ich bin nicht einmal in der Nähe von VS!) – dirkgently

+0

Ich vermute, dass die meisten Programmierer nicht die Deklarationen von statischen Funktionen in der .h-Datei setzen. Der Hauptunterschied zwischen .h und .c besteht zwischen der Schnittstelle und der Implementierung. – Dipstick

+0

@dirkgently: Okay, aber Ihr Compiler verhält sich nicht wie ein C-Compiler, wenn er nicht die richtige Dateierweiterung bekommt. Der Standard sagt nichts über Programme, die nicht C-Compiler sind :) – Thomas

1

Normalerweise enthalten Header-Dateien Deklarationen, Quelldateien enthalten Code.

Wenn Sie also in der Quelldatei A.c eine in der Quelldatei B.c implementierte Funktion benötigen, fügen Sie einfach B.h ein, um ihre Deklaration zu erhalten.

14

Was sollte in den Kopfzeilen und was sollte in den Quelldateien sein?

Typischerweise enthalten Header eine oder mehrere der folgenden Optionen:

  • Funktionsdeklaration (außer Statik)
  • Variablendeklaration (in der Regel global)
  • Benutzerdefinierte Typdeklaration (lesen struct, union usw. .)
  • Makrodefinition

Quelldateien auf der anderen Seite haben:

  • Funktion/Variablendefinition
  • Statische Funktion Deklaration und Definition (Sie wollen nicht, diese an Ihre Kunden belichten) Einige
  • Variable Definition
  • lieber Inline-Funktionen (C99) in einem Kopf

Wie implementiere ich diese Trennung definieren?

Die eine Definitionsregel ist dein Freund.

Denken Sie daran, wenn Sie eine Bibliothek schreiben, ist dies, was Ihr Kunde zu sehen bekommt. Seien Sie also hilfreich und geben Sie alle Informationen, die Sie für die Verwendung Ihrer Bibliothek benötigen. Die Quelldateien werden normalerweise in binärer Form kompiliert und bereitgestellt.

Und übrigens, C hat nicht das Konzept der Klassen.

+0

'struct' ist nahe genug für mich :) –

+2

Wenn" Die eine Definitionsregel "golden ist, bedeutet" Nicht sagen "Silber. Damit meine ich, dass private Details nicht in Header-Dateien gespeichert werden. Wenn Sie eine Bibliothek von Drittanbietern erstellen, müssen Sie alles, was Sie in die Headerdatei schreiben, in Zukunft unterstützen. Wenn Sie in großen Projekten arbeiten, unterstützt das Minimieren von Header-Dateien das Refactoring, da es die Kompilierungszeit reduziert, wenn Sie tatsächlich die Header-Dateien ändern müssen. (Ich war in einem Projekt, in dem es 12 Stunden dauerte, um neu zu kompilieren, wenn Sie zentrale Headerdateien änderten. 12hoursx # numberofdevelopers = Geld.) – FuleSnabel

1

Es gibt wenig grundlegende Unterschiede zwischen .c und .h Dateien (obwohl einige Compiler weigern, eine rohe .h-Datei zu kompilieren). Der Unterschied ist mehr Konvention.

In der Regel bietet die .h-Datei die API und die .c-Datei die Implementierung.

Daher enthält die .h-Datei nur Dinge, die von anderen Quelldateien benötigt werden, um auf die von Ihrer .c-Datei bereitgestellten Funktionen zuzugreifen. So würden die .h-Dateien die Funktionsprototypen globaler Funktionen, Deklarationen globaler Variablen (wenn sie wirklich benötigt werden) und die Strukturen und andere Typen, die von ihnen verwendet werden, bereitstellen. (Setzen Sie keine Struktur offen, wenn die API nur einen Zeiger auf die Struktur benötigt.)

In-line-Funktionen sind oft auch in .h-Dateien enthalten, aber einige Kodierungsrichtlinien bevorzugen die Verwendung einer separaten Erweiterung (z. B. .inl)

Alle anderen Funktionsimplementierungen, die Definition und Initialisierung von Variablen und Deklarationen lokaler (statischer) Variablen und Funktionen befinden sich in der .c-Datei.

Verwandte Themen