Wie inkrementiere ich eine Zeigeradresse und einen Zeigerwert?

Lesezeit: 7 Minuten

Dineshs Benutzeravatar
Dinesh

Lasst uns annehmen,

int *p;
int a = 100;
p = &a;

Was wird der folgende Code tatsächlich tun und wie?

p++;
++p;
++*p;
++(*p);
++*(p);
*p++;
(*p)++;
*(p)++;
*++p;
*(++p);

Ich weiß, das ist etwas chaotisch in Bezug auf die Codierung, aber ich möchte wissen, was tatsächlich passiert, wenn wir so codieren.

Hinweis: Nehmen wir an, dass die Adresse von a=5120300es wird im Zeiger gespeichert p dessen Adresse ist 3560200. Nun, was wird der Wert von sein p & a nach der Ausführung jeder Anweisung?

  • Warum führst du es nicht einfach im Debugger aus?

    – AndersK

    21. November 2011 um 6:27 Uhr

  • Naja.. warum nicht einfach Versuchen es und sehen? printf gibt einen Zeiger mit %p aus

    – Brian Roach

    21. November 2011 um 6:29 Uhr


  • Wenn Sie neugierig auf das Verhalten sind, spielen Sie einfach damit herum. Schreiben Sie einfach ein einfaches C-Programm, das all diese Anwendungsfälle durchgeht, und prüfen Sie, ob es für Sie sinnvoll ist.

    – Cyrus

    21. November 2011 um 6:36 Uhr

  • @AndersK. Vielleicht erwartet das OP undefiniertes Verhalten? …Oder vielleicht nicht.

    – Mateen Ulhaq

    21. November 2011 um 6:39 Uhr

Benutzeravatar von felipemaia
Felipemaia

Erstens hat der ++-Operator Vorrang vor dem *-Operator, und die ()-Operatoren haben Vorrang vor allem anderen.

Zweitens ist der ++number-Operator derselbe wie der number++-Operator, wenn Sie ihm nichts zuweisen. Der Unterschied ist, dass Zahl++ Zahl zurückgibt und dann Zahl erhöht, und ++Zahl zuerst erhöht und dann zurückgibt.

Drittens: Indem Sie den Wert eines Zeigers erhöhen, erhöhen Sie ihn um die Größe seines Inhalts, dh Sie erhöhen ihn, als ob Sie in einem Array iterieren würden.

Also, um das Ganze zusammenzufassen:

ptr++;    // Pointer moves to the next int position (as if it was an array)
++ptr;    // Pointer moves to the next int position (as if it was an array)
++*ptr;   // The value pointed at by ptr is incremented
++(*ptr); // The value pointed at by ptr is incremented
++*(ptr); // The value pointed at by ptr is incremented
*ptr++;   // Pointer moves to the next int position (as if it was an array). But returns the old content
(*ptr)++; // The value pointed at by ptr is incremented
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content
*++ptr;   // Pointer moves to the next int position, and then get's accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault

Da es hier viele Fälle gibt, könnte ich einen Fehler gemacht haben, bitte korrigieren Sie mich, wenn ich falsch liege.

BEARBEITEN:

Also habe ich mich geirrt, die Präzedenz ist etwas komplizierter als das, was ich geschrieben habe, sehen Sie es hier:
http://en.cppreference.com/w/cpp/language/operator_precedence

  • *ptr++, der Wert wird nicht erhöht, der Zeiger schon. Diese unären Operatoren haben denselben Vorrang, werden aber von rechts nach links ausgewertet. Der Code bedeutet “Nehmen Sie den Inhalt, auf den ptr zeigt, und erhöhen Sie dann ptr”. Es ist sehr verbreiteter C-Code (und ja, ziemlich verwirrend). Bitte korrigieren Sie dies und ich werde die Ablehnung entfernen. Gleiches gilt für *(ptr)++, die Klammer macht nichts.

    – Ludin

    21. November 2011 um 7:43 Uhr

  • Vielen Dank Lundin, habe ich noch etwas verpasst?

    – Felipemaia

    21. November 2011 um 15:03 Uhr

  • @Lundin Hallo, ist die obige Antwort jetzt korrigiert? Vielen Dank.

    – Unheilig

    11. März 2014 um 22:51 Uhr

  • @Unheilig Der erste Satz ist immer noch völlig falsch, Postfix ++ hat Vorrang vor unary *, das den gleichen Vorrang wie Präfix ++ hat. Abgesehen davon scheint es ok zu sein.

    – Ludin

    12. März 2014 um 7:19 Uhr

  • @felipemaia Bist du sicher, dass es einen Segfault geben wird? Vielleicht ist es nur undefiniertes Verhalten?

    – Jotik

    21. April 2016 um 10:59 Uhr

Benutzeravatar von Sujith R Kumar
Sujith R. Kumar

überprüft das Programm und die Ergebnisse sind wie folgt:

p++;    // use it then move to next int position
++p;    // move to next int and then use it
++*p;   // increments the value by 1 then use it 
++(*p); // increments the value by 1 then use it
++*(p); // increments the value by 1 then use it
*p++;   // use the value of p then moves to next position
(*p)++; // use the value of p then increment the value
*(p)++; // use the value of p then moves to next position
*++p;   // moves to the next int location then use that value
*(++p); // moves to next location then use that value

  • @alex verwenden bedeutet zum Beispiel, Anweisung berücksichtigen, ‘int *a = p++;’ Hier wird der erste Wert des Zeigers ‘p’ verwendet und danach bewegt sich p zur nächsten Position. Nach der Ausführung der obigen Anweisung wird also “a” auf die Adresse des vorherigen Ortes zeigen, auf den “p” zeigt, und “p” zeigt auf die nächste Position. Das heißt, verwenden Sie zuerst den Wert von ‘p’ für den Zuweisungsausdruck wie oben und erhöhen Sie dann den Wert von ‘p’, um auf die nächste Position zu zeigen

    – Sujith R. Kumar

    23. Juni 2015 um 14:49 Uhr

  • Kurz gesagt, ich denke, er verwendet den Ausdruck “use it” für den formelleren Begriff “assign”. Das ist alles.

    – Apekshik Panigrahi

    2. März 2019 um 15:34 Uhr

Benutzeravatar von Rico Picone
Rico Picone

Das Folgende ist eine Instanziierung der verschiedenen “Einfach drucken”-Vorschläge. Ich fand es lehrreich.

#include "stdio.h"

int main() {
    static int x = 5;
    static int *p = &x;
    printf("(int) p   => %d\n",(int) p);
    printf("(int) p++ => %d\n",(int) p++);
    x = 5; p = &x;
    printf("(int) ++p => %d\n",(int) ++p);
    x = 5; p = &x;
    printf("++*p      => %d\n",++*p);
    x = 5; p = &x;
    printf("++(*p)    => %d\n",++(*p));
    x = 5; p = &x;
    printf("++*(p)    => %d\n",++*(p));
    x = 5; p = &x;
    printf("*p++      => %d\n",*p++);
    x = 5; p = &x;
    printf("(*p)++    => %d\n",(*p)++);
    x = 5; p = &x;
    printf("*(p)++    => %d\n",*(p)++);
    x = 5; p = &x;
    printf("*++p      => %d\n",*++p);
    x = 5; p = &x;
    printf("*(++p)    => %d\n",*(++p));
    return 0;
}

Es kehrt zurück

(int) p   => 256688152
(int) p++ => 256688152
(int) ++p => 256688156
++*p      => 6
++(*p)    => 6
++*(p)    => 6
*p++      => 5
(*p)++    => 5
*(p)++    => 5
*++p      => 0
*(++p)    => 0

Ich wende die Zeigeradressen an ints, damit sie leicht verglichen werden können.

Kompiliert habe ich es mit GCC.

  • Ich würde dies ändern, um den Wert von x und p nach der Operation einzubeziehen.

    – NetJohn

    16. März 2018 um 18:50 Uhr

In Bezug auf “Wie inkrementiere ich eine Zeigeradresse und einen Zeigerwert?” ich denke, dass ++(*p++); ist eigentlich gut definiert und macht das, wonach Sie fragen, zB:

#include <stdio.h>

int main() {
  int a = 100;
  int *p = &a;
  printf("%p\n",(void*)p);
  ++(*p++);
  printf("%p\n",(void*)p);
  printf("%d\n",a);
  return 0;
}

Es ändert nicht zweimal dasselbe vor einem Sequenzpunkt. Ich denke jedoch nicht, dass es für die meisten Zwecke ein guter Stil ist – es ist ein wenig zu kryptisch für meinen Geschmack.

Benutzeravatar von Abhishek DK
Abhishek DK

        Note:
        1) Both ++ and * have same precedence(priority), so the associativity comes into picture.
        2) in this case Associativity is from **Right-Left**

        important table to remember in case of pointers and arrays: 

        operators           precedence        associativity

    1)  () , []                1               left-right
    2)  *  , identifier        2               right-left
    3)  <data type>            3               ----------

        let me give an example, this might help;

        char **str;
        str = (char **)malloc(sizeof(char*)*2); // allocate mem for 2 char*
        str[0]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char
        str[1]=(char *)malloc(sizeof(char)*10); // allocate mem for 10 char

        strcpy(str[0],"abcd");  // assigning value
        strcpy(str[1],"efgh");  // assigning value

        while(*str)
        {
            cout<<*str<<endl;   // printing the string
            *str++;             // incrementing the address(pointer)
                                // check above about the prcedence and associativity
        }
        free(str[0]);
        free(str[1]);
        free(str);

  • Was ist Assoziativität?

    – 71GA

    4. Februar 2020 um 5:20 Uhr

  • im Code sehen Sie *str++, jetzt haben hier sowohl * als auch ++ dieselbe Priorität (gleiche Priorität in Laiensprache) und auch *str++ werden nicht durch Klammern wie *(str++) oder (*str)++ getrennt, also es wird notwendig, wie es zu bewerten ist. also von rechts nach links bedeutet ( x = str++) und dann (y = *x)

    – Abhishek DK

    4. Februar 2020 um 8:49 Uhr


  • Was ist Assoziativität?

    – 71GA

    4. Februar 2020 um 5:20 Uhr

  • im Code sehen Sie *str++, jetzt haben hier sowohl * als auch ++ dieselbe Priorität (gleiche Priorität in Laiensprache) und auch *str++ werden nicht durch Klammern wie *(str++) oder (*str)++ getrennt, also es wird notwendig, wie es zu bewerten ist. also von rechts nach links bedeutet ( x = str++) und dann (y = *x)

    – Abhishek DK

    4. Februar 2020 um 8:49 Uhr


1422700cookie-checkWie inkrementiere ich eine Zeigeradresse und einen Zeigerwert?

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

Privacy policy