In C ist es optional. In C ++ deklariert eine "MUSS" eine Funktion, bevor sie verwendet / definiert wird. Wieso ist es so? Was ist das Bedürfnis? Wir machen das nicht in C # oder Java.
Lustig ist, dass wir eine Funktion definieren. Die Definition selbst hat schon damals eine Deklaration, die wir deklarieren müssen. Gott weiß warum?
Komisch, dass Sie das erwähnen, gerade diese Woche hat Eric Lippert einen Blogpost geschrieben, der sich auf Ihre Frage bezieht:
Grundsätzlich hängt das mit der Funktionsweise des Compilers zusammen. Die C # - und Java-Compiler machen mehrere Durchgänge. Wenn sie auf eine Methode stoßen, die noch nicht bekannt ist, ist das kein Fehler, da die Definition später gefunden werden kann und der Aufruf beim nächsten Durchlauf aufgelöst wird. Beachten Sie, dass meine Erklärung zu einfach ist. Ich schlage vor, Sie lesen Eric Lipperts Beitrag für eine umfassendere Antwort ...
Java und C # spezifizieren sowohl die Sprache als auch das binäre Objektdateiformat und sie sind Multi-Pass-Compiler.
Als Ergebnis sind sie in der Lage, spätere oder separat kompilierte Definitionen zu betrachten.
C funktioniert aus mehreren Gründen nicht so:
Ohne die Verwendung von verwaltetem Code ist es viel schwieriger, ein maschinenunabhängiges Objektformat mit Typinformationen zu definieren
C ermöglicht bewusst die Umgehung der Typ-Mechanismen
Wenn es ursprünglich definiert wurde, gab es im Allgemeinen nicht genug Speicher, um ausgefeilte Compiler auszuführen, und es gab auch keine Prototypen zum Lesen
C-Programme müssen mit systemspezifischen Bibliotheks- und Suchpfadmechanismen beliebig groß sein. All dies hindert ein objektmodulbasiertes Typsystem
Ein Teil der C-Portabilitäts- und Interoperabilitätsbasis ist die "reine Eingabedarstellung" der Spezifikation
Bis vor kurzem war selbst die begrenzte Ein-Pass-Natur von C für große Programme noch kaum praktikabel. Etwas wie Java oder C # wäre nicht in Frage gekommen: Sie könnten Urlaub machen und Ihr make(1)
wäre immer noch nicht fertig.
Im Grunde kommt es darauf an, wie Sie den Compiler für die Sprache schreiben. In C ++ wurde entschieden, eine One-Pass-Kompilierung zu ermöglichen. Dazu müssen Sie (bzw. der Compiler) zuerst die Deklaration aller Klassen, Methoden und dergleichen lesen können und dann die Implementierung (oder in C ++ - Terms, die Definition) lesen. In Java und C # liest der Compiler zuerst den gesamten Code durch und generiert, was dem entspricht, was der C ++ - Compiler beim Lesen der Header-Dateien erzeugt. Der C # / Java-Compiler liest dann die Implementierung (auch Definition genannt). In C ++ wird der Entwickler also aufgefordert, die Deklaration zu schreiben, während in C # der Compiler mehrere Male den Code durchläuft und die Deklarationsarbeit für den Entwickler ausführt.
Nebenbei: In anderen Sprachen wurden Sie gebeten, die Funktionen in der Reihenfolge zu schreiben, in der Sie sie benötigten (wenn Funktion B die Funktion A verwendet, müssen Sie zuerst A definieren). Die meisten dieser Sprachen haben Konstrukte, mit denen Sie das umgehen können. In (Turbo) Pascal war die Lösung in gewisser Weise die gleiche wie in C ++.
C ++ vs. Java / C # - Single-Pass-Compiler (C ++) vs. Multi-Pass-Compiler (Java und C #). Mehrere Durchgänge ermöglichen es Java- und C # -Compilern, zukünftige Typen und Funktionen von Prototypen zu sehen.
C ++ vs. C - Die C-Funktion, die eine Standarddeklaration hat, ist im Grunde genommen ein in C ++ behobener Fehler. Es verursacht Probleme und es ist eine aktivierte Warnung für gcc. In C ++ sind die Argumente Teil der Funktion exportierter Name (name-mangling), daher muss bekannt sein, bevor die richtige Funktion aufgerufen werden kann.
In C ++ muss man "MUSS" eine Funktion deklarieren, bevor sie benutzt / definiert wird. Wieso ist es so? Was ist das Bedürfnis? Wir machen das nicht in C # oder Java.
Ich würde gerne sagen, das ist nicht wahr. Ja, in C ++ müssen Sie eine Funktionssignatur (Prototyp) definieren, bevor Sie darauf verweisen. Aber Sie können die Implementierung für einen späteren Zeitpunkt verlassen.
In Java funktioniert das nicht: Sie können die Methode einer Klasse nicht aufrufen, ohne diese Klasse kompiliert zu haben (Anmerkung: zusammen mit der Implementierung) und in javac classpath verfügbar zu haben. Also ist Java in diesem Sinne strenger.