Ordem de Precedência

9 respostas
sidney.tavares
[RESOLVIDO]Boa tarde a todos os participantes, estou em fase de aprendizado, testei o código abaixo:
[list]
public class Operacoes extends Object{
	
	public void calculos(){
		int x = 10;
		int y = 9;
		
		double resultado = ((((x + y)* y )/ x) - y) % 3;
		System.out.println("Resultado : " + resultado);
	}
	public void operadoresUnarios(){
		int x= 1;
		int y = 1;
		int k = 10;
		int z = 10;
		
		for (int m = 0; m < 5; m++){
			System.out.println("USando o valor de x antes e incrementando depois");
			System.out.println(x++);
			System.out.println("Usando o valor de k antes de decrementá-lo => "+(k--));
		}
	}
	
	public void operadoresRelacionais(){
		int x = 10;
		int y = 9;
		
		if (x > y){
			System.out.println("X maior que Y  ");
		}
		if ( x != y){
			System.out.println("X diferente de Y ");
		}
		//outra forma de if, se x > y então k recebe 3, senão k recebe 7
		
		float k = x > y ? 3 : 7;
		System.out.println("Valor de k => "+ k);
		
		if ( 4 == 4){
			System.out.println("4 igual a 4 ");
		}
	}
	public void operacoesAtribuicao(){
		int x = 10;
		
		System.out.println("Valor Original => " + x);
		x += 10;
		System.out.println("Valor após soma com atribuição => " + x);
		x -= 5;
		System.out.println("Valor após subtração com atribuição => " + x);
		x *= 5;
		System.out.println("Valor após multiplicação com atribuição => " + x);
		x /= 5;
		System.out.println("Valor após divisão com atribuição => " + x);
	}
	
	public static void main (String args []){
		Operacoes o = new Operacoes ();
		o.calculos();
		o.operadoresUnarios();
		o.operadoresRelacionais();
		o.operacoesAtribuicao();
	}
}
[/list]

E ele me retornou o seguinte resultado:

[list]
Resultado : 2.0
USando o valor de x antes e incrementando depois
1
Usando o valor de k antes de decrementá-lo => 10
USando o valor de x antes e incrementando depois
2
Usando o valor de k antes de decrementá-lo => 9
USando o valor de x antes e incrementando depois
3
Usando o valor de k antes de decrementá-lo => 8
USando o valor de x antes e incrementando depois
4
Usando o valor de k antes de decrementá-lo => 7
USando o valor de x antes e incrementando depois
5
Usando o valor de k antes de decrementá-lo => 6
X maior que Y
X diferente de Y
Valor de k => 3.0
4 igual a 4
Valor Original => 10
Valor após soma com atribuição => 20
Valor após subtração com atribuição => 15
Valor após multiplicação com atribuição => 75
Valor após divisão com atribuição => 15
[/list]

Porém, mais do que não dar erro eu gostaria de entender alguns resultados, na linha 8 do código o resultado foi 2.0, como há uma série de parênteses nesta linha gostaria de entender como o cálculo foi feito, e tenho dúvidas se os resultados que retornaram para os decrementos e incrementos estão corretos, tenho estudado bastante e as coisas começam a ficar mais claras, mas ainda tenho dificuldade com os conceitos e com alguns resultados que retornam, se alguém tiver um tempo de analisar e puder me esclarecer principalmente a questão das precedências eu agradeço desde já. Abraços a todos.

9 Respostas

M

A expressão é avaliada como seria matematicamente. Primeiro o que está dentro dos parênteses mais internos (“de dentro para fora”).

No início temos isso:

x = 10
y = 9

((((x + y)* y )/ x) - y) % 3

  1. (x + y) -> (10 + 9) <- é avaliado

(((19 * y )/ x) - y) % 3

  1. (19 * y) -> (19 * 9) <- é avaliado

((171 / x) - y) % 3

  1. (171 / x) -> (171 / 10) <- é avaliado (lembre-se que são números inteiros, portanto o resultado será truncado)

(17 - y) % 3

  1. (17 - y) -> (17 - 9) <- é avaliado

8 % 3

  1. Essa operação de resto é executada. Oito dividido por três é dois, com resto dois. Como o resto é o que interessa, esse resultado é armazenado.
nel

Olá.

A precedência é matemática, ou seja, multiplicação e divisão tem a mesma precedência e em seguida adição e subtração, quando elementos de mesmo precedência são utilizados a operação é efetuada da esquerda para a direita. Para alterar este tipo de precedência, podemos utilizar dos paretênses.

Esta deve ser a linha que está deixando você confuso, certo?

double resultado = ((((x + y)* y )/ x) - y) % 3;

Ele vai efetuar a soma de x+y, multiplicar este valor por y, dividir por x e após isso com o valor ele subtrai de y e após isso pega o resultado e divide por 3, passando o resto da divisão para a variavél double resultado.

Se eu estiver enganado, por favor me corrijam.

Edit: o colega acima detalhou o procedimento, agora ficou mais fácil de entender, certo? :slight_smile:

Abraços.

M

As precedências são estas.

E lembre-se: quando se usa operadores valor++, valor-- eles são avaliados após seus valores serem usados.

Por exemplo:

int i = 1;
int j = 1;

System.out.println(i++); // imprime o valor de i (1) e depois incrementa
System.out.println(++j); // incrementa o valor de j (vai para 2) e depois imprime

Quanto ao operador ternário (if ternário), a expressão será avaliada. Se for verdadeira o primeiro valor (entre ? e : ) será atribuído à variável. Caso contrário, o segundo valor (entre : e ; ) será atribuído.

sidney.tavares

Obrigado amigos, como disse, to começando a entender melhor os conceitos, a explicação que ambos me deram me ajudou bastante.

RodyBr

se eu não me engano, no livro do Deitel fala sobre a precedência dos operadores no Java :wink:

M

O teste final!

Tente calcular o resultado que será impresso sem executar o programa.

int i = 10;                                              
int j = 12;                                              
                                                         
int k = i++ < --j ? i * j + 10 % 3 : j / i >> 2;         
                                                         
int l = !true || k >= i * i + j * 2  ? 3 * k++ : --k % 5;
                                                         
System.out.println(--l);

Isso vai ajudar a exercitar a lógica e fixar algum conhecimento que ainda falte.

Boa sorte! :slight_smile:

sidney.tavares

marcobiscaro2112:
O teste final!

Tente calcular o resultado que será impresso sem executar o programa.

int i = 10;                                              
int j = 12;                                              
                                                         
int k = i++ < --j ? i * j + 10 % 3 : j / i >> 2;         
                                                         
int l = !true || k >= i * i + j * 2  ? 3 * k++ : --k % 5;
                                                         
System.out.println(--l);

Isso vai ajudar a exercitar a lógica e fixar algum conhecimento que ainda falte.

Boa sorte! :)

Para ver se estou entendendo bem…

vai ser atribuído um valor inteiro a k, se o pós incremento de i, que eu acredito seja 11, for menor que pre-decremento de j, que eu acredito ser 11 também, vai ser analisada toda a expressão entre o ? e o : (i * j + 10 % 3), caso contrário será atribuído o valor entre o : e o ; que determina o fim da instrução, é isso? Mais uma coisa, o que quer dizer o sinal >>2 na primeira linha? Se também for um operador ainda não aprendi sobre ele.

Na segunda linha, !true, significa diferente de verdadeiro? Desculpe se parecer idiota a pergunta, mas ainda não trabalho plenamente com eles no meu aprendizado, não passa o resultado tá bom…vou fazer como você sugeriu, praticar a lógica…Obrigado pela ajuda…

M

Ainda bem que está perguntando!

  1. Lembre-se que que na hora de avaliar a expressão, o pós-incremento não é usado (ou seja, na primeira linha, onde verificamos se i++ < --j, o ‘i’ ainda não foi incrementado para fazer a comparação; já o ‘j’ foi decrementado).

  2. Logo após isso ser verificado, aí sim o pós-incremento é usado.

  3. O ‘>>’ é sim um operador (não muito usado normalmente) e que significa deslocamento de bit à direita. No exemplo, os bits do número são deslocados 2 casas para a direita. Um exemplo:
    12 >> 1
    Primeiro, vejamos quanto vale 12 em binário:
    1100
    Deslocando 1 casa:
    0110
    Veja que o número a mais (o zero mais a direita) que ficaria sobrando é ignorado. O operador ‘<<’ faz a operação similar, porém desloca à esquerda:
    12 << 1
    11000 ( = 24; um zero a mais adicionado)

  4. O operador ! é um não lógico. Ou seja, ele inverte o valor booleano. !true é o mesmo que false e vice-versa.

sidney.tavares

Muitissimo obrigado pelas explicações, eu gosto de entender o que to fazendo, por isso ainda não uso as IDE’s que fazem quase tudo pra gente, nada contra, mas no aprendizado, é melhor eu digitar e interpretar o que cada linha faz, pelo menos eu acredito nisso, porque depois fica bem mais fácil identificar erros. Muito Obrigado mesmo.

Criado 23 de dezembro de 2009
Ultima resposta 23 de dez. de 2009
Respostas 9
Participantes 4