Warum unterscheidet sich *p++ von *p += 1?

Lesezeit: 4 Minuten

Jacks Benutzeravatar
Jack

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?

  • 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

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).

  • Sie haben es so gut erklärt, aber könnten Sie bitte ein Detail hinzufügen? abhängig von Implementierungsspezifikationen.

    – Edwin Buck

    31. August 2012 um 19:27 Uhr

  • @EdwinBuck: Ich sehe die Relevanz nicht wirklich, das ist nur eine normale Zeigerarithmetik und nicht der Schwerpunkt der Frage.

    – GManNickG

    31. August 2012 um 19:29 Uhr

  • @EdwinBuck, ob ein Zeiger ein int oder ein char ist, wenn Sie ihn erhöhen, wird er um eins erhöht. Die tatsächliche Adresse, die diesen Zeiger darstellt, kann sich jedoch aufgrund der Größe des Zeigers um mehr als ein Byte ändern.

    – Richard J.Ross III

    31. August 2012 um 19:30 Uhr

  • @RichardJ.RossIII Wir haben beide Recht, aber wir sprechen über verschiedene Einsen. Eine Einheit bzw sizeof(*p) ist immer noch eine 1 in irgendeiner Skala, aber wenn Sie sich den darin gespeicherten Binärwert ansehen p Der tatsächliche Wert wird in der Binärarithmetik nicht immer “+1” sein.

    – Edwin Buck

    31. August 2012 um 19:41 Uhr

  • Die Darstellung des Zeigers, der in vielen C-Implementierungen die einfache Speicheradresse ist, sollte nicht mit seinem Wert verwechselt werden, der seine Bedeutung im C-Kontext hat. p++ erhöht den Wert um eins. Seine Auswirkung auf die Darstellung dieses Werts ist für die Zwecke dieser Frage ebenso irrelevant wie das Hinzufügen von 1 zum Float 1.f ändert typischerweise die Darstellung um 8.388.608.

    – Eric Postpischil

    31. August 2012 um 20:10 Uhr

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.

Benutzeravatar von G. Simsic
G. Simsic

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 …

1408670cookie-checkWarum unterscheidet sich *p++ von *p += 1?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy