Moin, habe da mal eine Frage bzgl. Pointern. Ich übergebe der Funktion ja als "strDest", den Zielort oder Speicher. Die Funktion kopiert mir also von "strSrc" -> nach "strDest". Meine Frage.: Ich inkrementiere den Zeiger "strDest" in der Funktion, heißt das auch gleichzeitig das ich die Adresse vom Zielspeicher inkrementiere? Oder wie genau wird das gehändelt? char buff[10] = ""; void strcpy_(char *strDest, const char *strSrc) { while(*strDest++ = *strSrc++); } Wenn ich dem Parameter "strSrc" = "Hallo" übergebe, wird "strDest" doch 6 mal inkrementiert oder? Somit müsste mein "buff" doch jetzt inkremtiert werden? Danke für die Erklärung.
UnderDog schrieb: > void strcpy_(char *strDest, const char *strSrc) > { > while(*strDest++ = *strSrc++); > } > > Wenn ich dem Parameter "strSrc" = "Hallo" übergebe, wird "strDest" doch > 6 mal inkrementiert oder? > Somit müsste mein "buff" doch jetzt inkremtiert werden? Nein. Inkrementiert werden nur die funktionslokalen Kopien der Zeiger. Willst du wirklich den ursprünglichen Zeiger inkrementieren, mußt du nicht den Zeiger selber an die Funktion übergeben, sondern einen Zeiger auf die Zeigervariable (und natürlich den Rumpf der Funktion entsprechend anpassen).
Ah Okay. Also werden jeweils noch Kopien in den Funktionen angelegt. Wusste ich noch nicht. Klingt aber logisch.
UnderDog schrieb: > Also werden jeweils noch Kopien in den Funktionen angelegt. Wusste ich > noch nicht. Klingt aber logisch. Eigentlich werden keine Kopien angelegt... das Konzept nennt sich "call by value", und in C gibt es auch nur dieses (im Gegensatz zu zB Pascal)
UnderDog schrieb: > Ah Okay. > Also werden jeweils noch Kopien in den Funktionen angelegt. Wusste ich > noch nicht. Klingt aber logisch. Wenn du den Pointer in einer Funktion inkrementieren willst, kannst du einen Pointer auf einen Ponter setzen und den der Funktion übergeben. also: TolleFunktion(int **ptr);
Michael R. schrieb: > Eigentlich werden keine Kopien angelegt... Nun ja, wie würdest Du das nennen, was da auf den Stack liegt?
Possetitjel schrieb: > Michael R. schrieb: > >> Eigentlich werden keine Kopien angelegt... > > Nun ja, wie würdest Du das nennen, was da auf den Stack > liegt? Hab mich unklar ausgedrückt: Die Funktion selbst legt keine Kopien an
Michael R. schrieb: >>> Eigentlich werden keine Kopien angelegt... >> >> Nun ja, wie würdest Du das nennen, was da auf den Stack >> liegt? > > Hab mich unklar ausgedrückt: Die Funktion selbst legt > keine Kopien an Ja, okay. Hast Recht. Die Kopie wird natürlich beim Aufruf der Funktion angelegt, nicht IN der Funktion.
Alle Parameter einer C-Funktion sind Kopien. Bei Arrays sind es halt die Anfangsadressen. Die Funktionsparametern sind alles lokale Variablen. Arrays kännen, nach ihrer Definition, weder in der Größe noch der Adresse geändert werden. Darum würde das Beispiel mit buff auch nicht mit Doppelzeiger (Zeiger auf Zeiger) funktioniern.
Dirk B. schrieb: > Darum würde das Beispiel mit buff auch nicht mit Doppelzeiger (Zeiger > auf Zeiger) funktioniern. Warum? Pointer sind nur Speicheradressen. Ob in der Speicherstelle auf die die Adresse zeight wieder eine Adresse steht (Doppelpointer), die Adresse auf das erste Element eines Arrays zeigt oder in den Wald ist dabei völlig unerheblich. Wenn da eine Adresse steht, kann man die auch verändern. Und das ist völlig legitim, der Compiler weiß duch die Deklaration auch genau, wie er daszu tun hat.
Pointerpointerpointer schrieb: > Dirk B. schrieb: > Darum würde das Beispiel mit buff auch nicht mit Doppelzeiger (Zeiger > auf Zeiger) funktioniern. > > Warum? > Pointer sind nur Speicheradressen. > > Ob in der Speicherstelle auf die die Adresse zeight wieder eine Adresse > steht (Doppelpointer), die Adresse auf das erste Element eines Arrays > zeigt oder in den Wald ist dabei völlig unerheblich. > > Wenn da eine Adresse steht, kann man die auch verändern. Und das ist > völlig legitim, der Compiler weiß duch die Deklaration auch genau, wie > er daszu tun hat. Einen pointer auf die anfansadresse des arrays kannst du natürlich verändern, ein array aber nicht.es wird zwar immer gern behauptet array=pointer aber das ist eben nicht immer wahr.
:
Bearbeitet durch User
UnderDog schrieb: > Somit müsste mein "buff" doch jetzt inkremtiert werden? Das ist genauso wie bei numerischen Argumenten:
1 | void add42 (int value) |
2 | {
|
3 | value += 42; |
4 | printf ("value=%d\n", value); |
5 | }
|
6 | |
7 | int main () |
8 | {
|
9 | int x = 10; |
10 | |
11 | add42 (x); |
12 | printf ("x=%d\n", x); |
13 | return 0; |
14 | }
|
Das Programm wird für x auch nach Aufruf der Funktion add42() 10 und nicht 52 ausgeben. Eben, weil die Werte der Parameter kopiert werden. Anders ist es, wenn Du eine Referenz (also einen Pointer) übergibst:
1 | void add42 (int *value) |
2 | {
|
3 | *value += 42; |
4 | printf ("value=%d\n", *value); |
5 | }
|
6 | |
7 | int main () |
8 | {
|
9 | int x = 10; |
10 | |
11 | add42 (&x); |
12 | printf ("x=%d\n", x); |
13 | return 0; |
14 | }
|
Hier wird der Pointer beim Aufruf kopiert. Dieser zeigt aber weiterhin auf den Speicherbereich, wo x abgelegt ist. Folglich hat die Variable x nach dem Funktionsaufruf nun den Wert 52.
buff ist ein Array. Da gibt es keinen (loaklisierbaren) Speicherplatz, in dem die Adresse des Arrays abgelegt ist.
1 | char buff[20]; |
2 | char *pc; |
3 | |
4 | //pc kannst du irgendwohin zeigen lassen, buff jedoch nicht.
|
5 | |
6 | void xxx (char **p) |
7 | { **p += 1; |
8 | }
|
9 | |
10 | xxx(&pc); // geht |
11 | xxx(&buff); // geht nicht |
Simon S. schrieb: > es wird zwar immer gern behauptet > array=pointer aber das ist eben nicht immer wahr. Das ist nie wahr. Die Schreibweisen beim Zugriff ähneln sich.
UnderDog schrieb: > Wenn ich dem Parameter "strSrc" = "Hallo" übergebe, wird "strDest" doch > 6 mal inkrementiert oder? > Somit müsste mein "buff" doch jetzt inkremtiert werden? Nein, so nicht. Wenn du in der aufrufenden Funktion einen inkrementierten Zeiger haben willst, muss der zurückgegeben werden: char * stpcpy_(char *strDest, const char *strSrc) { while(*strDest++ = *strSrc++); return strDest; } char buff[20]; char *t; t= stpcpy_(buff, "Hallo"); stpcpy_(t, " Welt!"); printf("%s\n",buff);
Die offizielle Formulierung lautet auf Englisch
> Die Schreibweisen beim Zugriff ähneln sich.
Ein Array „decays to“ = zerfällt in einen Pointer, wenn es als
Funktionsparameter übergehen wird. Innerhalb der Funktion ist es ein
Pointer, draußen ein Array.
Oliver
Oliver S. schrieb: > Ein Array „decays to“ = zerfällt in einen Pointer, wenn es als > Funktionsparameter übergehen wird. Innerhalb der Funktion ist es ein > Pointer, draußen ein Array. Ganz so war das nicht gemeint. Du kannst aus a[10] oder *b nicht erkennen, ob a oder b jeweils Pointer oder Array ist. Aber beim sizeof, inkrement, Adressoperator, als Zuweisungsziel ist es ein großer Unterschied.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.