zeiger rätsel
-
ich sitz hier an folgender aufgabe, die mir kopfzerbrechen bereitet:
#include <stdio.h> char *c[] = { "he dast ga", "lllt dumm", "C i", "dar nich" }; char **cp[] = { c+3, c+2, c+1, c }; char ***cpp = cp; int main( void ) { printf( "%s", **++cpp ); printf( "%s", *--*++cpp+5 ); printf( "%s", cpp[-2][0]+2 ); printf( "%s\n", *(cpp[1]+1)+3 ); getchar(); }
die lösung dafür kenne ich, weiss aber nicht, wie ich drauf kommen soll.
der erste printf-aufruf ist noch relativ einfach:cpp, was auf cp zeigt wird inkrementiert (c+2) und dann 2. dereferenziert.
1. mal um auf den inhalt von cpp zu kommen und ein 2. mal für den inhalt cp, also c?! -> "C i"beim 2. aufruf von printf bekomm ich schon probleme:
cpp, der auf c+2 in cp zeigt, wird wieder erst erhöht (->c+1 in cp), danach derefernziert. Damit würde ich doch nun schon cp verändern, weil ich nun auf dem zeiger arbeite oder?
oder habe ich durch die 2 dereferenzierungsoperatoren im 1. printf aufruf schon den zeiger cp verändert?
hier sollte zum schluss der zeiger auf c von cp[4] stehen, um dann 5 zeichen weiter zu gehen und zu "st ga" zu kommen?!3. bei den nächsten aufrufen weiss ich nicht weiter, weil es mir nicht klar ist, wie die zeiger im moment stehen. sollte ja nur ein indexzugriff sein, also kein zeiger verändert werden?!
genauso wie der letzte aufrufhier ist sicherlich der ein oder andere denkfehler drin.
vielleicht kann mir da jmd weiter helfen.
dankegruss pete
-
hatte schon einmal das gleiche problem, was ich auch gepostet hatte. Nur war es zu lange her, dass ich es anfangs nicht gefunden hab.
für die, die es interessiert:http://www.c-plusplus.net/forum/viewtopic-var-t-is-203381-and-highlight-is-.html
danke
-
Um Gottes willen
wer stellt denn solche Aufgaben? Die dienen wohl eher dazu den Leuten die Zeiger zu verleiden. Damit kann man doch kein Interesse vertiefen, sondern nur abneigung schaffen.
grüße,
-
Mit der beste Kopierschutz für Quellcode *grins*
Herrlich unleserlich - suche bei sowas mal Fehler, ts ts ts ...
-
Ist das Ergebnis von Scherzen wie
cpp[-2][0]
überhaupt definiert?
-
klar, ist das definiert. es steht nirgendwo geschrieben, dass man beim spielen mit zeigern nur addieren darf. man sollte sich an dieser stelle in erinnerung rufen, dass laut standard "array[stelle]" nur eine kurze schreibweise für "(array+stellesizeof(type_des_arrays))" ist.
wenn man jetzt den fall konstruiert, dass man mit einem iterator ähnlichen konstrukt durch ein mehrdimensionales array läuft, also so etwas:int array[][]; int array_it[][]=array; [...] array_it++; [...]
und man jetzt auf z.b. den 1. wert aus der zeile vor der aktuellen position des array_it zugreifen will, ist "array_it[-1][0]" durchaus eine sinnvolle konstruktion. man sollte halt immer nur sicher stellen, dass sich da auch wirklich etwas befindet...
in dem code des op geht das gut, weil der wert von cpp in den beiden zeilen davor jeweils um eins erhöht wurde. also cpp[-2] schlicht auf die adresse zeigt, die cpp zu beginn hatte.
-
Zu Beginn sieht es wie folgt aus:
cpp zeigt auf cp[0] cp = {c+3, c+2, c+1, c}
1. Zeile
printf( "%s", **++cpp ); ++cpp : erhöht den Zeiger cpp um 1 * sizeof(*cpp) *cpp : dereferenziert den Zeiger. Mit ++cpp zeigt *cpp auf c+2 Damit ist **++cpp der Zeiger auf "C i"
Nach dieser Zeile sieht es dann so aus:
cpp zeigt auf cp[1] cp = {c+3, c+2, c+1, c}
2. Zeile
printf( "%s", *--*++cpp+5 ); ++cpp : erhöht den Zeiger cpp um 1. also auf cp[2] *++cpp : Zeiger auf c[1], (Inhalt von cp[2]) --*++cpp : die Speicherstelle cp[2] wird mit dem Zeiger auf c überschrieben Damit ist dann *--*++cpp der Zeiger auf "he dast ga". *--*++cpp +5 setzt den Zeiger um 5 Stellen im String weiter: "st ga" wird ausgegeben.
Nach dieser Zeile sieht es nun so aus:
cpp zeigt auf cp[2] cp = {c+3, c+2, c, c}
3. Zeile
printf( "%s", cpp[-2][0]+2 ); cpp[-2] : ist das gleiche wie *(cpp-2) hier also: c+3 cpp[-2][0]: ist das gleiche wie *(*(cpp-2)): also der Zeiger auf "dar nich" Damit ist dann cpp[-2][0]+2 das gleiche wie *(*(cpp-2))+2: also der Zeiger auf "r nich"
Nach dieser Zeile sieht es so aus:
cpp zeigt auf cp[2] cp = {c+3, c+2, c, c}
4. Zeile
printf( "%s\n", *(cpp[1]+1)+3 ); cpp[1] : das gleiche wie *(cpp+1). hier also: c cpp[1]+1 : c+1 *(cpp[1]+1): Zeiger auf den String "lllt dumm" Dann wird noch der Zeiger um 3 Einheiten weitergeschoben: "t dumm"
Das Ergebnis ist dann: C ist gar nicht dumm
Das war doch nun nicht wirklich schwer, oder?
Gruß mcr