wake-up-neo.com

Wie kann man die Zeigeradresse und den Zeigerwert erhöhen?

Lasst uns annehmen,

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

Was macht der folgende Code eigentlich und wie? 

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

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

Anmerkung: Nehmen wir an, dass die Adresse von a=5120300 im Zeiger p gespeichert ist, dessen Adresse 3560200 ist. Wie lautet der Wert von p & a nach der Ausführung jeder Anweisung?

70
Dinesh

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

Zweitens ist der ++ number-Operator der gleiche wie der number ++ -Operator, wenn Sie ihn keinem Objekt zuweisen. Der Unterschied ist number ++ gibt number zurück und erhöht dann number und ++ number erhöht sich zuerst und gibt sie dann zurück.

Drittens, indem Sie den Wert eines Zeigers erhöhen, erhöhen Sie ihn um die Größe seines Inhalts, das heißt, Sie erhöhen ihn so, als würden Sie in einem Array iterieren.

Um es 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 of ptr is incremented
++(*ptr); // The value of ptr is incremented
++*(ptr); // The value of 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 of 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, habe ich vielleicht einen Fehler gemacht. Bitte korrigieren Sie mich, falls ich falsch liege.

BEARBEITEN:

Also habe ich mich geirrt, der Vorrang ist etwas komplizierter als das, was ich geschrieben habe, hier ansehen: http://en.cppreference.com/w/cpp/language/operator_precedence

123
felipemaia

das Programm überprüft und die Ergebnisse sind wie,

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
9
Sujith R Kumar

In Bezug auf "Wie erhöht man eine Zeigeradresse und den Zeigerwert?" Ich denke, dass ++(*p++); tatsächlich gut definiert ist und das tut, wonach Sie fragen, z.

#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 wird nicht zweimal dasselbe vor einem Sequenzpunkt geändert. Ich denke nicht, dass es für die meisten Anwendungen ein guter Stil ist - es ist ein bisschen zu kryptisch für meinen Geschmack.

3
Flexo

Das Folgende ist eine Instantiierung der verschiedenen "Just-It-It-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

Die Zeigeradressen werden in ints umgewandelt, damit sie leicht verglichen werden können.

Ich habe es mit GCC kompiliert.

2
Rico Picone
        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);
0
Abhishek D K