2010-01-08 14 views
35

skompilować i uruchomić ten kod w Cróżnice logiki w C i Java

#include <stdio.h> 

int main() 
{ 
    int a[] = {10, 20, 30, 40, 50}; 
    int index = 2; 
    int i; 

    a[index++] = index = index + 2; 
    for(i = 0; i <= 4; i++) 
    printf("%d\n", a[i]); 
} 

wyjściowa: 10 20 4 40 50

teraz za tą samą logiką w Javie

class Check 
{ 

    public static void main(String[] ar) 
    { 
    int a[] = {10, 20, 30, 40, 50}; 
    int index = 2; 

    a[index++] = index = index + 2; 
    for(int i = 0; i <= 4; i++) 
     System.out.println(a[i]); 
    } 
} 

wyjściowa: 10 20 5 40 50

Dlaczego występują różnice wyjściowe w obu językach, wyjście jest zrozumiałe lub Java ale nie rozumiem wyjścia w C

Jeszcze jedno, jeśli zastosujemy operator prefiksu ++, otrzymamy taki sam wynik w obu językach, dlaczego?

+17

ale kto napisałby taki kod (w prawdziwej aplikacji)? –

+0

@CarlosHeuberger Widzę, że nie jesteś przyzwyczajony do tagu 'C++ ' –

+0

@RyanHaining Nie rozumiem tego, ale komentarz był od 8 stycznia ** 2010 **, a pytanie nie zostało oznaczone tym razem jako' C++' . I nadal uważam, że 'a [index ++] = index = index + 2' nie jest dobry ani w C, C++, ani w Javie (Python?) - przez komentarze w górę głosów, wierzę, że nie jestem sam - czy też Znacznik C++ 'oznacza, że ​​kod może być nieczytelny (jak może być Code Golf?) I zobacz jedyną odpowiedź, także C jest trochę * zdezorientowana * o tym ... –

Odpowiedz

65

To dlatego a[index++] = index = index + 2; wywołuje zachowanie niezdefiniowane w C. Wystarczy popatrzeć na this

z linku:

..the zdanie drugie mówi: jeśli obiekt jest zapisywany wewnątrz pełne wyrażenie, każdy dostęp do niego w ramach tego samego wyrażenia musi być bezpośrednio zaangażowany w obliczanie wartości, która ma być zapisana. Ta zasada skutecznie ogranicza wyrażenia prawne do tych, w których dostępy w oczywisty sposób poprzedzają modyfikację. Na przykład stary tryb gotowości i = i + 1 jest dozwolony, ponieważ dostęp i jest używany do określenia wartości końcowej i. Przykład

a[i] = i++ 

jest niedozwolone, ponieważ jeden z dostępów od I (jeden w A [i]) nie ma nic wspólnego z wartością, która kończy się przechowywane w I (co zdarza się w i ++) , a więc nie ma dobrego sposobu, aby zdefiniować - dla naszego zrozumienia lub kompilatora - czy dostęp powinien mieć miejsce przed lub po zapisaniu zwiększonej wartości. Ponieważ nie ma dobrego sposobu, aby to zdefiniować, Standard deklaruje, że jest niezdefiniowany i że przenośne programy po prostu nie mogą używać takich konstrukcji. Podobny do a[i++]=i (który wywołuje UB) również twoje wyrażenie wywołuje UB.

Twoje wyrażenie ma również podobne zachowanie.

Zachowanie jest dobrze zdefiniowane w Java.

+0

jednak "a [indeks ++] = indeks + 2" (ten sam wynik, głównie) jest niezdefiniowany. Będę musiał sprawdzić standardy, aby być pewnym, szczerze mówiąc. –

+2

+1 .......... :) – missingfaktor

+2

@Michiel: Tak, to też byłby UB, z tego samego powodu. –

Powiązane problemy