Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Variablen mitten im Quelltext deklarieren - Warum?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
07.09.2008, 12:05 Uhr
~Erik
Gast


Hallo alle miteinander,

ich weiß nicht, ob meine folgende Frage schon gestellt wurde; der Suchfunktion nach wohl eher nicht, daher stell ich sie einfach mal. Ich komme ursprünglich aus der Pascal-Ecke und eigne mir derzeit C++ an. Nachdem ich ein Buch und mehrere Tutorials gelesen hatte, habe ich mich über eine Sache doch sehr gewundert:

Scheinbar ist es gang und gebe, Variablen irgendwo mittendrin zu deklarieren, ein Tutorial sprach sogar von "so spät wie möglich; am besten erst, wenn wir sie wirklich brauchen". Meine Frage ist: Warum? In Pascal z.B. gibt es aus gutem Grund sogar extra einen Deklarationsteil, wo man alle verwendeten Variablen, Funktionen, etc. definiert, um nicht den Überblick zu verlieren. Warum wird das in C++ anders empfohlen?

Ich hoffe, ihr könnt mir das irgendwie erläutern

Erik
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
07.09.2008, 15:28 Uhr
Hans
Library Walker
(Operator)


Hi,

die Empfehlung, Variablen erst so spät wie möglich zu deklarieren, hat zum Einen damit zu tun, wie lokale Variablen von C++ intern verwaltet werden. Die werden nämlich alle auf dem Stack des Prozessors abgelegt, dessen Speicherkapazität begrenzt ist. Da sich der Gültigkeitsbereich jeweils nur auf einen Block bezieht, nämlich jenem, in dem sie deklariert sind, existieren sie auch nur dort. Beispiel:

C++:
for (int i=0; i<x; i++)
  {
     /* tue irgendwas */  
  }


Die Variable i existiert hier nur innerhalb der Schleife. Sobald der Code zur Bearbeitung des Schleifenrumpfes verlassen wird, hört die Variable i auf zu existieren und der Speicherplatz kann anders verwendet werden.

In Pascal hat die Deklaration der Variablen am Anfang ebenfalls mit der Speicherverwaltung zu tun. Da müssen die Variablen vorher deklariert werden, damit der Compiler den benötigten Speicherplatz berechnen kann. Das war zur Zeit der Entwicklung von Pascal nötig, hatte aber auch den Zweck, Programmierer dazu zu erziehen, sich mehr Gedanken über den benötigten Speicherplatz zu machen.

Und ganz wichtig: In C++ (und auch in C) gibt es einen Unterschied zwischen deklaration und definition von Variablen. Eine Deklaration sagt demn Compiler lediglich, das es eine Variable gibt. Das merkt er sich dann, reserviert aber keinen Speicherplatz dafür. Erst bei der Definition einer Variablen wird auch Speicherplatz dafür bereit gestellt. Ich glaube, das steht hier auch schon irgendwo ausführlicher beschrieben.

Zum Vergleich mal eine Codesequenz in Pascal und C++ :
Pascal:

Code:
var a, b, c : integer;
    t       : char;


Hier werden 4 Variablen deklariert, und entsprechend Speicherplatz zur Verfügung gestellt.

C++:

C++:
int a, b, c;
char t;


Hier werden ebenfalls 4 Variablen deklariert, aber der Compiler reserviert dafür noch keinen Speicherplatz, sondern merkt sich erst mal nur, das es diese Variablen geben soll.

Der andere Grund, warum man Variablen in C++ erst dann definieren soll, wenn man sie braucht, hat mit der OOP zu tun. Wenn sich hinter einer Variablen ein umfangreiches Objekt verbirgt, dann wird ein Konstruktor aufgerufen, der dafür entsprechend Speicherplatz reserviert. Dieser Aufruf benötigt auch Rechenzeit, die man u.U. anderswo besser gebrauchen könnte. Wenn nun am Anfang einer Funktion viele Objekte erstellt werden, dauert es erst mal eine Weile, bis die Objekte erstellt sind, bevor die Funktion das tut, was sie soll. Am Ende der Funktion müssen die erstellten Objekte alle wieder zerstört werden (Destruktor aufruf), was auch wieder Rechenzeit kostet.
Wird so eine Funktion nun öfter aufgerufen, ist der Prozessor möglicherweise mehr damit beschäftigt, Objekte zu erstellen und zu zerstören, als es nötig ist, und die Bearbeitung der eigentlichen Funktion beansprucht nur einen Bruchteil der Gesamtlaufzeit der Funktion.

Dann kann es auch vorkommen, das Destruktoren nicht sauber geschrieben sind, und Objekte dadurch nicht vollständig zerstört werden, was zu Speicherlecks führt.

So, ich hoffe, das war einigermassen verständlich und vollständig. Meine persönliche Meinung ist ja, das man die Angewohnheit aus Pascal, Variablen am Anfang zu deklarieren ruhig beibehalten kann, solange man es mit Standarddatentypen zu tun hat. Auch für zusammengesetzte Datentypen, also Records in Pascal halte ich es so, solange dadurch keine Speicherplatzverschwendung im grossen Stil entsteht.
Sobald aber Objekte, und damit Konstruktoren und Destruktoren ins Spiel kommen, ist es Vernünftig, darüber noch mal nachzudenken, und Variablen wirklich erst dann zu definieren, wenn man sie braucht.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 07.09.2008 um 15:31 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
07.09.2008, 17:16 Uhr
~Erik
Gast


Ah, vielen Dank, das erklärt einiges

Mir war schon bewusst, dass die Variablen auf dem Stack abgelegt werden; dass beim Deklarieren noch kein Speicher reserviert wird, hingegen nicht. Da spräche es ja erst recht nichts dagegen, sie gleich am Blockanfang zu deklarieren.

Wie gesagt, ich hatte es häufig so gesehen:

C++:
#include <iostream>

int main() {
    // ... ganz viel Quelltext ...

    int irgendwas = 88;
    beispiel(irgendwas);

    // ... noch mehr Quelltext ....

    return 0;
}


Korrigiert mich, wenn ich falsch liege, aber man könnte es ja auch so machen:

C++:
#include <iostream>

int main() {
    int irgendwas;
    // ... ganz viel Quelltext ...

    irgendwas = 88;
    beispiel(irgendwas);

    // ... noch mehr Quelltext ....

    return 0;
}


Bei umfangreicheren Datentypen sollte man sowieso überlegen, ob man sie nicht doch auf dem Heap ablegt. Aber jetzt verstehe ich wenigstens die Gründe dazu

Erik
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.09.2008, 19:11 Uhr
Kest
saint


@Hans: Das stimmt so nicht. Eine Deklaration verlangt, dass es auch eine Definition geben muss (wenn sie überhaupt gebraucht wird). Eine echte Deklaration wäre z.B.:>extern int a;<, der Speicher wird woanders angelegt oder >int foo(int);<: der Funktionsrumpf wird woanders definiert. >int a;< ist sowohl eine Deklaration, als auch eine Definiton, wie auch die meisten Deklarationen.

Aber um auf die Frage von ~Erik zu kommen: es hat, außer von Hans bereits oben erwähntem komplexen Verhalten von benutzerdefinierten Typen, und dem Vorteil der Lokalität, damit zu tun, Fehler durch uninitialisierte Variablen zu vermeiden. Man könnte ja diesen 89ger Stil benutzen, doch gebrachte hätte's nicht viel: woher soll ich nach >ganz viel Quelltext< wissen, was ich an >irgendwas< zuweisen soll? Ich könnte ja nachschauen und all die "der ganze Quelltext"-Zeilen geteilt durch ungefähr 20 Deklarationen am Anfang nach dem Kommentar zu durchsuchen, aber auf dem Weg dahin hab ich sieben Zuweisungen an sie entdeckt.
Ich habe selten einen Grund zu deklarieren, ohne den Initialwert zuzuweisen. Somit deklariere ich erst dort, wo ich es brauche.
--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.

Dieser Post wurde am 07.09.2008 um 19:28 Uhr von Kest editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: