Подтвердить что ты не робот

Как увеличить адрес указателя и значение указателя?

Предположим, что

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

Что будет делать следующий код и как?

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

Я знаю, это довольно беспорядочно с точки зрения кодирования, но я хочу знать, что произойдет на самом деле, когда мы будем писать так.

Примечание. Предположим, что адрес a=5120300, он хранится в указателе p, адрес которого 3560200. Теперь, каково будет значение p & a после выполнения каждого оператора?

4b9b3361

Ответ 1

Во-первых, оператор ++ имеет приоритет над оператором *, а операторы() имеют приоритет над всем остальным.

Во-вторых, оператор ++number является таким же, как оператор number++, если вы не назначаете им что-либо. Разница заключается в number++ возвращает число, а затем увеличивает число, а ++number сначала увеличивает, а затем возвращает.

В-третьих, увеличивая значение указателя, вы увеличиваете его на sizeof его содержимого, то есть вы увеличиваете его, как если бы вы выполняли итерацию в массиве.

Итак, подведем итог:

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 accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get accessed, with your code, segfault

Поскольку здесь много дел, я, возможно, ошибся, пожалуйста, поправьте меня, если я ошибаюсь.

РЕДАКТИРОВАТЬ:

Таким образом, я был не прав, приоритет немного сложнее, чем то, что я написал, посмотрите здесь: http://en.cppreference.com/w/cpp/language/operator_precedence

Ответ 2

проверили программу, и результаты будут такими же,

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

Ответ 3

Что касается "Как увеличить адрес указателя и значение указателя?" Я думаю, что ++(*p++); на самом деле хорошо определен и делает то, о чем вы просите, например:

#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;
}

Он не меняет одну и ту же вещь дважды до точки последовательности. Я не думаю, что это хороший стиль, хотя для большинства применений - это слишком загадочно для меня.

Ответ 4

Ниже приводится описание различных предложений "просто распечатайте". Я нашел его поучительным.

#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;
}

Он возвращает

(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

Я передал адреса указателя int чтобы их можно было легко сравнить.

Я скомпилировал его с помощью GCC.

Ответ 5

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