Expressões Aritméticas
Estrutura de Linguagens
Bacharelado em Informática
Universidade de Fortaleza – UNIFOR
Notas de Aula
Professor Augusto Pedroza
O Historicamente, a avaliação de expressões
foi uma das motivações para o
desenvolvimento das primeiras linguagens
de programação
O Expressões aritméticas consistem de
operadores, operandos, parêntesis e
chamadas de função
© Augusto Pedroza
Questões de Projeto
Questões de Projeto
O Quais são as regras de precedência de
operadores?
O Quais são as regras de associatividade dos
operadores?
O Qual é a ordem da avaliação dos
operandos?
O Existem restrições quanto aos efeitos
colaterais da avaliação dos operandos?
O A linguagem permite a sobrecarga de
operadores?
O Qual mesclagem de modos é permitida nas
expressões?
© Augusto Pedroza
Tipos de Operadores
© Augusto Pedroza
Precedência
O As regras de precedência de operadores, para
avaliação de expressões, definem a ordem na qual
operadores adjacentes , com diferentes níveis de
precedência, são avaliados
O Níveis de precedência típicos:
O Unário
O Binário
O Ternário
–
–
–
–
–
© Augusto Pedroza
Parêntesis
Operadores unários
** (se as linguagem suporta)
Operadores multiplicativos
Operadoress aditivos
© Augusto Pedroza
1
Precedência em Pascal
Associatividade
Nível Operadores
1
@, ^, NOT, - (unário), + (unário)
2
*, /, DIV, MOD, AND, SHL, SHR
3
OR, XOR, +, -
4
O As regras de associatividade de operadores
para avaliação de expressões definem a
ordem na qual operadores adjacentes, com
a mesma precedência, são avaliados
O Regras de associatividade típicas:
–
–
IN, =, <>, >, <, <=, >=
Da esquerda para a direita (exceção **)
Algumas linguagens (C, C++ e Fortran) têm
operadores unários associados da direita para
a esquerda
© Augusto Pedroza
© Augusto Pedroza
Ordem de Avaliação dos
Operandos
Associatividade
O APL é diferente, pois todos os operadores
tem precedência igual e todos os
operadores associam-se da esquerda para a
direita
O Regras de precedência e associatividade
podem ser alteradas por parêntesis
O O processo
–
–
–
–
Variáveis: busca de valores
Constantes: algumas vezes uma busca na
memória; na maioria, os valores encontramse na instrução
Expressões entre parêntesis primeiro
Chamadas de função
© Augusto Pedroza
Efeitos Colaterais
© Augusto Pedroza
Efeitos Colaterais
O Quando uma função muda um parâmetro de duas
formas ou muda uma variável não local
int x;
int funcao(int *a)
{ x = x * 2;
return *a/2; }
void main()
{ x = 100;
cout << x << "\t" << ++x + funcao(&x); }
© Augusto Pedroza
void main()
{
int i = 10;
cout << i << "\t" << i++ << "\t" << i++ << "\n";
i = 10;
cout << i << "\t" << ++i << "\t" << ++i;
}
© Augusto Pedroza
2
Soluções para Efeitos Colaterais
O Escrever a definição da linguagem de forma
a não permitir efeitos colaterais funcionais:
–
–
–
–
Parâmetros sem referências
Funções sem acesso a variáveis globais
Vantagem: funciona
Desvantagem perda de flexibilidade
Expressões Condicionais
O Presente em C, C++ e Java
char L;
L = getch();
// Se for letra, transforma em maiúscula
L = L >= ‘a’ && L <= ‘z’ ? L –32 : L;
O Escrever a definição da linguagem de forma
a fixar a ordem de avaliação das expressões
–
Desvantagem: limita otimizações do compilador
© Augusto Pedroza
Sobrecarga de Operadores
Conversão Implícita de Tipos
O Algumas sobrecargas são comuns (+ para
inteiros e reais)
O Algumas são potencialmente problemáticas
–
–
© Augusto Pedroza
Perda de detecção de erros pelo compilador
(como a omissão de um operando, por exemplo)
Pode ser evitado com a introdução de novos
símbolos
O C++, Ada e Fortran 90 permitem sobrecarga
de operadores (pobre legibilidade)
© Augusto Pedroza
Conversão Implícita de Tipos
O Uma expressão de modo misto é aquela que
tem operandos de tipos diferentes
O Coerção é uma operação de conversão de
tipo implícita. Tem como desvantagem
diminuir a possibilidade de detecção de
erros de tipo por parte do compilador
O Na maioria das linguagens, todos os tipos
numéricos sofrem coerção usando
conversão de alargamento
© Augusto Pedroza
O Uma conversão de estreitamento é aquela
que converte um objeto para um tipo que
não pode incluir todos os valores do tipo
original
O Uma conversão de alargamento é aquela na
qual um objeto é convertido para um tipo
que pode incluir ao menos aproximações
para todos os valores do tipo original
© Augusto Pedroza
Conversão Implícita de Tipos
O Em Módula-2 e Ada não há coerção em
expressões
© Augusto Pedroza
3
Conversão de Tipo Explícita
O Causados por:
O Geralmente chamada casting
O Exemplo em Ada:
–
–
INTEGER ( F ) – F é do tipo FLOAT
O Exemplo em C:
–
Erros em Expressões
–
float media = 1 / (float) 2;
Limitações inerentes da matemática, como
divisão por zero, raiz quadrada de valor
negativo etc
Limitações da computação aritmética como
overflow e underflow
O Esse últimos erros são freqüentemente
ignorados pelo sistema em tempo de
execução
© Augusto Pedroza
Expressões Relacionais
© Augusto Pedroza
Expressões Lógicas
O Usa operadores relacionais e operandos de
vários tipos
O Avaliadas para atingir algum valor lógico
O Símbolos usados variam entre as
linguagens (!=, <>, .ne., /=, #, not equal)
O Os operandos são lógicos e o resultado é
lógico
O Operadores
FORTRAN 77 C
.AND.
.OR.
.NOT.
Ada
&& and
||
or
!
not
xor
Cobol
and
or
not
O ex.:(Cobol) if a is greater than b and c is not
equal to 10 then add 1 to b.
© Augusto Pedroza
Expressões Lógicas
© Augusto Pedroza
Avaliação Curto-Circuito
O C não tem tipos lógicos – usa valores 0
(zero) para falso e diferente de zero para
verdade
O Uma característica estranha das expressões
C: a < b < c é uma expressão legal, mas o
resultado não e o que se esperaria
© Augusto Pedroza
O Usada inicialmente nas linguagens
funcionais para melhoria de desempenho
O Pascal: não usa
O C, C++ e Java: usam para operadores
lógicos (&& e ||), mas não para os lógicos
binários (& e |)
O Ada o programador pode especificar
usando “and then” ou “or else”
© Augusto Pedroza
4
Avaliação Curto-Circuito
Instruções de Atribuição
O Fortran 77: usa e fica a cargo do
implementador determinar o ocorre no
caso de efeitos colaterais
O Grande problema: efeitos colaterais
O Quanto ao símbolo dos operadores:
1.
2.
= Fortran, Basic, PL/I, C, C++, Java
:= Algol 60, Algol 68, Pascal, Modula-2,
Ada
O = pode ser ruim se houver sobrecarga para
o operador relacional como em PL/I
A = B = C;
O Alvos múltiplos (PL/I): x, y = 10
© Augusto Pedroza
Instruções de Atribuição
© Augusto Pedroza
Alvos Condicionais
O Operadores de atribuição conjugados (C,
C++ e Java): a += b;
O Operadores de atribuição unários (C, C++
e Java): a++;
O Operador de atribuição binário que produz
resultado e causa problemas de
visibilidade(C, C++ e Java):
a = b && (y = (x == 10) + 1);
if (( a == b) || (a = b))
© Augusto Pedroza
void main() {
int v1 = 0, v2 = 0, cond = 1;
(cond ? v1 : v2) = 10;
cout << "v1 = " << v1;
cout << "\nv2 = " << v2;
cond = 0;
(cond ? v1 : v2) = 20;
cout << "\nv1 = " << v1;
cout << "\nv2 = " << v2; }
© Augusto Pedroza
Atribuições de Modo Misto
O Em Fortran, C e C++, qualquer valor numérico
pode ser atribuído para qualquer variável escalar.
Qualquer conversão que seja necessária é feita
O Em Pascal, inteiros podem ser atribuídos para
reais, mas não o contrário (deve haver
truncamento ou arredondamento)
O Em Java, somente coerções de alargamento são
permitidas
O Ada e Módula-2 não permitem coerção na
atribuição, não permitindo atribuições mistas
© Augusto Pedroza
5