Comandos e
Expressões
Prof: Sergio Souza Costa
Adaptado de © 2004, Programming Language Design Concepts
D.A. Watt, University of Glasgow
Sobre mim
Sérgio Souza Costa
Professor - UFMA
Doutor em Computação Aplicada (INPE)
prof.sergio.costa@gmail.com
https://sites.google.com/site/profsergiocosta/home
https://twitter.com/profsergiocosta
http://gplus.to/sergiosouzacosta
http://www.slideshare.net/skosta/presentations?order=popular
Roteiro
Comandos
skips, atribuições, chamadas de procedimentos ...
Expressões
literais, construtores, chamadas de funções
Comandos
Comando (ou statement) é uma construção que ira ser executada para
atualizar variáveis e são caracteristicos de linguagens imperativas.
● skips
● atribuições
● chamadas de procedimentos
● comandos sequenciais
● comandos de seleção
● comandos iterativos
Skips
O skip é um comando com nenhum efeito.
Exemplo:
“;” in C and Java
“null;” in Ada.
Skips podem ser usados em com comandos condicionais.
Atribuições
● Uma atribuição armazena um valor em uma variável.
● Atribuição simples:
○ “V = E;” em C e Java
○ “V := E;” em Ada
■ valor da expressão E é armazenada na variável V.
● Atribuição múltipla:
○ “V1
 = ... = Vn
 = E;” em C e Java
■ – o valor de E é armazenada em cada de V1
,..., Vn
.
● Atribuição combinada com operador  binário:
○ “V (x)= E;” em C e Java significa o mesmo como “V = V (x) E;”.
Exemplo Lua - Atribuições
Algumas linguagens como Lua, Python e Ruby permitem atribuir dois
valores distintos a variáveis distintas. Trocar dois valores é tão simples
assim:
a= 10
b = 5
a, b = b, a
Chamadas de procedimento
Uma chamada de procedimento alcança seus efeitos pela aplicação
de um procedimento a alguns argumentos.
Forma:
P(E1
,..., En
);
    Aqui P determina procedimento ser aplicada, e E1
, ... , En
 são
avaliados para determinar os argumentos. Cada argumento pode ser
ou um valor ou uma referencia para a variável.
Comandos sequenciais
Comando sequenciais, condicionais e iterativos (encontrados em todas
linguagens imperativas) permite compor comandos alcançando controle de
fluxo.
Comando sequência específica que dois (ou mais) comandos são
executados em sequência:
    C1
C2
- comando 
C1
é executado antes dos comandos 
C2
Comandos condicionais
Um comando condicional escolhe um dos subcomandos para ser executado
dependendo da condição.
Um comando if escolhe entre dos subcomandos usando uma condição
booleana.
Um comando case escolhe entre vários subcomandos.
Comando if
Forma (Ada e C/Java, respectivamente):
if E then if (E)
C1 C1
else else
C2 C2
end if;
Abreviação (Ada):
if E then if E then
C1 C1
end if; else
null;
end if;
E deve ser um
boolean
Comando if
Generalizando múltiplas condições (em Ada):
if E1 then
C1
elsif E2 then
C2
…
elsif En then
Cn
else
C0
end if;
Comando case: C/C++
switch (E) {
case v1
:
C1
…
case vn
:
Cn
default:
C0
}
Comando case: Ada
today: Date;
...
case today.m is
when jan => put("JAN");
when feb => put("FEB");
...
when nov => put("NOV");
when dec => put("DEC");
end case;
Date today;
...
switch (today.m) {
case 1: System.out.print("JAN"); break;
case 2: System.out.print("FEB"); break;
...
case 11: System.out.print("NOV"); break;
case 12: System.out.print("DEC");
}
Comando case: Java
Comandos iterativos
Um comando iterativo (ou laço) executa repetidamente um
subcomando que é o corpo do laço.
Cada execução do corpo do laço é chamado de iteração.
Os comandos iterativos podem ser:
○ Indefinidos: o número de iterações não é predeterminada.
○ Definido: o número de iterações é predeterminada.
Comandos iterativos 
Indefinido é comumente suportado pelo comando while
                  
                       
C1
while (E)
{ C3 C2 }
for (C1; E; C2)
C3
while (E)
c
while E loop
C en
d loop;
Definido
Comandos iterativos, alternativos
Lua:
t = {1,2,3}
for i, v in pairs (t) do
    print (i, v)
end
JavaScript:
a = [1,2,3]
for (x in a){
    ..
}
Python:
a = ['cat', 'window', 'defenestrate']
for x in a:
    print x, len(x)
Expressões com efeitos colaterais
● O propósito principal de avaliar uma expressão é o retorno de um
valor.
● Em muitos casos em linguagens imperativas, a avaliação de uma
expressão pode atualizar valor de variáveis – efeitos colaterais.
● In C e Java, atribuições são na verdade expressões com efeitos
colaterais: “V = E” armazena o valor de E em V. Similarmente “V (X)
= E”.
Efeitos colaterais: Exemplo C
A funcão C getchar(f) lê um caracter e atualiza a variavel file que f aponta.
O seguinte código é correto e conciso:
char ch;
while ((ch = getchar(f)) != NULL)
putchar(ch);
O seguinte codigo é incorreto (Por que?):
enum Gender {female, male};
Gender g;
if (getchar(f) == 'F') g = female;
else if (getchar(f) == 'M') g = male;
else ..
Expressões
Uma expressão é uma construção que pode ser avaliada para um dado valor:
● literais
● construtores
● chamada de funções
● expressões condicionais
● expressões iterativas
Literais
The simplest kind of expression is a literal, which denotes a fixed
value of some type.
365 3.1416 false '%' "What?"
Construtores
Construtor é uma expressão que constroem um valor composto a partir
dos seus componentes
Em C, os valores componentes são restritos a literais.
    {jan, 1}
Ada, Java, e Haskell, os valores componentes são avaliadas como
subexpressões:
    tomorrow: Date := (today.m, today.d + 1);
Construtores - Ada
Registros:
type Date is record
m: Month;
d: Day_Number;
end record;
today: Date := (Dec, 25);
tomorrow: Date := (today.m, today.d+1);
Arranjo:
leap: Integer range 0 .. 1;
…
month_length: array (Month) of Integer :=
(31, 28+leap, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31)
Construtores - Java
Classes:
class Date {
public int m, d;
public Date (int m, int d) {
this.m = m; this.d = d;}
…
}
Objeto:
Date today = new Date(12, 25);
Date tomorrow =
new Date(today.m, today.d+1)
Chamada de funções
Calcula um resultado aplicando uma função a seus argumentos.
Se uma função tem um único argumento, então uma chamada é
tipicamente na forma
○  “F(E)”,
○  ou apenas “F E”,
Onde F determina a função ser aplicada, e a expressão E é avaliada
para um determinada argumento.
Chamada de funções, operadores
Um operador é em essência uma função.
Aplicar um operador unário ϴ é essencialmente uma chamada de
função com um argumento.
    ϴ E  é equivalente a ϴ(E)
Chamada de funções, operadores
Aplicar um operador binário ϴ é essencialmente uma chamada de função
com dois argumentos. 
            E1 ϴ E2 é equivalente a ϴ(E1, E2)
Desse modo, uma expressão aritmética é essencialmente composição de
funções:
    a * b + c / d equivale a
     +(*(a, b), /(c, d))
Chamada de funções, operadores
Linguagens modernas, como Haskell, não diferencia operadores e funções.
Em Lisp, todos os operadores são chamadas de funções no formato prefixo:
(* 5 (+ 2 5))
Qual o problema dessa abordagem ? O que ainda está faltando para tratar
operadores como funções ?
Ordem de Avaliação
O valor de uma expressão depende em parte da ordem de avaliação
dos operadores.
Exemplo:
a + b * c
Avaliar esta expressão da esquerda para a direita e da direita para a
esquerda pode gerar resultados diferentes
As LPs devem definir uma ordem de precedência entre os operadores
Isto é feito através de regras de precedência de operadores
Ordem de Avaliação - Precedência
Nas linguagens , a ordem de precedência normalmente é a mesma (baseada
na matemática)
Ruby C Ada
Mais alta ** ++ e --
posfixados
**, abs
+ e – unários ++ e –
préfixados, + e –
unários
*, /, mod, rem
*, / e % *, / e %
Mais baixa + e – binários + e – binários
Ordem de Avaliação - Associatividade
Considere a expressão:
a – b + c – d
Quando uma exp. possui dois operadores adjacentes com a mesma precedência, a
ordem de avaliação é feita através das regras de associatividade da LP
Mais à direita
Mais à esquerda
Normalmente os operadores tem associatividade à esquerda, com exceção da
exponenciação (à direita)
○ Exceção: Em Ada, a exponenciação não é associativa....
Operadores - Haskell
Em Haskell, como operadores são funções, essas regras são
escritas também na linguagem.
infixr 9 .
infixl 9 !! 
infixr 8 ^, ^^, ** 
infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, % 
infixl 6 +, - 
infixr 5 ++ 
infix 4 ==, /=, <, <=, >=, >, `elem`, `notElem` 
Ordem de Avaliação dos argumentos
Estratégia call-by-value --- Avalia primeiro o argumento antes de aplicar a
função (Pascal, C, Java, etc).
(x -> x+1) (2+3)
= (x+1)+ 5
= 5+1
= 6
Estratégia call-by-name (ou lazy evaluation) --- Aplica imediatamente a
função ao argumento, adiando para mais tarde a avaliação desse argumento
(Haskell e Miranda)
(x -> x+1) (2+3)
= (2+3)+1
= 5+1
= 6
Operadores - Curto Circuito
Uma avaliação em curto-circuito de uma expressão é tal que o resultado é
determinado sem avaliar todos os operandos e operadores
Exemplo:
(13 * a) * (b / 13 - 1) // se a == 0...
(a >= 0) && (b < 10)
if ((a != NULL) && (a->x > 2) )
Expressões condicionais
Uma expressão condicional escolhe uma das suas subexpressões para ser
avaliada, dependendo de uma condição.
Uma if-expression a escolha é entre duas
Uma case-expression a escolha é entre várias.
São mais comuns em linguagens funcionais.
Expressões condicionais
Java if-expression:
x>y ? x : y
Comparando expressões e comandos
int max1 (int x, int y) {
   return (x>y ? x : y);
}
int max2 (int x, int y) {
  if (x>y)
    return x;
  else
    return y;
}
Expressões condicionais
Haskell case-expression:
case m of
feb -> if isLeap y then 29 else 28
apr -> 30
jun -> 30
sep -> 30
nov -> 30
_ -> 31
if x>y then x else y
Haskell if-expression:
Haskell: Expressão if
Em Haskell, como é uma linguagem funcional sempre temos o else, e r1 e r2
são valores do mesmo tipo e não são comandos.
if <e> then
<r1>
else
<r2>
menor x y = if x <= y then x
else y

Comandos e expressões

  • 1.
    Comandos e Expressões Prof: SergioSouza Costa Adaptado de © 2004, Programming Language Design Concepts D.A. Watt, University of Glasgow
  • 2.
    Sobre mim Sérgio SouzaCosta Professor - UFMA Doutor em Computação Aplicada (INPE) prof.sergio.costa@gmail.com https://sites.google.com/site/profsergiocosta/home https://twitter.com/profsergiocosta http://gplus.to/sergiosouzacosta http://www.slideshare.net/skosta/presentations?order=popular
  • 3.
    Roteiro Comandos skips, atribuições, chamadasde procedimentos ... Expressões literais, construtores, chamadas de funções
  • 4.
    Comandos Comando (ou statement)é uma construção que ira ser executada para atualizar variáveis e são caracteristicos de linguagens imperativas. ● skips ● atribuições ● chamadas de procedimentos ● comandos sequenciais ● comandos de seleção ● comandos iterativos
  • 5.
    Skips O skip é um comandocom nenhum efeito. Exemplo: “;” in C and Java “null;” in Ada. Skips podem ser usados em com comandos condicionais.
  • 6.
    Atribuições ● Uma atribuição armazenaum valor em uma variável. ● Atribuição simples: ○ “V = E;” em C e Java ○ “V := E;” em Ada ■ valor da expressão E é armazenada na variável V. ● Atribuição múltipla: ○ “V1  = ... = Vn  = E;” em C e Java ■ – o valor de E é armazenada em cada de V1 ,..., Vn . ● Atribuição combinada com operador  binário: ○ “V (x)= E;” em C e Java significa o mesmo como “V = V (x) E;”.
  • 7.
    Exemplo Lua -Atribuições Algumas linguagens como Lua, Python e Ruby permitem atribuir dois valores distintos a variáveis distintas. Trocar dois valores é tão simples assim: a= 10 b = 5 a, b = b, a
  • 8.
    Chamadas de procedimento Uma chamadade procedimento alcança seus efeitos pela aplicação de um procedimento a alguns argumentos. Forma: P(E1 ,..., En );     Aqui P determina procedimento ser aplicada, e E1 , ... , En  são avaliados para determinar os argumentos. Cada argumento pode ser ou um valor ou uma referencia para a variável.
  • 9.
    Comandos sequenciais Comando sequenciais,condicionais e iterativos (encontrados em todas linguagens imperativas) permite compor comandos alcançando controle de fluxo. Comando sequência específica que dois (ou mais) comandos são executados em sequência:     C1 C2 - comando  C1 é executado antes dos comandos  C2
  • 10.
    Comandos condicionais Um comando condicional escolheum dos subcomandos para ser executado dependendo da condição. Um comando if escolhe entre dos subcomandos usando uma condição booleana. Um comando case escolhe entre vários subcomandos.
  • 11.
    Comando if Forma (Adae C/Java, respectivamente): if E then if (E) C1 C1 else else C2 C2 end if; Abreviação (Ada): if E then if E then C1 C1 end if; else null; end if; E deve ser um boolean
  • 12.
    Comando if Generalizando múltiplascondições (em Ada): if E1 then C1 elsif E2 then C2 … elsif En then Cn else C0 end if;
  • 13.
    Comando case: C/C++ switch(E) { case v1 : C1 … case vn : Cn default: C0 }
  • 14.
    Comando case: Ada today:Date; ... case today.m is when jan => put("JAN"); when feb => put("FEB"); ... when nov => put("NOV"); when dec => put("DEC"); end case;
  • 15.
    Date today; ... switch (today.m){ case 1: System.out.print("JAN"); break; case 2: System.out.print("FEB"); break; ... case 11: System.out.print("NOV"); break; case 12: System.out.print("DEC"); } Comando case: Java
  • 16.
    Comandos iterativos Um comandoiterativo (ou laço) executa repetidamente um subcomando que é o corpo do laço. Cada execução do corpo do laço é chamado de iteração. Os comandos iterativos podem ser: ○ Indefinidos: o número de iterações não é predeterminada. ○ Definido: o número de iterações é predeterminada.
  • 17.
    Comandos iterativos  Indefinido écomumente suportado pelo comando while                                            C1 while (E) { C3 C2 } for (C1; E; C2) C3 while (E) c while E loop C en d loop; Definido
  • 18.
    Comandos iterativos, alternativos Lua: t= {1,2,3} for i, v in pairs (t) do     print (i, v) end JavaScript: a = [1,2,3] for (x in a){     .. } Python: a = ['cat', 'window', 'defenestrate'] for x in a:     print x, len(x)
  • 19.
    Expressões com efeitoscolaterais ● O propósito principal de avaliar uma expressão é o retorno de um valor. ● Em muitos casos em linguagens imperativas, a avaliação de uma expressão pode atualizar valor de variáveis – efeitos colaterais. ● In C e Java, atribuições são na verdade expressões com efeitos colaterais: “V = E” armazena o valor de E em V. Similarmente “V (X) = E”.
  • 20.
    Efeitos colaterais: ExemploC A funcão C getchar(f) lê um caracter e atualiza a variavel file que f aponta. O seguinte código é correto e conciso: char ch; while ((ch = getchar(f)) != NULL) putchar(ch); O seguinte codigo é incorreto (Por que?): enum Gender {female, male}; Gender g; if (getchar(f) == 'F') g = female; else if (getchar(f) == 'M') g = male; else ..
  • 21.
    Expressões Uma expressão é uma construçãoque pode ser avaliada para um dado valor: ● literais ● construtores ● chamada de funções ● expressões condicionais ● expressões iterativas
  • 22.
    Literais The simplest kindof expression is a literal, which denotes a fixed value of some type. 365 3.1416 false '%' "What?"
  • 23.
    Construtores Construtor é uma expressãoque constroem um valor composto a partir dos seus componentes Em C, os valores componentes são restritos a literais.     {jan, 1} Ada, Java, e Haskell, os valores componentes são avaliadas como subexpressões:     tomorrow: Date := (today.m, today.d + 1);
  • 24.
    Construtores - Ada Registros: typeDate is record m: Month; d: Day_Number; end record; today: Date := (Dec, 25); tomorrow: Date := (today.m, today.d+1); Arranjo: leap: Integer range 0 .. 1; … month_length: array (Month) of Integer := (31, 28+leap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
  • 25.
    Construtores - Java Classes: classDate { public int m, d; public Date (int m, int d) { this.m = m; this.d = d;} … } Objeto: Date today = new Date(12, 25); Date tomorrow = new Date(today.m, today.d+1)
  • 26.
    Chamada de funções Calculaum resultado aplicando uma função a seus argumentos. Se uma função tem um único argumento, então uma chamada é tipicamente na forma ○  “F(E)”, ○  ou apenas “F E”, Onde F determina a função ser aplicada, e a expressão E é avaliada para um determinada argumento.
  • 27.
    Chamada de funções,operadores Um operador é em essência uma função. Aplicar um operador unário ϴ é essencialmente uma chamada de função com um argumento.     ϴ E  é equivalente a ϴ(E)
  • 28.
    Chamada de funções,operadores Aplicar um operador binário ϴ é essencialmente uma chamada de função com dois argumentos.              E1 ϴ E2 é equivalente a ϴ(E1, E2) Desse modo, uma expressão aritmética é essencialmente composição de funções:     a * b + c / d equivale a      +(*(a, b), /(c, d))
  • 29.
    Chamada de funções,operadores Linguagens modernas, como Haskell, não diferencia operadores e funções. Em Lisp, todos os operadores são chamadas de funções no formato prefixo: (* 5 (+ 2 5)) Qual o problema dessa abordagem ? O que ainda está faltando para tratar operadores como funções ?
  • 30.
    Ordem de Avaliação Ovalor de uma expressão depende em parte da ordem de avaliação dos operadores. Exemplo: a + b * c Avaliar esta expressão da esquerda para a direita e da direita para a esquerda pode gerar resultados diferentes As LPs devem definir uma ordem de precedência entre os operadores Isto é feito através de regras de precedência de operadores
  • 31.
    Ordem de Avaliação- Precedência Nas linguagens , a ordem de precedência normalmente é a mesma (baseada na matemática) Ruby C Ada Mais alta ** ++ e -- posfixados **, abs + e – unários ++ e – préfixados, + e – unários *, /, mod, rem *, / e % *, / e % Mais baixa + e – binários + e – binários
  • 32.
    Ordem de Avaliação -Associatividade Considere a expressão: a – b + c – d Quando uma exp. possui dois operadores adjacentes com a mesma precedência, a ordem de avaliação é feita através das regras de associatividade da LP Mais à direita Mais à esquerda Normalmente os operadores tem associatividade à esquerda, com exceção da exponenciação (à direita) ○ Exceção: Em Ada, a exponenciação não é associativa....
  • 33.
    Operadores - Haskell EmHaskell, como operadores são funções, essas regras são escritas também na linguagem. infixr 9 . infixl 9 !!  infixr 8 ^, ^^, **  infixl 7 *, /, `quot`, `rem`, `div`, `mod`, :%, %  infixl 6 +, -  infixr 5 ++  infix 4 ==, /=, <, <=, >=, >, `elem`, `notElem` 
  • 34.
    Ordem de Avaliaçãodos argumentos Estratégia call-by-value --- Avalia primeiro o argumento antes de aplicar a função (Pascal, C, Java, etc). (x -> x+1) (2+3) = (x+1)+ 5 = 5+1 = 6 Estratégia call-by-name (ou lazy evaluation) --- Aplica imediatamente a função ao argumento, adiando para mais tarde a avaliação desse argumento (Haskell e Miranda) (x -> x+1) (2+3) = (2+3)+1 = 5+1 = 6
  • 35.
    Operadores - CurtoCircuito Uma avaliação em curto-circuito de uma expressão é tal que o resultado é determinado sem avaliar todos os operandos e operadores Exemplo: (13 * a) * (b / 13 - 1) // se a == 0... (a >= 0) && (b < 10) if ((a != NULL) && (a->x > 2) )
  • 36.
    Expressões condicionais Uma expressãocondicional escolhe uma das suas subexpressões para ser avaliada, dependendo de uma condição. Uma if-expression a escolha é entre duas Uma case-expression a escolha é entre várias. São mais comuns em linguagens funcionais.
  • 37.
    Expressões condicionais Java if-expression: x>y? x : y Comparando expressões e comandos int max1 (int x, int y) {    return (x>y ? x : y); } int max2 (int x, int y) {   if (x>y)     return x;   else     return y; }
  • 38.
    Expressões condicionais Haskell case-expression: casem of feb -> if isLeap y then 29 else 28 apr -> 30 jun -> 30 sep -> 30 nov -> 30 _ -> 31 if x>y then x else y Haskell if-expression:
  • 39.
    Haskell: Expressão if EmHaskell, como é uma linguagem funcional sempre temos o else, e r1 e r2 são valores do mesmo tipo e não são comandos. if <e> then <r1> else <r2> menor x y = if x <= y then x else y