Was ist der Unterschied zwischen Header-Dateien und Quelldateien in C ++?


Antwort 1:

Leute benutzen Header-Dateien, um Dateien in einem Paket zu organisieren. Sie können leicht erkennen, was ein Paket hat, indem Sie die Header-Dateien lesen, in denen die Deklarationen übersichtlich angeordnet (und im Allgemeinen kommentiert) sind. Sie können sich einen Überblick über die Funktionsweise verschaffen, ohne durch Codezeilen scrollen zu müssen.

In den Quelldateien wird in der Regel der eigentliche Code definiert.

Dies ist ein allgemeines C-Beispiel, daher ist es für die C ++ - Syntax nicht korrekt (ich bin verrostet):

/ * foo.h * /
void func1 (int, int);

(Separate Datei)

/ * foo.c * /
#include "foo.h"
int main () {func1 (3,3); }

void func1 (int x, int y) {
    return x + 2 * y * y;
}

Sie sehen, wie Sie func1 im Hauptmenü von foo.c verwenden konnten, ohne neu definieren zu müssen? Dies ist eine andere Sache über Header-Dateien: Sie können die kleineren Funktionen unter alles setzen (da main das wichtigste ist).

In C ++ haben wir viel mehr Funktionen: Klassen, Namespaces usw. Es schadet immer noch nicht, Dateien ordentlich zu organisieren. Zum Beispiel können wir Klassendeklarationen in einem Header durchführen und dann die Klassenfunktionen im Quellcode definieren.


Antwort 2:

Die einfache Antwort lautet: Header-Dateien beschreiben eine Schnittstelle; Sie enthalten keine Algorithmus-Implementierung. Dafür sind die Quelldateien gedacht.

Das ist aber nur eine sehr oberflächliche Erklärung. Sie können tatsächlich Funktionen in Header-Dateien implementieren. Ich werde es verstehen, aber zuerst, was ist ein praktischer Unterschied zwischen einer "Header-Datei" und einer "Quelldatei"?

Die Antwort lautet: Es gibt keinen anderen Unterschied als den herkömmlichen. Mit der Pre-Processor-Direktive #include können Sie eine beliebige Datei an der Stelle einfügen, an der sie sich befindet. Sie möchten jedoch (mit Ausnahme ganz besonderer Fälle) Ihren allgemeinen Code (die Quelldateien) nicht einbinden. In der Regel müssen Typinformationen und Schnittstellenspezifikationen (Funktionsdeklarationen) eingebunden werden, um sie verwenden zu können.

Wenn Sie Ihren Code einfügen, würde dies in der Tat bedeuten, dass er in allen Dateien multipliziert wird, in denen #include ausgeführt wird. Und das würde höchstwahrscheinlich unerwünschtes Verhalten verursachen.

Kehren Sie nun zur Funktionsimplementierung in den "Header" -Dateien zurück. Sie definieren einen Code in ihnen:

  • Makros. Ein Makro wird an der Stelle seiner Verwendung erweitert. Dies geschieht wiederum durch den Vorprozessor und wiederum durch direktes Umschreiben der Makrodefiniendum-Verwendung durch seine (optional parametrisierten) Definiens. Sie rufen kein Makro auf. Seine Verwendung wird vor dem Kompilieren neu geschrieben. Inline-Funktionen. Diese könnten (und könnten nicht) ähnlich wie die Makros funktionieren. Mit der Ausnahme, dass der Compiler möglicherweise beschließt, eine echte Funktion zu definieren (und ihren Aufruf zu generieren), anstatt den Funktionsinhalt zu inlinieren. Für jedes # include wird eine gemeinsame Funktion generiert (sofern dies nicht implizit inline betrachtet wird, siehe unten). Der Inline-Deklarator ist für den Compiler nicht bindend. es kann inline sein, aber es kann nicht sein, es ist nur ein "Hinweis". Tatsächlich ändert der C ++ 17-Standard die Semantik von Inline in "Mehrfachdefinitionen zulässig". Also sei vorsichtig; Wenn Sie beispielsweise eine Inline-Funktion mit darin enthaltenen statischen Daten erstellen, kann es leicht vorkommen, dass Sie mehrere Instanzen dieser statischen Daten haben (jeweils für eine Definition der Funktion). Wahrscheinlich nicht das, was Sie wollten ... Vorlagencode. Vorlagen werden instanziiert. Wenn Sie eine Vorlage zum Erstellen eines konkreten Typs verwenden, erstellt der Compiler diesen Typ lokal (so, als würden Sie ihn zum Zeitpunkt seiner Verwendung "manuell" definieren). Template-Funktionen werden implizit als Inline-Funktionen betrachtet (aber der Compiler kann und wird oft entscheiden, sie für den generierten Typ nicht inline zu setzen).

Im Allgemeinen definieren Sie Ihre (öffentlichen) Typen und deklarieren Ihre Funktionen in den Header-Dateien. Hier definieren Sie auch Ihre Makros, Vorlagen und Inline-Funktionen. Sie definieren Ihre Funktionen in den Quelldateien und deklarieren / definieren dort auch lokale, nicht öffentliche, Typen und statische Funktionen. Überschriften sind Schlüssel für den Zugriff auf Funktionen, Quellen implementieren die Funktionen.

Quelldateien werden in Objektdateien kompiliert. Dazu gehört der gesamte Code, der aus der Quelle generiert wurde, und der auch den gesamten Code enthält, der in den Header-Dateien definiert ist, die in der Quelldatei enthalten sind. Und schließlich besteht Ihr Programm (oder Ihre Bibliothek) aus diesen miteinander verknüpften Objektdateien.

Hoffe das hilft.


Antwort 3:

Quelldateien sind die Dateien, die den Code enthalten, der kompiliert wird. Die Implementierung Ihres Algorithmus ist in einer Quelldatei enthalten.

Header-Dateien enthalten Code (normalerweise Funktions- oder Klassendefinitionen), der mithilfe der Präprozessor-Direktive #include in Ihre Quelldatei kopiert wird. Der große Vorteil bei der Verwendung von Header-Dateien ist die Wiederverwendbarkeit. Ich meine, stellen Sie sich vor, Sie müssten den Code für die Definition der Zeichenfolgenklasse jedes Mal schreiben, wenn Sie ihn verwenden möchten, wenn ein einfaches #include ausreichen würde.


Antwort 4:

Sie fügen Inhalte in eine Header-Datei ein, die von ANDEREN Quelldateien verwendet wird.

Um pedantisch zu sein, sind Header-Dateien eine Konvention in C und C ++. Einige Compiler kümmern sich möglicherweise nicht einmal darum, ob Sie eine Datei mit der Erweiterung .h kompilieren sollen.

C hat einen primitiven, aber einigermaßen leistungsfähigen und flexiblen Weg eingeschlagen, um einen Vorprozessor zu implementieren. Es behandelt #include und so weiter. Der Compiler sieht die Datei erst, nachdem alle Includes… enthalten sind. Ein Header wird niemals gemäß Konvention kompiliert. Es ist nur enthalten (Beachten Sie, dass es laut CONVENTION Ausnahmen gibt.) Sie fügen also nur Daten in Kopfzeilen ein, die es einer Quelldatei ermöglichen, zu erfahren, welche Informationen aus anderen Quelldateien verfügbar sind, z. B. Funktionen. Oder für gängige Typen. Oder handliche Makros. Oder ... na ja ... es gibt viele Verwendungsmöglichkeiten.