In Betracht ziehen:
void foo1(char **p) { *p++; }
void foo2(char **p) { *p += 1; }
und
char *s = "abcd";
char *a = s;
foo1(&a);
printf("%s", a); //abcd
aber wenn ich benutze foo2()
Anstatt von:
char *a = s;
foo2(&a);
printf("%s", a); //bcd
Kann es jemand erklären?
Der Schlüssel ist der Vorrang der +=
und die ++
Operator. Das ++
hat eine höhere Priorität als die +=
(Tatsächlich haben Zuweisungsoperatoren den zweitniedrigsten Vorrang in C), also die Operation
*p++
bedeutet den Zeiger dereferenzieren, dann den Zeiger inkrementieren selbst durch 1 (wie es nach den Regeln der Zeigerarithmetik üblich ist, ist es nicht unbedingt ein Byte, sondern sizeof(*p)
bezüglich der resultierenden Adresse). Auf der anderen Seite,
*p += 1
bedeutet den Wert erhöhen auf die der Zeiger zeigt um eins (und tue nichts mit dem Zeiger selbst).
Vorrang. Das Postfix ++
bindet enger als das Präfix *
es erhöht sich also p
. Das +=
befindet sich am unteren Ende der Prioritätsliste, zusammen mit dem einfachen Zuweisungsoperator, also fügt er 1 hinzu *p
.
Vorrang von Präfix ++ und * ist gleich. Die Assoziativität beider ist von rechts nach links. Der Vorrang von Postfix ++ ist höher als sowohl * als auch Präfix ++. Die Assoziativität von Postfix ++ ist von links nach rechts.
Lass uns beginnen mit *p += 1
Ich werde versuchen, dies aus einem etwas anderen Blickwinkel zu beantworten … Schritt 1 Schauen wir uns die Operatoren und die Operanden an: In diesem Fall ist es ein Operand (der Zeiger p), und wir haben zwei Operatoren, in diesem Fall * zum Dereferenzieren und += 1 zum Inkrementieren. Schritt 2 mit höherem Vorrang * hat Vorrang vor +=
*P++
Das hier ist ein bisschen kniffliger… vielleicht sogar abgefahren. Wieder haben wir einen Operanden (p der Zeiger) und zwei Operatoren, nur haben jetzt * für Dereferenzierung und ++ Post-Inkrement die gleiche Priorität. (In einigen Tabellen hat das ++ in einem Beitrag eine höhere Priorität.)
Schritt 1 Schauen wir uns die Operatoren und die Operanden an: In diesem Fall ist es der Operand, und Sie haben zwei Operatoren, in diesem Fall * zum Dereferenzieren und ++ zum Erhöhen. Schritt 2, welcher hat die höhere Priorität? ++ hat höheren Vorrang vor * Hinweis: selbst wenn sie die GLEICHE Vorrangstellung haben, verbinden sie rechts mit links, wieder ist das ++ vor * Schritt 3 (der heikle Teil …) Wo ist ++ ? es steht auf der rechten Seite des Operanden, was bedeutet POST-Inkrement In diesem Fall macht sich der Compiler eine „geistige Notiz“, um das Inkrement auszuführen NACH es ist mit allen anderen Operatoren erledigt … Was bedeutet danach? Dies bedeutet, dass das Inkrement nur als allerallerletzter Schritt vor dem nächsten ‘;’ angewendet wird. so wird es mit allen anderen Operatoren gemacht, die sich in derselben ‘Zeile’ befinden. Hinweis: Wenn es *++p war, wird es VOR jedem anderen Operator in derselben Zeile ausgeführt, also ist es in diesem Fall gleichbedeutend mit dem Nehmen zwei der Register des Prozessors, eines enthält den Wert des dereferenzierten * p und das andere den Wert des inkrementierten p ++. Der Grund dafür, dass es in diesem Fall zwei gibt, ist die POST-Aktivität … Hier ist in diesem Fall es ist knifflig, und es sieht aus wie ein Widerspruch. Man würde erwarten, dass das ++ Vorrang vor dem * hat, was es auch tut, nur dass der POST bedeutet, dass es nur nach ALLEN anderen Operanden angewendet wird, VOR dem nächsten ‘;’ Zeichen…
Wie gesagt, der knifflige Teil ist, dass jedes Inkrement rechts von einem Operanden beiseite gelegt und als LETZTE Operation angewendet wird, bevor es zur nächsten Zeile weitergeht …
Da
*p++
ist das gleiche wie*(p++)
– Paul Tomblin
31. August 2012 um 19:25 Uhr
Operator Vorrang
– Chris
31. August 2012 um 19:25 Uhr
Probiere auch
void foo3(char **p) { (*p)++; }
– Michael Burr
31. August 2012 um 20:34 Uhr
Viel Spaß mit deinem netten Frageabzeichen 🙂
– Ricky Gummadi
12. Oktober 2012 um 3:49 Uhr