Na ja, das funktioniert schon. ABer nicht so wie du dir das vorstellst
Dein Problem dürfte das hier sein
1 | int main()
|
2 | {
|
3 | int i = 5;
|
4 |
|
5 | foo( i );
|
6 | printf( "%d\n", i );
|
7 | }
|
8 |
|
9 | void foo( int j )
|
10 | {
|
11 | j = 8;
|
12 | }
|
und die Frage dazu lautet: warum hat i nach dem Funktionsaufruf immer
noch den WErt 5, ich habe ihm doch in der Funktion einen neuen Wert
zugewiesen.
Die Antwort darauf (die sich auch in jedem C-Lehrbuch findet) lautet:
Weil bei der Parameterübergabe eine Kopie gemacht des Arguments gemacht
wird. Die Funktion bekommt keinen Zugang zu i, sondern nur eine Kopie
des Wertes von i. Und diesen Wert überschreibt sie lokal in der Funktion
mit 8. Das ändert aber i nicht!
Will man einer Funktion die Möglichkeit geben, dann muss man der
Funktion die Adresse der zu ändernden Variablen zur Verfügung stellen.
1 | int main()
|
2 | {
|
3 | int i = 5;
|
4 |
|
5 | foo( &i );
|
6 | printf( "%d\n", i );
|
7 | }
|
8 |
|
9 | void foo( int* j )
|
10 | {
|
11 | *j = 8;
|
12 | }
|
Jetzt hat die Funktion die Möglichkeit i zu ändern.
Bei dir ist jetzt die Sache die, das du nicht einfach einen int Wert
hast, sondern einen Pointer
1 | int main()
|
2 | {
|
3 | char * wert = "Hallo";
|
4 |
|
5 | foo( wert );
|
6 | printf( "%s\n", wert );
|
7 | }
|
8 |
|
9 | void foo( char * j )
|
10 | {
|
11 | j = "Welt";
|
12 | }
|
Was passiert? Genau wie im ersten Beispiel bekommt die Funktion eine
Kopie des momentanten Inhalts von wert. Dieser ist: die Startadresse des
Strings.
DIese Startadresse wird in j abgelegt und innerhalb der Funktion
manipuliert.
Aber: Das ändert nicht die Variable "Wert"
Das Schema sieht doch so aus
1 | int main()
|
2 | {
|
3 | T i = ...;
|
4 |
|
5 | foo( i );
|
6 | }
|
7 |
|
8 | void foo( T j )
|
9 | {
|
10 | j = ...;
|
11 | }
|
Im ersten Beispiel war T der Datentyp "int". Im dritten Beispiel war T
der Datentyp "char *". Aber ansonsten sind die beiden Beispiele völlig
gleichwertig. Es gibt keinen konzeptionellen Unterschied.
Das 2.te Beispiel hat gezeit, wie es richtig geht.
Das allgemeine Schema dazu lautet
1 | int main()
|
2 | {
|
3 | T i = ...;
|
4 |
|
5 | foo( & i );
|
6 | }
|
7 |
|
8 | void foo( T * j )
|
9 | {
|
10 | * j = ...;
|
11 | }
|
Setze anstelle von T einfach "int" ein und du landest beim 2.ten
Beispiel.
Beim Aufruf steht ein & (als ein "Adress of" Operator), in der Argument
Liste wird ein Pointer gemacht und Zugriffe erfolgen über den
Dereferenzierungsoperator *.
Und jetzt wendest du dieses Schema auf die Situation an, dass T ein char
Pointer ist. Also alle T durch "char *" austauschen.
Du landest bei
1 | int main()
|
2 | {
|
3 | char * wert = "Hallo";
|
4 |
|
5 | foo( &wert );
|
6 | printf( "%s\n", wert );
|
7 | }
|
8 |
|
9 | void foo( char * * j )
|
10 | {
|
11 | *j = "Welt";
|
12 | }
|
Und jetzt lautet die Ausgabe des Programmes tatsächlich "Welt", genauso
und aus genau dem gleichen Grund, warum die Ausgabe in der int Version
eine 8 war. foo hat über den Pointer Zugriff auf die Pointer-Variable
wert und lässt sie auf den String "Welt" zeigen.
Willkommen in der 2-Stern Programmierung.