Academia da Força Aérea
Expressões devolvem sempre um valor concreto com um determinado tipo.
Operação unária ➡ Operação que recebe apenas 1 operando, e.g. -v
Por outro lado, as outras operações são binárias ➡ 2 operandos, e.g. 1+2
Cuidado com a divisão!
O resto da divisão % requer 2 operandos inteiros.
Usar 0 como o segundo operando da divisão / ou resto da divisão %, i.e. divisão por 0, gera comportamento não definido.
As operações no C têm uma precedência.
| Precedência | Nome | Operadores | Associatividade |
|---|---|---|---|
| 1 | incremento (sufixo) | ++ -- |
esquerda |
| 2 | incremento (prefixo) additivos unários |
++ --+ - |
direita |
| 3 | multiplicativos | * / % |
esquerda |
| 4 | aditivos binários | + - |
esquerda |
| 5 | desigualdades | < <= > >= |
esquerda |
| 6 | igualdades | == != |
esquerda |
| 7 | atribuição | = *= /= %= += -= |
direita |
Exemplo de precedência de operadores. Fonte: geeksforgeeks.org
Exemplos:
1 + 2 * -2 ➡ 1 + (2 * (-2))i + j * k ➡ i + (j * k)-i * -j ➡ (-i) * (-j)E quando uma expressão tem 2 operações com a mesma precedência?
Tem-se em conta a associatividade.
Exemplo de associatividade de operadores. Fonte: geeksforgeeks.org
i / j * k == (i / j) * k
+ - * / % têm associtividade à esquerda, logo agrupam o que está antes do operador.
Os operadores unários têm associatividade à direita.
- -2 == - (-2)
Exemplo de associatividade e precedência de operadores. Fonte: geeksforgeeks.org
Já conhecemos o operador de atribuição simples =.
É o que designamos por uma operação com efeitos secundários, porque altera o estado dos operandos.
a = 2 altera o estado da variável a porque o seu valor é agora 2.
Adicionalmente, a = 2 é uma expressão válida que devolve o valor que foi atribuido à variável
Todas as operações de atribuição exigem que o operando da esquerda seja uma variável.
Existem outros que se combinam com operações aritméticas.
| Expressão | Descrição |
|---|---|
var+=3 |
soma 3 ao valor de var e atribui o resultado a var |
var-=3 |
subtrai 3 ao valor de var e atribui o resultado a var |
var*=3 |
multiplica 3 com o valor de var e atribui o resultado a var |
var/=3 |
divide o valor de var por 3 e atribui o resultado a var |
var%=3 |
faz o resto da divisão entre var e 3 e atribui o resultado a var |
v*=3 não é equivalente a v = v * 3, embora na maior parte das utilizações o resultado seja o mesmo. Porquê?
Observem a expressão v *= 3 + 10. É equivalente a v = v * 3 + 10?
Devido às regras de precedência e associatividade leva a um resultado diferente.
Não confundir += com =+.
A primeira operação acumula o valor à direita.
A segunda é uma simples atribuição seguida do operador + unário.
Em suma…
… usem sempre ( ) para deixar claro qual é a ordem das operações.
Existe uma instrução que é frequentemente usada no C (irão perceber porquê quando abordarmos ciclos):
Existe outra forma de escrever esta instrução, com o operador de incremento ++
Este operador pode ser usado tanto antes de uma variável (pré-incremento) como depois (pós-incremento).
Qual será a diferença?
Além do incremento ++, também temos disponível o decremento --, que funciona da mesma forma, mas subtrai em uma unidade.
Com este conhecimento conseguimos avaliar expressões complicadas.
a= b += c++ - d + --e / -f
a= b += c++ - d + --e / -f
a= b += (c++) - d + (--e) / -f c++ e depois --e (precedência)a= b += (c++) - d + (--e) / (-f) operador unário -f (precedência)a= b += (c++) - d + ((--e) / (-f)) divisão (precedência)a= b += (c++) - d + ((--e) / (-f))a= b += ((c++) - d) + ((--e) / (-f)) - e + com a mesma precedência e com operando em comum d (precedência), agrupam da esquerda para a direita, logo - primeiro (associatividade)a= b += (((c++) - d) + ((--e) / (-f))) + (precedência)a= (b += (((c++) - d) + ((--e) / (-f)))) = e += com mesma precedência (precedência), agrupam da direita para a esquerda, logo += primeiro (associatividade)(a= (b += (((c++) - d) + ((--e) / (-f))))) sobra apenas o = (precedência)Moral da história: façam um favor a vós próprios…
… e usem ( ).
Programação