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).
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);
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.
UnderDog schrieb:> Somit müsste mein "buff" doch jetzt inkremtiert werden?
Das ist genauso wie bei numerischen Argumenten:
1
voidadd42(intvalue)
2
{
3
value+=42;
4
printf("value=%d\n",value);
5
}
6
7
intmain()
8
{
9
intx=10;
10
11
add42(x);
12
printf("x=%d\n",x);
13
return0;
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
voidadd42(int*value)
2
{
3
*value+=42;
4
printf("value=%d\n",*value);
5
}
6
7
intmain()
8
{
9
intx=10;
10
11
add42(&x);
12
printf("x=%d\n",x);
13
return0;
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.
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.