движение указателя в чем разница между cs [1] и * cs ++ - PullRequest
3 голосов
/ 23 июня 2011

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

int cs={1,2,3};  

затем cs указывает на cs[0] что мне не понятно, так это то, на что указывает * cs.

#include<stdio.h>
int main()
{
        int array[] = { 1, 2, 3, 4, 5 };
        int *arrptr1 = array;
        int *arrptr = array;
        int i;
        for (i = 0; i < sizeof(array) / sizeof(int); i++) {
                printf("%d, %d, %d\n", array[i], *arrptr1++, *arrptr + i);
        }
}

вывод вышеуказанной программы

1, 1, 1
2, 2, 2
3, 3, 3
4, 4, 4
5, 5, 5

тогда мое понимание *arrptr должно увеличить значение, хранящееся в

*arrptr

должно быть увеличено на 1. Где, как я наблюдаю, указатель перемещается в следующее место. Просто хочу узнать, что не так в моем понимании?

UPDATE
Согласно ответам ниже, я понимаю, что

print("%d", *arrptr1++);

в таком утверждении оценка операторов производится справа налево. Следовательно, в *arrptr1++ сначала будет оцениваться ++, а затем arrptr, а затем * Таким образом, чтобы подтвердить то же самое, я написал другую программу

#include<stdio.h>
int main()
{
        int array[] = { 10, 20, 30, 40, 50 };
        int *q1 = array;
        printf("q1 = %p\n",q1);
      printf("*q1++ = %d\n",*q1++);
        printf("q1 = %p\n",q1);
      printf("*q1++ = %d\n",*q1);
}

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

q1 = 0x7ffffcff02e0
*q1++ = 10
q1 = 0x7ffffcff02e4
*q1++ = 20

Так что я ожидал во 2-й строке вывода вместо *q1++ = 10 после *q1++ = 20 так что приоритет оператора не произошел справа налево?

Ответы [ 4 ]

2 голосов
/ 23 июня 2011

Всякий раз, когда вы используете оператор разыменования * и оператор пре-инкремента (пре-декремент) или пост-инкремент (пост-декремент) для переменной одновременно, порядок операций справа налево (если скобки не используются).

То, что вы хотите сделать, это (*arrptr)++

из-за более высокого приоритета (), он заставит компилятор сначала получить доступ к элементу, на который указывает arrptr, а затем увеличить его значение. Когда вы делаете это *arrptr++, как я уже сказал, сначала работает самый правый оператор (т.е. ++) а затем оператор разыменования. Если напишешь

РЕДАКТИРОВАНИЕ (только комментарий): *++arrptr // increment the pointer then access

сначала он продвинет указатель, а затем получит доступ к значению хранится в адресе, указанном arrptr. Еще одна вещь, запятая, используемая для разделения аргументов функции, не является оператором запятой, поэтому порядок вычисления аргументов не определен. (уже сказано)

2 голосов
/ 23 июня 2011

*arrptr1++ анализируется как *(arrptr1++), а не (*arrptr1)++.

0 голосов
/ 23 июня 2011

cs = & cs [0] (cs равен адресу cs sub 0); * cs = cs [0] (указатель cs равен cs sub 0); Вы должны помнить, что * скрывает [].

    // here is a print function with a pointer
    int foo[5] = { 2, 9, 1, 3, 6};
    int *walker, count;

    walker = foo;

    for (count = 0; count < 5; walker++, count++)
        printf("Array[%d]: %d\n", count, *walker);

Повтор: уокер равен & foo [0], поэтому, когда вы увеличиваете уокер (например, уокер ++), вы перемещаете указатель на следующий адрес, который является foo [1]. И когда мы печатаем значение, мы не можем сказать ..., Уокер); поскольку walker (& foo [что угодно]) указывает на адрес, нам нужно разыменовать указатель, чтобы получить значение. Опять же, самое важное, что нужно помнить

array = &array[0] AND *array = array[0]
0 голосов
/ 23 июня 2011

В результате *arrptr1++ интерпретируется как *(arrptr1++), что означает, что указатель на массив увеличивается на единицу каждый раз в цикле, и, следовательно, он будет указывать на тот же элемент, что и array[i].*arrptr + i с другой стороны интерпретируется как « значение элемента массива, на которое указывает arrptr плюс целое число i».В этом цикле это означает, что он будет отображать то же самое, что и array[i], но он не указывает на один и тот же элемент (arrptr всегда указывает на первый элемент в вашем массиве).Если вы измените значения в массиве на что-то более случайное, это должно быть очевидно при повторном запуске программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...