2015-07-28 7 views
0
#include <stdio.h> 

int main(void) 
{ 
    int i; 
    int *p = (int *) malloc(5 * sizeof(int)); 

    for (i=0; i<10; i++) 
     *(p + i) = i; 

    printf("%d ", *p++); 
    return 0; 
} 

Итак, я запустил этот код. Теперь мне сказали, что Why won't the output be 4 in this case? (в принятом ответе), что *p++ будет увеличивать указатель сначала, а затем разыгрывать его. Поэтому в приведенном выше коде не следует сначала увеличивать указатель, а затем де-ссылку и, следовательно, вывод должен быть 1? Вместо этого выход выходит 0. Зачем?Почему вывод `0` в этом случае?

+0

Пожалуйста, посмотрите, почему бы не использовать] (http://stackoverflow.com/q/605845/2173917) возвращаемое значение 'malloc()' и family в 'C'. –

+1

Ответы, приведенные в вышеприведенном сообщении, в основном говорят о том, что мы должны написать ненужный код, как это имеет отношение к моему вопросу? –

+1

вам нужно '#include ' – BLUEPIXY

ответ

4

Вы получили часть право старшинства, но давайте посмотрим на оператора собственности приращения постфикса, мы?

C11 стандарт говорит в главе §6.5.2.4, Постфиксные инкремента и декремента

Результат оператора постфикса ++ это значение операнда. В качестве побочного эффекта добавляется значение объекта операнда (то есть к нему добавляется значение 1 соответствующего типа). [...]

Таким образом, сам переменный будет опыт эффект приращения, но заявление, в котором переменное присутствуют (с приращением постфикса) будет помогло существующего значения переменная, а не добавочное значение. Приращение будет выполнено как побочный эффект в более поздней части.

3

Это утверждение

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

выполняет следующие действия:

  1. де-ссылка ptr, что приводит к значению ptr[0]
  2. распечатать int шаг 1 принимает значение, то есть ptr[0]
  3. приращение ptr, поэтому он указывает на ptr[1]

Чтобы распечатать ptr[1] использование:

printf("%d ", *++ptr); 
+1

Не думаете ли вы, что '* p ++' будет рассматриваться как '* (p ++)'? Поскольку '++' и '*' имеют одинаковый приоритет, а ассоциативность будет справа налево. – ameyCU

+0

@ameyCU: Короче говоря: Нет. Длительная причина здесь (из C11Draft 6.5.2.4/2): «* Результатом оператора postfix ++ является значение операнда. В качестве побочного эффекта значение объект операнда увеличивается (то есть значение 1 соответствующего типа добавляется к нему ). См. обсуждения аддитивных операторов и составное назначение для информации об ограничениях, типах и преобразованиях и эффектах операций над указателями . Вычисление значения результата секвенируется перед побочным эффектом , обновляющим сохраненное значение операнда. * «Ключевое слово здесь:« * побочный эффект * » – alk

+0

@ameyCU: Вы правы в отношении результата, но фактически постфикс-операторы (включая приращение) имеют * более высокий * приоритет, чем унарные операторы (например, разыменование). – EOF

1

Обратите внимание, что после приращения. Таким образом, возвращаемое значение оператора postfix ++ является значением самого операнда, а затем как побочный эффект , значение объекта операнда увеличивается.

Выражение *ptr++ будет

  1. *ptr
  2. использовать значение *ptr, как printf("%d ", *ptr);
  3. ptr = ptr + 1

Выход таких выражений может быть понято:

  1. Приоритет префикс ++ и * такой же. Ассоциативность обоих составляет справа налево.
  2. Приоритет постфикса ++ выше, чем * и префикс ++. Ассоциативность postfix ++ is Слева направо.

Следовательно, в приведенном выше коде не следует сначала увеличивать указатель, а затем отменять привязку и, следовательно, выход должен быть равен 1?

Используйте для этого требования следующие:

printf("%d ", *++ptr); 
0

Во-первых, вы должны добавить #include <stdlib.h>. Во-вторых, вы должны исправить свой код int *p = (int *) malloc(10 * sizeof(int));. Затем *p++ обозначает 1. printf *p; 2. p++. Если вы хотите получить значение 1, вы должны использовать код printf("%d ", *++p);. Я надеюсь это тебе поможет.

 Смежные вопросы

  • Нет связанных вопросов^_^