поведение printf - PullRequest
       31

поведение printf

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

Взять int ptr={10,20,30,40,50} Я понимаю, что

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

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

#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

но я ожидал

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

так что приоритет оператора не произошел справа налево? Или в моем понимании что-то не так?

ОБНОВЛЕНИЕ

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

#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++));// note the braces here *(q1++) so that () get evaluated 
        printf("q1 = %p\n",q1);
      printf("*q1++ = %d\n",*q1);
}

Результат все тот же, обратите внимание на использование скобок, как вы упомянули. Тем не менее вывод

q1 = 0x7fff043f2120
*q1++ = 10 <-- I expected *q1++ = 20//since I used braces ()
q1 = 0x7fff043f2124
*q1++ = 20

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

Ответы [ 4 ]

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

Нет, операторы не оцениваются справа налево. Существует таблица приоритетов операторов , которая дает порядок.

Однако это не причина поведения, которое вы видите. Причина в том, что вы используете оператор после увеличения , что означает, что в *q1++ разыменование указателя происходит со значением, которое q1 имело до сложения.

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

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

++ справа возвращает значение перед оценкой.

printf("*q1++ = %d\n",*q1++);

совпадает с

printf("*q1++ = %d\n",*q1);
++q1;
1 голос
/ 23 июня 2011

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

x = * q ++;

- то же самоекак:

x = *q;
++q;

Эквивалент предварительного приращения:

x = *++q;

, который будет:

++q;
x = *q;
1 голос
/ 23 июня 2011

Оператор *ptr++; будет оценивать значение, на которое сначала указывает ptr, а , а затем , увеличивать ptr. Для увеличения сначала используйте *++ptr;.

...