__Son´s Bersi__ schrieb:
> Karl Heinz Buchegger schrieb:
>> Du kannst nicht einfach Dinge hinschreiben wie du sie denkst und hoffen,
>
> Wenn du die Variabl. meinst, die wollte ich blockartig = übersichtlicher
> deklarieren. Fehler?
Die erste Frage lautet: brauchst du denn die Variablen überhaupt?
Schau dir mein Programm an: Weit und breit nichts von diesen Variablen
zu sehen.
Der nächste Punkt ist: Variablen haben einen Gültigkeitsbereich und
damit gekoppelt einen Sichtbarkeitsbereich. Grob gesagt: Variablen sind
in dem Block gpltig und sichtbar, in dem sie definiert sind (und in
allen darin enthaltenen Blöcken. Der Block begrenzt die Sichtbarkeit -
ausserhalb des Blockes existiert die Variable schlicht und ergreifend
einfach nicht.
1 | void foo()
|
2 | { // <----- hier beginnt ein Block, Block A
|
3 |
|
4 | int wert; // <--- diese Variable ist nur innerhalb des Blockes
|
5 | // bekannt, in dem sie definiert wurde
|
6 |
|
7 | if( ... )
|
8 | { // ein weiterer Block (in den aeusseren reingeschachtelt)
|
9 | // beginnt. Block B
|
10 |
|
11 | int j; // diese Variable ist innerhalb von Block B definiert.
|
12 | // Ihre Lebensdauer und damit ihre SIchtbarkeit wird
|
13 | // durch diesen Block begrenzt.
|
14 |
|
15 | j = wert; // das ist ok. j ist innerhalb von Block B definiert
|
16 | // und wert ist eine Blockebene 'höher' definiert, weil
|
17 | // ja Block B in Block A eingeschachtelt ist.
|
18 | // Man kann es auch so sagen: einfach die Blockstruktur
|
19 | // nach 'aussen' verfolgen und nachsehen ob es in diesem
|
20 | // Block die angegebene Variable gibt
|
21 |
|
22 | } // <--- hier wied Block B (der vom if) wieder geschlossen
|
23 | // Alle Variablen in diesem Block existieren danach
|
24 | // nicht mehr.
|
25 | // In diesem konkreten Beispiel gibt es daher
|
26 | // danach keine Variable j mehr
|
27 |
|
28 | } // <---- Der Block A wird geschlossen. Alle in diesem BLock
|
29 | // enthaltenen Variablen gibt es danach nicht mehr.
|
30 | // D.h. hier endet die Lebensdauer und damit auch
|
31 | // Sichtbarkeit von wert. Ausserhalb dieses Blocks gibt
|
32 | // es keine Variable 'wert' und wenn es doch eine Variable
|
33 | // dieses Namens gibt, dann handelt es sich dabei
|
34 | // um eine andere Variable.
|
> Zur weiteren Transparenz, hatte ich das main nach oben geschrieben.
> Fehler?
Lies deinen Code von oben nach unten. So wie es auch der Compiler macht.
Und halte dich an den einfachen Grundsatz: Benutzt werden kann nur das,
was auch bekannt ist. Wenn du eine Funktion aufrufen willst, dann hat
die eine Funktionssignatur. Die muss bekannt sein, ehe man sie aufruft.
Durch die Reihenfolge
1 | void foo( void )
|
2 | {
|
3 | ...
|
4 | }
|
5 |
|
6 | int main()
|
7 | {
|
8 | foo();
|
9 | }
|
ist automatisch die Funktionssignatur dem Compiler bekannt gemacht
worden, ehe die Funktion benutzt wird. Schreibst du das anders rum
1 | int main()
|
2 | {
|
3 | foo();
|
4 | }
|
5 |
|
6 | void foo( void )
|
7 | {
|
8 | ....
|
9 | }
|
dann zwingst du den Compiler dazu, Standardannahmen zu treffen, wenn der
den Aufruf der Funktion behandeln soll, ehe er die Funktion selbst zu
Gesicht bekommt. Und in deinem Fall waren diese Standardannahmen eben
falsch.
Lösen kann man das entweder durch Umdrehen der Reihenfolge, oder in dem
man mittels eines Prototypen dem Compiler die Funktionssignatur bekannt
gibt, ehe man die Funktion das erste mal aufrufen will
1 | void foo( void ); // Ein Protoyp. Es gibt eine Funktions namens foo
|
2 | // und so sieht ihr Funktionskopf aus
|
3 |
|
4 | int main()
|
5 | {
|
6 | foo(); // Durch den Protoypen weiß der Compiler, wie er
|
7 | // das hier behandeln muss und braucht keine
|
8 | // ANnahmen treffen
|
9 | }
|
10 |
|
11 | void foo( void ) // Aber irgendwann muss natürlich auch mal die
|
12 | { // Funktion selbst kommen. Bisher war da ja nur
|
13 | ... // der Prototyp
|
14 | }
|
Aber warum erklär ich dir das eigentlich (halbherzig), wo du das in
jedem noch so grindigem C-Buch auf dutzenden Seiten in aller
Ausführlichkeit nachlesen kannst?
Kauf dir ein C-Buch!