dúvida parece ser besta ... [RESOLVIDO]

galera tô com uma dúvida aqui parece até ser bestinha mas alguém por gentileza pode me explicar essa diferença de resultado, pois em C e Java é o mesmo código pra cada linguagem só que as saídas são diferentes:

Códgio em Java:

int x=10;

x = -x++;

System.out.printf("%d\n", x);

Saída: -10

Código em C:

    int x=10;
    
    x = -x++;
    printf("%d\n", x);

Saída: -9

obs: o código é exatamente esse mesmo não precisa usar parênteses nem nada não do jeito que tá aí!

obrigado,

abraços
:smiley:

tenta fazer isso e vê o que acontece:


x=-++x;

Por que?

C é C e Java é Java.

Ok, então a precedência dos operadores menos “-” e pós-incremento “++” em C e Java são diferentes, isso é válido. Interessante! :slight_smile:

Teste se é compilável e qual o resultado com o pré-incremento:x = -++x;

nesse caso

x = -++x;

a saída é a mesma pra Java e C onde ele irá executar primeiro negar e depois pre-incremento…

mas voltando ao assunto alguém sabe me dizer o pq???

obrigado,

abraços
:smiley:

Interessante. Me esclareceu bem tbm, já que sou iniciante.

Truques com “++” e “–” são típicos de professores que não passaram da primeira apostila de programação Java e não aprenderam o essencial, só as pegadinhas.

Tais professores, infelizmente, não são raros, e deveriam ser atirados ao fundo do mar, junto com aqueles escandalosos citados por Jesus:

Mas qualquer que escandalizar um destes pequeninos que crêem em mim, melhor lhe fora que se lhe pendurasse ao pescoço uma mó de azenha, e se submergisse na profundeza do mar.

É bom saber que tais coisas existem (acho que tais coisas, com pegadinhas, nem caem mais na prova de certificação), mas evite sempre escrever código que precise usar esses truques sujos. É por que ninguém que vai consertar seu código (incluindo você mesmo) vai acabar entendendo o que realmente está sendo feito.

bezier curve kkkkkk você é engraçado mas deixando as piadinhas de lado sempre é bom saber o pq dessas diferenças apesar desse código jamais seja programado desta forma. Mas a pergunta é a seguinte se Java se baseou no C++ que este tbm se baseou no C então existe um pq da diferença de resultados…

[quote=ppontes]bezier curve kkkkkk você é engraçado mas deixando as piadinhas de lado sempre é bom saber o pq dessas diferenças apesar desse código jamais seja programado desta forma. Mas a pergunta é a seguinte se Java se baseou no C++ que este tbm se baseou no C então existe um pq da diferença de resultados…
[/quote]

Sim, a razão é “porque não programaram igual”.
O pós e pré incremento não são exatamente um operadores matemático padrão.
Sua precedência é sujeita a interpretação ou, pior ainda, ao gosto de quem cria a linguagem.

Quanto ao que o beziér disse, só posso afirmar uma coisa: “Amém”.

desculpa ViniGodoy mas resposta como “porque não programaram igual” é a mesma coisa de “…vou responder qualquer coisa pra tirar esse cara de tempo…” só lembrando os operadores unários tanto em C e Java tem a mesma precedência e associatividade como podem ser programados diferentes??

Não, não.

Estou falando sério. Muitas das decisões são especificas de implementação.
Então, a razão é exatamente: “porque fizeram assim”.

Especialmente quando você usa um operador de atribuição, que recebe o valor de um pós incremento. Essa é operação que em C é considerada “undefined behavior” e, de fato, seu comportamento pode variar de compilador para compilador.

Nunca li em algum documento oficial de que Java que se é utilizado exatamente a mesma precedência que em C/C++. Provavelmente alguém com conhecimento (algum professor ou no fórum) falou que é a mesma precedência, mas certamente não é oficialmente e exatamente a mesma.

Esse tipo de programação não deve ser feito. Deveria-se utilizar parênteses ou duas atribuições, na ordem que preferir. O programador pode entender, mas quem dar manutenção não irá entender, o que vai acabar entrando na refatoração de código do sistema.

Ok. Vou te explicar a parte do “porque quiseram assim”.

Em Java, uma expressão como:
i = i++;

É interpretada da seguinte forma:

int valorAntigo = i; i = i + 1; i = valor antigo;

No C não existe uma definição clara do que isso pode fazer. Porém, na maior parte das implementações que conheço, isso será interpretado da seguinte forma:

i = i; i++;

Ou seja, no C, graças a sua política minimalista, fazem o que chamamos de “delayed increment”.

Entretanto, em c ou c++, receber o valor de uma variável que foi pós incrementada na própria variável é considerado um estilo pobre de programação, até porque, isso em C é um “undefined behavior”, o que quer dizer que o padrão não cobre esse caso em específico.

Então, não seria estranho encontrar compiladores que geram resultados iguais ao do Java. Ou mesmo, descobrir um compilador que gera resultados diferentes usando políticas diferentes de otimização (mais raro, porém, nada se garante em undefined behaviors).

Isso explica porque esse código imprime 0 em Java, e 1 em C:

int i = 0; i = i++; System.out.println(i);

Como falei anteriormente, não existe uma especificação matemática para o operador de “pós incremento”. Como ele não é parte da matemática padrão sua implementação está sujeita ao gosto ou entendimento do criador da linguagem ou do compilador.

Por isso simplesmente olhar para a tabela de precedência não diz muita coisa.

hum então seria isso o compilador escolherá a melhor forma de fazer ?? Ou seja dois compiladores de C distintos poderá ter resultados diferentes??

Sim. “undefined behavior” significa que não está especificado no padrão e, portanto, fica sujeito a interpretação de quem lê.
Aliás, essa não é a única operação desse tipo em C, várias outras podem gerar undefined behaviors.

Não é à toa que existe um tópico inteiro da wiki dedicado ao assunto:

Outro interessante que vi lá:

x[i] = i++;

Blz valeu pelos esclarecimentos ViniGodoy

[quote=dionat4n]…Esse tipo de programação não deve ser feito. Deveria-se utilizar parênteses ou duas atribuições, na ordem que preferir. O programador pode entender, mas quem dar manutenção não irá entender, o que vai acabar entrando na refatoração de código do sistema.
[/quote]
Pra isso existe comentário :slight_smile:
Mas o melhor mesmo é evitar esse tipo matemática pois não deverá ganhar nada fazendo isso além de código pouco usual (exceto se garantir-se uma possível otimização o q acho improvável).