2013-07-16 1 views
3

Пожалуйста, обратите внимание на следующее заявление:Разница в операторе инкремента-декремента в C и JAVA

int a[]={1,2,3,4,5,6,7,8}; 
int i=0,n; 
n=a[++i] + i++ + a[i++] + a[i] ; 

Согласно моей логике п должно быть 10. Но я получаю различный результат в с (выход 7) Однако в java Я получаю ожидаемый результат, который равен 10. Есть ли разница в том, как работают операторы приращения и декремента в c и java.

Вот моя точная с и Java-код:

  #include <stdio.h> 
      int main() 
      { 
       int a[]={1,2,3,4,5,6,7,8}; 
       int i=0,n; 
       n=a[++i] + i++ + a[i++] + a[i] ; 
       printf("%d",n); 
       getch(); 
       return 0; 
      } 

Java код с выхода: 10

public class HelloWorld{ 

    public static void main(String []args){ 

     int a[]={1,2,3,4,5,6,7,8}; 
     int i=0,n; 
     i=0; 
     n=a[++i] + i++ + a[i++] + a[i] ; 
     System.out.println(n); 
    } 
} 
+3

Дизайнеры Java решили точно определить результаты для всех случаев приращения и т. Д., Хотя JLS рекомендует избегать множественных побочных эффектов в одном утверждении. Стандарты C++ оставляют некоторые случаи неопределенными. –

+0

Вы имеете в виду, что причина, по которой результат равен 7, а не 10, называется так называемым «неопределенным поведением c». Фактически ответ может быть равен 7, если вы оцениваете выражение справа налево, а не слева направо. Вы уверены, что это не имеет никакого отношения к ассоциативности операторов. –

+0

@PatriciaShanahan –

ответ

2

В отношении C от c99draft standard6.5.2:

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

это приводит следующие примеры кода, как быть определено:

i = ++i + 1; 
a[i++] = i; 

Секция такое же в draft 2011 standard как хорошо, но он читает немного более неудобно. Это хорошая ссылка на sequence point.

Раздел 15.7 является соответствующий раздел из JLS:

гарантирует язык программирования Java, что операнды операторов, как представляется, оцениваются в определенном порядке оценки, а именно, слева направо.

Настоятельно рекомендуется, чтобы код не основывался на этой спецификации. Код обычно более четкий, если каждое выражение содержит не более одного побочного эффекта.

3

В C, это неопределенное поведение. Поскольку C не гарантирует порядок оценки отдельной операции в выражении.

+0

На самом деле ответ может быть 7, если вы оцениваете выражение справа налево, а не слева направо. Вы уверены, что это не имеет никакого отношения к ассоциативности операторов. –

+0

Есть ли что-нибудь, что мне нужно помнить, в частности, о порядке оценки выражения в c (где я могу найти некоторые четко определенные правила, если они есть?) –

+3

@AbhasTandon. Вы не можете. Вот почему это называется неопределенным поведением. В общем, вам следует избегать изменения одной и той же переменной более одного раза в одном выражении. –

2

Чтобы добавить ответ Рохита, если вы выполните каждый из шагов отдельно, дается ответ 10. Это просто подчеркивает, что выполнение i++ и ++i может не происходить в том порядке, в котором аргументы добавляются к значению n.

#include <stdio.h> 
int main() 
{ 
    int a[]={1,2,3,4,5,6,7,8}; 
    int i=0,n; 
    n=a[++i] + i++ + a[i++] + a[i] ; 
    printf("%d\n",n); 

    i=0; 
    n=0; 
    n=a[++i]; 
    printf("%d\n",n); 
    n+=i++; 
    printf("%d\n",n); 
    n+=a[i++]; 
    printf("%d\n",n); 
    n+=a[i]; 
    printf("%d\n",n); 
    return 0; 
} 
Смежные вопросы