Einführung in Deklarationen in C++ im Rahmen der Lehre des Programmierens mit der Programmiersprache C++ [] (C++ Deklaration C++ Deklarationen C++ Funktionsdeklaration C++ Funktionsdeklarationen C++ Definition Unterschied), Lektion, Seite 721230
http://www.purl.org/stefan_ram/pub/c++_deklaration_de (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Deklarationen in C++

Alle bisher vorgestellten Definitionen sind auch Deklarationen. Eine Deklaration legt den Typ  eines Bezeichners fest. Eine Definition legt darüber hinaus auch fest, an welche Entität  ein Bezeichner gebunden ist. Es gibt aber auch Deklarationen, die keine  Definitionen sind. Diese geben nur den Typ  eines Bezeichners an, ohne  dem Bezeichner eine Entität zuzuordnen. Bei einer Funktionsdeklaration sagt man auch, solch eine Deklaration lege den Prototyp  einer Funktion fest, um zu sagen, daß der Leser nun ihren Typ kenne. Zusammen mit der Angabe der nötigen Kopfdirektive bildet eine Deklaration auch die Synopsis.

Mindestens der Typ  eines Bezeichners muß bei Verwendung des Bezeichners bekannt sein, damit der Leser des Programms (z.B. der Übersetzer) prüfen kann, ob die Verwendung hinsichtlich des Typs korrekt ist, ohne zuerst die gesamte (restliche) Datei lesen zu müssen. Soll ein Bezeichner erst nach  der Verwendung im Quelltext definiert werden, dann muß er also vor  der Verwendung zumindest deklariert werden.

In dem folgenden Beispielprogramm wird die Funktion "hallo" zunächst ohne Definition deklariert. Dabei wird nur der Typ  festgelegt. Die Funktion kann dann schon verwendet  werden, weil der Übersetzer ihren Typ  an der Stelle des Aufrufs kennt. Nach der ersten Verwendung folgt weiter unten im Quelltext die Definition (Implementation). Der Übersetzer liest den Quelltext nur einmal  von vorne bis hinten durch. Erst der Verbinder wird dann die Adresse der Funktion "hallo" an den Stellen des Aufrufs dieser Funktion einsetzen, das ermöglicht dann den Aufruf. Der Verbinder  kann solch Ersetzungen auch dann erzeugen, wenn eine Definition im Programmtext nach der Verwendung erfolgt.

Es ist erlaubt, einen Bezeichner mehrfach  zu deklarieren, wenn alle Deklarationen übereinstimmen. Eine Definition eines Bezeichners darf jedoch in der Regel nur einmal innerhalb eines Namensraumes und Gültigkeitsbereichs erfolgen (abgesehen von bestimmten Ausnahmen, wie Überladungen).

deklaration.cpp
#include <iostream> 
#include <ostream>
void hallo(); // Deklaration von "hallo" (ohne Definition)
int main(){  
hallo // Verwendung von "hallo" 
(); }
void hallo(); // identische Redeklaration ist erlaubt
void hallo() // Definition und erneute Deklaration von "hallo" 
{ ::std::cout << "Hallo!\n"; } //

::std::cout
Hallo!

Ohne die Deklaration kennte der C++ -Leser die Funktion beim Aufruf nicht gut genug, um die Richtigkeit ihrer Verwendung zu prüfen.

deklaration.txt
#include <iostream> 
#include <ostream>
int main(){ hallo(); }
void hallo(){ ::std::cout << "Hallo!\n"; }

Konsole
"deklaration.txt", line 3: error: identifier "hallo" is undefined 
int main(){ hallo(); } 
^
1 error detected in the compilation of "deklaration.txt".

Wenn eine Funktion vor  ihrer ersten Verwendung definiert wird, ist eine zusätzliche Deklaration nicht nötig.

definition.cpp
#include <iostream> 
#include <ostream>
void hallo() // Definition von "hallo" 
{ ::std::cout << "Hallo!\n"; } //
int main(){  
hallo // Verwendung von "hallo" 
(); }

::std::cout
Hallo!

Natürlich könnte der Eindruck entstehen, daß Deklarationen, die nicht gleichzeitig Definitionen sind, nicht so dringend benötigt werden, weil Funktionen ja vor  ihrer Verwendung definiert werden können. Das ist aber nicht immer möglich. Deklarationen, die nicht gleichzeitig Definitionen sind, spielen eine wichtige Rolle. Beispielsweise kann ein C++ -Programm Funktionen der Standardbibliothek benutzen, die es nicht selber definiert hat. Das geht aber nur dann, wenn diese vorher deklariert wurden. Diese Deklaration wird von den Kopfdirektiven, wie beispielsweise "#include <iostream>" bewirkt, ohne daß der Quelltext der Definition von Standardfunktionen zugänglich sein muß.

Lokale Deklarationen

Innerhalb eines Blocks ist die Definition  einer Funktion nicht möglich. Eine Funktion kann jedoch innerhalb eines Blocks deklariert  werden. Der Typ der so deklarierten Funktion ist dann nur innerhalb dieses Blocks bekannt. Daher spricht man auch von einer (zu diesem Block) lokalen  Deklaration.

deklaration1.cpp
#include <iostream> 
#include <ostream>
int main(){  
void hallo(); // lokale Deklaration von "hallo" 
hallo // Verwendung von "hallo" 
(); }
void hallo() // Definition von "hallo" 
{ ::std::cout << "Hallo!\n"; } //

::std::cout
Hallo!

Leere Klammern oder Schlüsselwort "void"?

Sowohl in einer Definition  als auch in einer Deklaration  können die runden Klammern leer sein oder das Schlüsselwort "void" enthalten, das ändert nichts an der Bedeutung. In dem folgenden Programmbeispiel "voidpar.cpp" gilt die zweite reine Deklaration daher als identische Redeklaration. Auch in der Definition kann das Schlüsselwort "void" in die runden Klammern geschrieben werden.

voidpar.cpp
#include <iostream> 
#include <ostream>
void hallo(); // Deklaration von "hallo" (ohne Definition)
void hallo( void ); // identische Redeklaration ist erlaubt
void hallo( void ) // Definition und erneute Deklaration von "hallo" 
{ ::std::cout << "Hallo!\n"; } //
int main(){ hallo(); }

::std::cout
Hallo!

Es wird empfohlen, das Schlüsselwort "void" nie in den runden Klammern zu verwenden, sondern diese gegebenenfalls immer leer zu lassen, da dies bei gleicher Bedeutung kürzer ist.

Anhang *

»void« als Parameterliste

“The parameter list (void) is equivalent to the empty parameter list.”, »ISO/IEC 14882:1998(E)« und »ISO/IEC 14882:2003(E)«, 8.3.5 p2.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram721230 stefan_ram:721230 slrprd, slrprdqxx, slrprddoc, slrprd721230, slrprddef721230, PbclevtugFgrsnaEnz

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten.
http://www.purl.org/stefan_ram/pub/c++_deklaration_de