2013-07-07 15 views
6

biegnę następujące programy w Visual C++ i Java:Zachowanie PreIncrement and PostIncrement operatora w C i Java

Visual C++

void main() 
{ 
    int i = 1, j; 
    j = i++ + i++ + ++i; 
    printf("%d\n",j); 
} 

wyjściowa:

6 

Java:

public class Increment { 
    public static void main(String[] args) { 
     int i = 1, j; 
     j = i++ + i++ + ++i; 
     System.out.println(j); 
    } 
} 

wyjściowa:

7 

Dlaczego wyjście w tych dwóch językach są różne? Jak oba języki traktują inaczej operatorów przed i po cynkowaniu?

+0

W językach C i C++ kolejność, w jakiej wyrażenia są oceniane, oraz kolejność, w jakiej stosowane są efekty uboczne, są * nieokreślone *; wynik będzie się różnić od wdrożenia do wdrożenia. Odpowiednie standardy pozostawiają takie zachowanie * niezdefiniowane *, aby implementator kompilatora nie musiał się martwić o sposób obsługi takich wyrażeń; dowolny wynik jest uważany za "prawidłowy". Java i C#, OTOH, określają, że wszystkie wyrażenia są oceniane od lewej do prawej i że wszystkie efekty uboczne są stosowane natychmiast, więc takie wyrażenia są dobrze zdefiniowane. –

Odpowiedz

2

C/C++ Zachowanie jest nieokreślona, ​​ponieważ w tym wyrażeniu i jest modyfikowany więcej niż jeden raz bez pośredniego punktu sekwencji. przeczytaj: What's the value of i++ + i++?

Oczywiście w Java zachowanie this kind of codes jest dobrze zdefiniowane. Poniżej znajduje się moja odpowiedź dla języka Java, krok po kroku:

Na początku i jest 1.

j = i++ + i++ + ++i; 
// first step, post increment 
j = i++ + i++ + ++i; 
// ^^^ 
j = 1 + i++ + ++i; 
// now, i is 2, and another post increment: 
j = i++ + i++ + ++i; 
// ^^^^^^^^^ 
j = 1 + 2 + ++i; 
// now, i is 3 and we have a pre increment: 
j = i++ + i++ + ++i; 
// ^^^^^^^^^^^^^^^^ 
j = 1 + 2 + 4; 
j = 7; 
+0

twoja odpowiedź jest bardzo dobra dla Java, dodałem dla c w twojej odpowiedzi, jeśli nie lubisz powrotu do swojej wersji. –

4

Przykład C++ wywołuje niezdefiniowane zachowanie. Nie wolno modyfikować wartości więcej niż raz w wyrażeniu. między punktami sekwencji. [Edytowany w celu uzyskania większej precyzji.]

Nie jestem pewien, czy to samo dotyczy Javy. Ale z pewnością jest to prawda w C++.

Oto dobre odniesienie:
Undefined behavior and sequence points

+1

cytat, proszę? Nigdy o tym nie słyszałem ... tylko, że nie było to zalecane. – Mgetz

+0

@Mgetz: Edytowane powyżej, aby dodać ostateczne odniesienie. Przewiń w dół do "1) Pomiędzy poprzednim a następnym punktem sekwencji, obiekt skalarny będzie miał co najmniej jedną zmianę wartości zapamiętanej przez ocenę wyrażenia." –