Programação de Computadores I UFOP DECOM 2013–2 Aula prática 4 Comandos de Desvio Resumo Nesta aula você irá resolver problemas que requerem uma decisão com base em um teste, ou condição. Para implementar a solução de problemas desse tipo, são utlizados comandos de desvio do fluxo de execução do programa, tais como if-then-else ou switch. Sumário 1 Comandos de Desvio 1.1 Condições mutuamente exclusivas . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 Problemas 2 1 Comandos de Desvio Suponha que você quer escrever um programa Scilab para calcular o valor de f (x), onde f é a função definida a seguir, e x é um valor especificado pelo usuário. f (x) = ln 1 1−x Note que essa função não é definida se x = 1. Portanto, seu programa deverá testar se o valor especificado pelo usuário é igual a 1 e, em caso afirmativo, informar ao usuário que esse não é um valor válido. Caso contrário, o programa deve calcular e imprimir o valor de f (x). O programa poderia ser então escrito do seguinte modo: x = input("Informe o valor de x (deve ser diferente de 1): ") if x <> 1 then printf("f(%g) = %g\n", x, 1/log(1-x)) else printf("Valor inválido: deve ser diferente de 1") end Um comando if-then-else tem a seguinte sintaxe: if condição then bloco de comandos 1 else bloco de comandos 2 end A condição deve ser uma expressão booleana, isto é, uma expressão cujo valor é verdadeiro (%t) ou é falso (%f). Cada bloco de comandos é uma sequência de comandos, incluindo, possivelmente, outros comandos de desvio. A execução de um comando if-then-else é feita do seguinte modo: primeiro, a condição é avaliada; se o valor resultante for %t, o bloco de comandos 1 é executado; caso contrário (se o valor for %f), o bloco de comandos 2 é executado. Observação: a parte else do comando pode ser omitida, caso não se deseje executar nenhum comando particular no caso em que a condição seja falsa. 1 1.1 Condições mutuamente exclusivas Em algumas situações, podemos querer testar um conjunto de condições mutuamente exclusivas, tal como na computação da função definida a seguir: x+y x ≥0e y ≥0 2 x+y x ≥0e y <0 g(x, y) = 2 x + y x <0e y ≥0 x2 + y 2 x < 0 e y < 0 Para computar o valor de g(x, y) podemos escrever o seguinte trecho de código em Scilab: if x >= 0 & y >= 0 then gx = x + y elseif x >= 0 & y < 0 then gx = x + y^2 elseif x >= 0 & y < 0 then gx = x^2 + y else // x < 0 & y < 0 gx = x^2 + y^2 end // bloco 1 // bloco 2 // bloco 3 // bloco 4 No comando acima, a condição da cláusula if é avaliada e, caso seja verdadeira, o bloco de comnados 1 é executado. Caso contrário, é avaliada a condição da cláusula elseif e, caso esta seja verdadeira, o bloco 2 é executado, e assim por diante. Caso nenhuma das condições anteriores seja verdadeira, é executado o bloco de comandos 4, correspondente à cláusula else. Expressões booleanas podem ser construídas usando-se operadores relacionais (tal como < ou <=), e podem ser combinadas por meio de operadores booleanos, tais como & e |. Os operadores relacionais e os operadores booleanos disponíveis em Scilab são mostrados nas tabelas a seguir. Operadores Relacionais operação descrição x < y x menor que y x <= y x menor ou igual a y x > y x maior que y x >= y x maior ou igual a y x == y x igual a y x ~= y x diferente de y x <> y operação ~b b1 & b2 b1 | b2 Operadores Lógicos descrição semântica negação (não) %t se e somente se b é falsa conjunção (ê) %t se e somente se b1 e b2 são ambas verdadeiras disjunção (ou) %f se e somente se b1 e b2 são ambas falsas 2 Problemas 2 Tarefa 1: Tarifa de correio (exercício 2.11) O custo de enviar um pacote pelo correio é de R$ 15,00 para o primeiro kg e R$ 5,00 para cada meio kg ou fração acima de 1 kg. Se o pacote pesar mais de 35 kg, uma tarifa adicional de R$ 15,00 é adicionada ao custo. Nenhum pacote com mais de 50 kg é aceito. Escreva um programa que leia o peso do pacote, em kg, e calcule o custo de envio desse pacote. Seu programa deve também testar se o valor informado para o peso do pacote é válido (isto é, se é maior que 0), imprimindo uma mensagem indicativa de valor inválido, caso contrário. OBS: Imprima o custo de envio no formato correto, isto é, com 2 casas decimais. Exemplo de execução da aplicação Correios: cálculo da tarifa por pacote --------------------------------------Informe o peso do pacote (em kg): 54 Peso acima do valor permitido Exemplo de execução da aplicação Correios: cálculo da tarifa por pacote --------------------------------------Informe o peso do pacote (em kg): 3.4 Custo de envio = 40.00 OBS: Teste o seu programa para valores de peso que possam exercitar todos os caminhos de execução do programa, tais como: 1, 1.7, 6, 38.2, 50, 54. Solução: clear;clc; // Custo de envio de um pacote pelo correio printf("Correios: cálculo da tarifa por pacote\n"); printf("---------------------------------------"); // lê o peso do pacote peso = input("Informe o peso do pacote (em kg): "); // calcula tarifa if peso <=0 then printf("Valor inválido"); else if peso > 50 then printf("Peso acima do valor permitido"); else tarifa = 15 + 5*ceil((peso-1)*2); if peso > 35 then tarifa = tarifa + 15; end // informa o custo de envio printf("Custo de envio = %5.2f",tarifa); end 3 Tarefa 2: Tarifa de Energia A conta de energia elétrica de consumidores residenciais de uma cidade é calculada do seguinte modo, onde o consumo é dado em kilowatts (kw): • Se o consumo é de até 500 kw, a tarifa é de R$ 0,02 por unidade. • Se o consumo é maior que 500 kw, mas não excede 1000 kw, a tarifa é de R$ 0,10 para os 500 primeiros kw e de R$ 0,05 para cada kw excedente a 500. • Se o consumo é maior que 1000 kw, a tarifa é de R$ 0,35 para os 1000 primeiros kw e de R$ 0,10 para cada kw excedente a 1000. • Em toda conta, é cobrada uma taxa básica de serviço de R$ 5,00, independentemente da quantidade de energia consumida. Escreva um programa que leia o consumo de energia elétrica de uma residência e imprima a sua conta de energia, no formato indicado no exemplo abaixo. O programa deve verificar se o valor fornecido para o consumo de energia é um valor inteiro positivo e, caso contrário, terminar exibindo uma mensagem indicativa de valor inválido. Exemplo de execução da aplicação Cálculo da Conta de Energia Elétrica -----------------------------------Informe o consumo de energia: 547 -------------------------------------Consumo = 547 Custo da energia consumida = R$ 304.70 Tarifa básica de serviço = R$ 5.00 Valor a pagar = R$ 309.70 -------------------------------------- Solução: clear; clc; // Conta de Energia Elétrica printf("Cálculo da Conta de Energia Elétrica\n"); printf("------------------------------------\n"); tservico = 5.0; // Lê o consumo de energia consumo = input("Informe o consume de energia: "); if consumo < 0 | int(consumo) <> consumo then printf("valor inválido"); else if consumo <= 500 then custo = consumo * 0.02; elseif consumo <= 100 then custo = 500* 0.1 + (consumo - 500) * 0.05; else custo = 1000 * 0.35 + (consumo - 1000) * 0.1; end // imprime a conta de energia printf("--------------------------------------\n"); printf("Consumo = %g \n", consumo); printf("Custo da energia consumida = R$ %6.2f \n", custo); printf("Tarifa básica de serviço = R$ %6.2f \n", tservico); printf("Valor a pagar = R$ %6.2f \n", custo + tservico); printf("--------------------------------------"); end 4 Tarefa 3: Refração da Luz (exercício 3.12) Refração é a mudança de direção de uma onda (por exemplo, de luz, ou de som) em razão de uma mudança no seu meio de transmissão, como ilustrado na figura abaixo. Ao passar de um meio 1, com índice de refração n1 , para um meio 2, com índice de refração diferente, n2 , a frqu^ncia da onda permanece a mesma, mas sua velocidade de fase se altera (de v1 para v2 ), observando-se então uma mudança no ângulo de incidência da onda (de θ 1 para θ 2 ). Esse fenômeno é descrito pela chamada Lei de Snell: sin θ 1 v1 n1 = = sin θ 2 v2 n2 Escreva um programa que leia os índices de refração de dois meios, n1 e n2 , e o ângulo de incidência θ 1 (em graus), e calcule e imprima os dados a seguir. 1. O ângulo de refração θ 2 correspondente (em graus). Se (n1 /n2 ) sin θ 1 > 1, a equação acima não dará valores reais para θ 2 . Neste caso, a onda é toralmente refletida de volta para o meio 1, e o seu programa deverá exibir a mensagem reflexão total. 2. O ângulo crítico θ c (em graus), que é o ângulo de incidência para o qual θ 2 = 90o . Como sin(90o ) = 1, o valor do ângulo crítico é θ c = sin −1 (n2 /n1 ), que somente é definido se n2 ≤ n1 . Se o valor do ângulo crítico não for definido, seu programa simplesmente não deverá imprimir tal valor. Seu programa deve verificar se os valores fornecidos para os índices de refração n1 e n2 são maiores ou iguais a 1, e também se o valor fornecido para θ 1 está no intervalo 0 ≤ θ 1 ≤ 90o . Caso alguma dessas condições não seja satisfeita, o programa deve terminr, imprimindo a mensagem valores inválidos. Exemplo de execução da aplicação Refração de onda ---------------indice de refração do meio 1 (>= 1) = 1.7 indice de refração do meio 2 (>= 1) = 1 ângulo de incidência (0 a 90 graus) = 30 ângulo de refração = 58.2117 graus ângulo crítico = 36.0319 graus Exemplo de execução da aplicação Refração de onda ---------------indice de refração do meio 1 (>= 1) = 1.7 indice de refração do meio 2 (>= 1) = 1 ângulo de incidência (0 a 90 graus) = 45 reflexão total ângulo crítico = 36.0319 graus 5 Exemplo de execução da aplicação Refração de onda ---------------indice de refração do meio 1 indice de refração do meio 2 ângulo de incidência (0 a 90 ângulo de refração = 24.5789 (>= 1) = 1 (>= 1) = 1.7 graus) = 45 graus Solução: clc; clear; // Refração de onda // n1 sin(theta1) = n2 sin(theta2) printf("Refração de onda\n"); printf("----------------\n"); // Le indices de refração dos meios e ângulo de incidência n1 = input("indice de refração do meio 1 (>=1) = "); n2 = input("indice de refração do meio 2 (>=1) = "); theta1 = input("ângulo de incidência (0 a 90 graus) = "); if n1<1 | n2<1 | theta1 <0 | theta1 > 90 then printf("valores inválidos\n"); else // Cálculo do ângulo de refração r = (n1/n2) * sind(theta1); if r > 1 then printf("reflexão total\n") else printf("ângulo de refração = %g graus\n", asind(r)); end // Cálculo do ângulo crítico if n2 <= n1 then printf("ângulo crítico = %g graus\n", asind(n2/n1)); end end Dicas: 1. Scilab provê funções trigonoétricas para lidar com ângulos expressos em radianos ou em graus. Algumas delas são mostradas na tabela a seguir: função sin(r) cos(r) asin(x) acos(x) sind(a) cosd(a) asind(x) acosd(x) descrição seno do ângulo r, dado em radianos coseno do ângulo r, dado em radianos valor, em radianos, do ângulo cujo seno é x (0 ≤ x ≤ 1) valor, em radianos, do ângulo cujo coseno é x (0 ≤ x ≤ 1) seno do ângulo a, dado em graus coseno do ângulo a, dado em graus valor, em graus, do ângulo cujo seno é x (0 ≤ x ≤ 1) valor, em graus, do ângulo cujo coseno é x (0 ≤ x ≤ 1) 2. Para testar seu programa, você poderá usar alguns dos índices de refração a seguir. 6 meio vácuo índice de refração 1.0 Gases- a 0o C e 1 atm ar 1.000293 hidrogênio 1.000132 Líquidos- a 20o água 1.3330 álcool etílico 1.361 benzeno 1.501 Sólidos- temp. ambiente gelo 1.31 quartzo 1.458 diamante 2.419 7