2010-01-08 10 views
35

compilar y ejecutar el código en Cdiferencias lógicas en C y 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]); 
} 

Salida: 10 20 4 40 50

ya por la misma lógica en Java

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]); 
    } 
} 

Salida: 10 20 5 40 50

¿Por qué hay diferencia de salida en ambos idiomas, la producción es comprensible f o Java pero no puedo entender la producción en C

Una cosa más, si aplicamos el operador de prefijo ++, obtenemos el mismo resultado en ambos idiomas, ¿por qué?

+17

pero ¿quién escribiría un código como ese (en una aplicación real)? –

+0

@CarlosHeuberger Veo que no está acostumbrado a la etiqueta 'C++' –

+0

@RyanHaining No lo entiendo, pero el comentario fue del 8 de enero ** 2010 ** y la pregunta no fue etiquetada con 'C++' ese momento . Y todavía creo que 'a [index ++] = index = index + 2' no es bueno ni en C, C++ ni en Java (Python?) - por el comentario up-votes, creo que no estoy solo - o lo hace' La etiqueta C++ 'significa que el código puede ser ilegible (como Code Golf quizás?) Y, vea la única respuesta, también C está un poco * confundido * al respecto ... –

Respuesta

65

Eso se debe a que a[index++] = index = index + 2; invoca un comportamiento indefinido en C. Tenga una mirada en this

Desde el enlace:

..la segunda frase dice: si un objeto se escribe dentro de un completo expresión, todos y cada uno de los accesos dentro de la misma expresión deben estar directamente involucrados en el cálculo del valor que se escribirá. Esta regla efectivamente limita las expresiones legales a aquellas en las que los accesos preestablecen la modificación. Por ejemplo, se permite el viejo modo de espera i = i + 1, porque el acceso de i se usa para determinar el valor final de i. El ejemplo

a[i] = i++ 

no está permitido porque uno de los accesos de i (la de a [i]) no tiene nada que ver con el valor que termina siendo almacenado en i (que pasa por encima en i ++) , y entonces no hay una buena manera de definir, ya sea para nuestro entendimiento o para el del compilador, si el acceso debe tener lugar antes o después de que se almacene el valor incrementado. Como no existe una buena manera de definirlo, el Estándar declara que no está definido y que los programas portátiles simplemente no deben usar dichos constructos. Similar a a[i++]=i (que invoca UB) su expresión también invoca UB.

Su expresión también tiene un comportamiento similar.

El comportamiento está bien definido en Java.

+0

would 'a [index ++] = index + 2' (el mismo resultado, en su mayoría) no está definido. Tendría que buscar el estándar para estar seguro, para ser honesto. –

+2

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

+2

@Michiel: Sí, eso sería UB también, la misma razón. –

Cuestiones relacionadas