Capítulo 4 Estruturação de Procedimentos 4.1 Exercícios de revisão 1. Diga o que entende por linguagem estruturada em blocos. Descreva a regra associada a esta estrutura, e diga qual a sua importância. 2. O que entende pelo domínio de um nome? 4.2 Exercícios de programação 4.2.1 Estrutura de Blocos 1. (1) Considere as seguintes alternativas para definir um procedimento que calcula a função factorial. Alternativa 1: (define (factorial n) (if (>= n 0) (fact-aux n) (error "factorial: argumento negativo"))) (define (fact-aux n) (if (= n 0) 1 (* n (fact-aux (- n 1))))) Alternativa 2: (define (factorial n) (define (fact-aux n) (if (= n 0) 1 (* n (fact-aux (- n 1))))) (if (>= n 0) (fact-aux n) (error "factorial: argumento negativo"))) 40 CAPÍTULO 4. ESTRUTURAÇÃO DE PROCEDIMENTOS (a) Compare estas duas alternativas quanto à garantia de que o factorial não é calculado com valores indevidos. Sugestão: Será que se pode avaliar directamente (fact-aux -1)? (b) Como se chama a estrutura definida pela alternativa 2? Qual a sua vantagem? 2. (1) A estrutura de blocos leva à existência de novos ambientes. Com base no procedimento que se segue, que calcula m! n! (m > n), justifique a afirmação. Sugestão: Identifique as variáveis locais e não locais para cada um dos procedimentos. (define (quociente-de-factoriais m n) (define (iter m res) (if (= m n) res (iter (- m 1) (* m res)))) (iter m 1)) 3. (1) (Secção 2.2.3, Ex 2) Recorrendo à estrutura de blocos, escreva um procedimento em Scheme somatorio que recebe um número inteiro positivo n, e devolve a soma de todos os números até n. O seu procedimento deve gerar um processo iterativo. > (somatorio 3) 6 > (somatorio 6) 21 4. (1) (Secção 2.2.3, Ex 4) Recorrendo à estrutura de blocos, escreva um procedimento em Scheme factorial que recebe um número inteiro positivo n, e devolve o factorial desse número. O seu procedimento deve gerar um processo iterativo. > (factorial 0) 1 > (factorial 5) 120 5. (2) (Secção 2.2.3, Ex 7) Recorrendo à estrutura de blocos, escreva um procedimento em Scheme numero-primos-menores que recebe um número inteiro positivo n, e retorna o número de primos menores ou iguais a n. O seu procedimento deve gerar um processo iterativo. Sugestão: Utilize o procedimento primo? definido na alínea 17 da Secção 3.2. > (numero-primos-menores 9) 4 > (numero-primos-menores 23) 9 4.2. EXERCÍCIOS DE PROGRAMAÇÃO 41 6. (2) (Secção 2.2.3, Ex 8) Recorrendo à estrutura de blocos, escreva um procedimento em Scheme numero-divisores-primos que recebe um número inteiro positivo n, e retorna o número de divisores primos de n. No caso de n ser 0 deverá retornar 0. O seu procedimento deve gerar um processo iterativo. Sugestão: Utilize o procedimento primo? definido na alínea 17 da Secção 3.2. > (numero-divisores-primos 1) 0 > (numero-divisores-primos 20) 2 > (numero-divisores-primos 30) 3 7. (3) (Secção 2.2.3, Ex 10) O logaritmo inteiro de um número n na base b é o maior número inteiro e tal que be ≤ n. Recorrendo à estrutura de blocos, escreva um procedimento em Scheme logaritmo que recebe dois números inteiros positivos n e b, e devolve o logaritmo inteiro de n na base b. No caso de n ou b serem 0 deverá retornar 0. O seu procedimento deve gerar um processo iterativo. > (logaritmo 8 2) 3 > (logaritmo 7 2) 2 8. (3) (Secção 2.2.3, Ex 15) Recorrendo à estrutura de blocos, escreva um procedimento em Scheme soma-digitos-pares que recebe um número inteiro positivo n, e retorna a soma de todos os dígitos pares de n. O seu procedimento deve gerar um processo iterativo. > (soma-digitos-pares 9) 0 > (soma-digitos-pares 1412) 6 9. (4) (Secção 2.2.3, Ex 19) Um número binário bn bn−1 . . . b1 b0 pode ser transformado � num número decimal usando a seguinte formula ni=0 bi 2i . Recorrendo à estrutura de blocos, escreva um procedimento em Scheme binario-decimal que recebe um número b escrito em binário e retorna a sua representação decimal. O seu procedimento deve gerar um processo iterativo. > (binario-decimal 1001) 9 > (binario-decimal 10000) 16 42 CAPÍTULO 4. ESTRUTURAÇÃO DE PROCEDIMENTOS 4.2.2 Utilização de Nomes Locais 1. Em relação às seguintes expressões utilizando o “let”, avalie o valor da expressão e transforme-a numa expressão equivalente utilizando o “lambda”. (a) (1) (let ((x 5) (y 3)) (* x y)) (b) (1) (let ((x 4) (y 3)) (let ((z (* x y))) (+ z x))) (c) (2) (let ((x 5)) (let ((x 3) (y (* x 2))) (+ x y))) (d) (2) (let ((x 5) (y 12)) (+ x (let ((x (+ x y))) (+ x 3)))) 2. (2) Suponha que a tem o valor 5 no ambiente global. Diga qual o resultado de avaliar a seguinte expressão: (let ((a 3) (b (* a 4))) (+ a b)) 3. (2) Considere as seguintes expressões. São equivalentes? Justifique. (let ((x 8)) (let ((x 5) (y (+ x 4))) (+ x y))) (let* ((x 8) (x 5) (y (+ x 4))) (+ x y)) 4. Para cada uma das seguintes combinações envolvendo uma expressão “lambda”, calcule o seu valor e transforme-a numa expressão equivalente utilizando o “let”. (a) (1) 4.2. EXERCÍCIOS DE PROGRAMAÇÃO 43 ((lambda (x y) (+ (* 3 x) y)) 2 3) (b) (1) ((lambda (x) ((lambda (y) ((lambda (z) (* y z)) (+ x y))) 2)) 5) (c) (1) ((lambda (x) ((lambda (y) (+ (* 2 y) x)) (+ x 3))) 5) (d) (2) ((lambda (x y) ((lambda (x) (+ (* 2 x) y)) (+ x y))) 6 2) (e) (2) ((lambda (x y) (+ x y ((lambda (z) (* 2 z)) (+ y 1)))) 5 2) 5. Para cada uma das seguintes séries, escreva um programa em Scheme que calcula o valor aproximado da série. O seu programa deve apresentar uma estrutura de blocos e deve evitar cálculos repetidos. Pode utilizar os procedimentos potencia e factorial sem os definir. (a) (2) ∞ � 1 1 1 1 1 1+ + + + + ... = 2 4 8 16 2n n=0 (b) (2) 1− ∞ � 1 1 1 1 1 + − + + ... = (−1)n+1 = ln(2) 2 3 4 5 n n=0 44 CAPÍTULO 4. ESTRUTURAÇÃO DE PROCEDIMENTOS (c) (2) ∞ � xn n=0 n! = ex (d) (2) 1− ∞ � x2 x4 x2n−2 + − ... = (−1)n+1 = cos(x) 2! 4! (2n − 2)! n=1