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

C - указатели и разные результаты?

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

#include <stdio.h>

int main()
{
    char array[] = "123456789";
    char* ptr = array;

    printf("%c\n", *(ptr++));
    printf("%c\n", *ptr);

    *ptr = array[3];
    printf("%c\n", *(ptr++));
    printf("%c\n\n", *ptr);

    return 0;
}

Результат:

1
2
4
3
  • У меня есть указатель, который я назначаю array.

  • Затем я печатаю, что, по моему мнению, будет первым индексом ('2'), но вместо этого получим 1. - Итак, я предполагаю, что *(ptr++) фактически разыгрывает, прежде чем он увеличивает указатели.

  • Затем я переназначаю ptr 4-й индекс ('4') и повторю шаг 2. Это работает так, как ожидается, теперь, когда Я вижу, что C не вычисляет скобки сначала перед разыменованием.

  • Затем я печатаю новый приращенный ptr для отображения ('5')... и я получаю 3?

Как это, шаги 1 и 2 и 3 и 4 идентичны, но я получаю разные результаты?

4b9b3361

Ответ 1

Пропустите шаг за шагом:

Шаг 0:

char* ptr = array;

Наведите указатель на char на начало массива (а именно на позицию 0).

Шаг 1:

printf("%c\n", *(ptr++));

Разверните указатель в позиции 0, распечатайте там значение (1) и затем увеличите указатель на позицию 1

Шаг 2:

printf("%c\n", *ptr);

Разместите указатель в позиции 1 и распечатайте там значение (2)

Шаг 3:

*ptr = arr[3];

Разместите указатель в позиции 1 и обновить значение, на которое указывает значение в позиции 3 массива. Это значение 4.

Шаг 4:

printf("%c\n\n", *(ptr++));

Разделите указатель в позиции 1, распечатайте только что обновленное значение (4), а затем увеличьте указатель на позицию 2

Шаг 5:

printf("%c\n", *ptr);

Разместите указатель в позиции 2 и напечатайте там значение (3).

Возможно, вы намеревались иметь ptr = &arr[3];, который назначит указатель на новую позицию (а именно адрес arr[3]).

Обратите внимание, что фигурные скобки вокруг ptr в приведенном выше примере фактически избыточны из-за приоритета оператора.

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

Скобки также не нужны и для *(++ptr). Здесь, несмотря на то, что предварительный инкремент и косвенность имеют одинаковый приоритет, они оцениваются справа налево. И поэтому указатель будет увеличен до того, как он будет разыменован.

Ответ 2

Попробуйте это вместо:

ptr = array + 3;

Ответ 3

ptr++ - оператор post-increment, поэтому указатель увеличивает ПОСЛЕ, он разыскивает его (согласно стандарту).

Кроме того, шаг:

*ptr = array[3];

присваивает значение array[1] значение 4, поэтому вы печатаете 4 вместо 2 и увеличиваете до 3.

Ответ 4

  • * (ptr ++) продвигает указатель после разыменования. Если вы хотите получить второе значение в массиве, используйте *(++ptr).

  • Вы назначаете значение указателю. Фактически, вы меняете указатель (указывающий на второй элемент), указывая на 4. Вы вообще не меняете местоположение указателя. Таким образом, вы все еще печатаете второй элемент, за исключением того, что теперь оно имеет значение 4.

  • Вы переходите к 3-му элементу, печатаете 3.

Ответ 5

Правильный способ назначения указателя:

ptr = &array[3];

или

ptr = (array + 3);

Фактически вы присваиваете значение array[3] значению, указанному на ptr.