pointer auf char array
-
Ich habe momentan ein kleines Verständnisproblem. Die Zeile:
const char *siffon[] ={"tomate", "ei"}; printf("\n\nsiffon: %s", siffon[1]);
gibt mir wunderschön das zweite Element aus dem array.
Aber WARUM sagt mein Compiler mir, wenn ich printf mit:printf("\n\nsiffon: %s", (*siffon[1]));
aufrufe, dass ein int wert zurückgegeben wird? Nach meinem Verständnis solllte ich nämlich genau so den pointer aufrufen...
Besten dank im voraus!
-
siffon
: Array mit zwei Elementen vom Typconst char*
siffon[1]
: Eines der Elemente aus dem Array, also einconst char*
*siffon[1]
: Dereferenzierung dieses Zeigers, also einconst char
.Bei Formatspezifizierer
%s
wird jedoch einconst char*
erwartet.Da printf eine Funktion mit variabler Parameterzahl ist, wird der
const char
zusätzlich noch zu einem Integer aufgewertet, aber das ändert nichts da dran, dass vorher schon einmal zu oft dereferenziert wurde.
-
Das klingt soweit Einleuchtend. Allerdings kann ich mir dann nicht erklären, warum:
printf("\n\nsiffon: %s", *siffon);
mir das erste Elemten der Liste ausgiebt. Müsste dann ja auch eine Dereferenzierung sein !?
-
royal_ts schrieb:
Müsste dann ja auch eine Dereferenzierung sein !?
Ja, ist es auch. Ein Array wird in fast jedem Zusammenhang wie ein Zeiger auf sein erstes Element aufgefasst (Ausnahmen sind, wenn das Array als Operand eines sizeof oder eines Adressoperators dient und noch ein paar andere). Das heißt hier gilt siffon als ein Zeiger auf sein erstes Element, dieser wird dereferenziert, also erhält man "tomate".
Der Elementzugriffsoperator [] ist übrigens nichts anderes als eine Abkürzung für eine Addition und Dereferenzierung:
foo[i] // entspricht *(foo + i)
(Dabei gelten die üblichen Regeln der Pointerarithmetik: Wenn zum Beispiel ein Zeiger auf int um 1 erhöht wird, dann wird der Addresswert in dem Pointer um die Größe eines int erhöht, nicht um 1 Byte)
Nebenbemerkung (nicht wichtig, aber interessant zu wissen, wenn man unleserlichen Code schreiben will
):
Die Erklärung zum Elementzugriffsoperator ist durchaus wörtlich zu nehmen:char foo[] = "Hallo"; 2[foo];
Kann man tatsächlich so schreiben. Das entspricht nach obiger Erklärung
*(2 + foo)
, was ein gültiger Ausdruck ist, der 'l' ergibt. Denn da man die Addition auch umdrehen kann ist das das selbe wie*(foo + 2)
, was das selbe ist wiefoo[2]
. Da Zeichenkettenlliterale selber auch einen Arraytyp haben kann man sogar schreiben"Hallo"[2]; // oder sogar 2["Hallo"];