ausgabe bei kommandozeilenargument
-
Welche Ausgabe hat folgendes Programm, wenn man es mit dem Kommandozeilenargument GSVCPD aufruft? Erläutern Sie, wie es zu dieser Ausgabe kommt. 01 #include <stdio.h> 02 #include <string.h> 03 04 int main(int argc, char *argv[]) 05 { 06 char **pp, *z; 07 if (argc > 1) 08 { 09 pp = argv + 1; 10 z = *pp + strlen(*pp); 11 12 while (*pp - --z) 13 printf("%c", --*z); 14 15 printf("%c\n", *z); 16 } 17 return 0; 18 }
pp zeigt ja auf GSVCPD
bei z wird es schon schwieriger... *pp wäre ja G?! und dann + strlen(*p)?
is das dann derefernziert die länge von G bzw. 1?die bedinung in der while schleife is mir auch net ganz klar...
kann mir da vielleicht jmd helfen?
gruss peteedit: ich weiss was raus kommt, nur möchte ich drauf kommen
-
p ist ein Zeiger auf einen char*, *p ist der char* dahinter (und verweist auf das erste (und einzige) übergebene Argument "GSVCPD") - mit strlen() holst du dir die Länge dieses Arguments (6). Damit wird z auf den Null-Terminator des Argument-Strings gesetzt (und läuft in der Schleife schrittweise zurück).
Zur while-Schleife:
"--z" dekrementiert z und liefert dessen neuen Wert zurück
"*p - --z" bildet den Abstand zwischen den beiden Zeigern (am Anfang 5, am Ende 0 - was als false interpretiert wird und die Schleife beendet)(und das "--*z" verringert den Zeichenwert im Argumentstring, bevor er ausgegeben wird)
-
beim ersten durchlauf:
hätte ich ja dann in der whileschleife die bedingung: G-D != 0 , was bedeutet, dass er
rein läuft.
dann gib ich das erste zeichen aus... wäre ein P ... müsste aber doch ein C sein... also nochmal dekrementiert???ist die whileschleife = 0, wenn z dann P angekommen ist?! wäre ja dann 0...
auch wenn man die ascii werte benutzt und voneinander abzieht.
-
Da werden nicht die Inhalte hinter den Zeigern verrechnet, sondern die Zeiger-Adressen. Prinzipiell kannst du dir das so vorstellen:
//vor dem Beginn der while-Schleife: pp->argv[1] | v [ G | S | V | C | P | D |\0 ] ^ | z ----------------------------+ -> pp - z = -6 //Abfrage der while-Schleife: pp->argv[1] | v [ G | S | V | C | P | D |\0 ] ^ | z ------------------------+ -> pp - --z = -5 (parallel wird z umgebogen) //Ausgabe in der Schleife: pp->argv[1] | v [ G | S | V | C | P | C |\0 ] ^ | z ------------------------+ -> --*z dekrementiert jetzt tatsächlich den Wert in deinem Argumentstring (aus 'D' wird 'C') -> der neue Inhalt von *z ('C') wird ausgegeben
(in den weiteren Schleifendurchläufen wird auf die selbe Art 'O','B','U','R' ausgespuckt - und nach der Schleife das 'G' vom Anfang des übergebenen Arguments.
(du stammst nicht zufällig aus Coburg, oder?)
-
ja doch... genau aus coburg
habe die dereferenzierung bei der printf anweisung nicht beachtet gehabt, weshalb ich noch ne stelle im kommandozeilenargument geschoben habe.
vielen dank für deine ausführliche hilfe!
-
dahier hätte ich noch eins:
#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(); }
da weiss ich nicht genau, was ich mit:
printf( "%s", --++cpp+5 );
machen soll.
da +cpp auf "C i" zeigt und dann
--++cpp+5 zuerst dekrementiert, dann inkrementiert und dann +5?
inkrement und dekrement würde sich doch gegenseitig aufheben?!...
trotzdem er dann nicht auf "t ga"
-
Na gut, nehmen wir den Ausdruck mal auseinander:
--++cpp+5 -> ((--((++cpp))))+5Ausgangsbedingung: cpp verweist auf cp[1], dieses wiederum auf c[2]="C i"
(++cpp) - verbiegt cpp auf cp[2] -> c[1] = "lllt dumm"
(++cpp) - dereferenziert cpp - d.h. wir arbeiten nun mit cp[2] weiter
--((++cpp)) - verbiegt cp[2] auf c[0] = "he dast ga"
(--((++cpp))) - dereferenziert cp[2] - d.h. wir arbeiten mit c[0] weiter
((--((++cpp))))+5 - geht fünf Schritte nach vorne - damit haben wir einen Zeiger auf das 6. Zeichen von cp[0] (das ist das s)-> die Ausgabe liefert "st ga"
(die Zeigerbiegereien im ersten und dritten Schritt bleiben auch für die folgenden Ausgaben erhalten)
-
(++cpp) - dereferenziert cpp - d.h. wir arbeiten nun mit cp[2] weiter
--((++cpp)) - verbiegt cp[2] auf c[0] = "he dast ga"d.h. wenn ich dereferenziere, arbeite ich nicht mehr mit dem aktuellen zeiger, sondern geh eine stufe tiefer und verwende den dann weiter?!
-
Ja, das ist der Zweck des Dereferenzierens - du gehst von einem Zeiger zu dem Wert, auf den er gerade zeigt.