Instituto Superior Técnico Linguagens de Programação – 2015/2016 Primeiro Teste – 15/04/2016 Número: Nome: Escreva o seu número em todas as folhas da prova. O tamanho das respostas deve ser limitado ao espaço fornecido para cada pergunta. Pode usar os versos das folhas para rascunho. A prova tem 3 páginas e a duração é de 1.0 hora. A cotação de cada questão encontra-se indicada entre parêntesis. Boa sorte. 1. (1.0) Qual foi a primeira linguagem de programação de alto nı́vel? Era uma linguagem funcional ou imperativa? A primeira linguagem de programação de alto nı́vel denominava-se Fortran e era uma linguagem imperativa. 2. (3.0) A alocação de variáveis pode ser estática, no stack ou no heap. Escreva, em linguagens à sua escolha, três fragmentos de programas (cada um contendo, pelo menos, uma subrotina) tais que: (a) (1.0) Possa ser empregue alocação estática. int x = 0; int f(int y) { return x + y; } (b) (1.0) Não possa ser empregue alocação estática mas possa ser empregue alocação no stack. int fact(int n) { if (n == 0) { return 1; } else { return n * fact (n - 1); } } 2 Número: (c) (1.0) Não possa ser empregue alocação estática ou alocação no stack e tenha de ser empregue alocação no heap. (define (compose f g) (lambda (x) (f (g x)))) 3. (2.0) Considere o seguinte programa escrito na linguagem imaginária C+/-. declare x = 2; sub f() { print x; } sub g() { declare x = 5; f(); print x; } g(); print x; (a) (1.0) Se admitirmos que a linguagem C+/- possui âmbito léxico, qual é o output do programa? Explique. 2 5 2 (b) (1.0) Se admitirmos que a linguagem C+/- possui âmbito dinâmico, qual é o output do programa? Explique. 5 5 2 4. (1.0) Para evitar ambiguidades gramaticais, a instrução de selecção if presente na maioria das linguagens encontra-se restringida de forma a que ifs encadeados tenham um significado preciso. Em Pascal, C e Java, adopta-se a regra de que um else diz respeito ao if (não completo) mais próximo. Que outras abordagens conhece? O problema coloca-se quando o consequente de um if é outro if seguido de uma alternativa else. Em Algol 60, existe uma restrição que proı́be que o consequente de um if seja outro if. Em Algol 68 e Fortran 77 usa-se uma instrução explı́cita para terminar o if, impedindo a possibilidade de existirem ifs incompletos. Em Lisp, usam-se parêntesis para delimitar os ifs, não resultando qualquer ambiguidade. 3 Número: 5. (1.0) Quando a linguagem C foi criada, os seus autores escreveram: Since assignment is about twice as frequent as equality testing in typical C programs, it’s appropriate that the operator be half as long. Infelizmente, esta decisão permite a inadvertida introdução de erros de programação que podem ser muito difı́ceis de detectar. Explique de que erros estamos a falar e explique ainda a forma como a linguagem Java lidou com esta questão. 6. (1.0) Em linguagens como C e Java, o operador += permite simplificar as expressões da forma α = α + β. Quais as vantagens? Em que circustâncias é que uma das formas pode produzir resultados diferentes da outra? 7. (1.0) É sabido que uma instrução case corresponde a uma série de instruções if encadeadas. No entanto, nas implementações usuais em linguagens como C, Pascal ou Modula, um case pode executar muito mais rapidamente do que os ifs correspondentes. Explique as técnicas de implementação que permitem este fenómeno. Uma instrução if precisa sempre de avaliar a sua condição e, no caso de ifs encadeados, o número de condições a avaliar cresce linearmente. No caso de uma instrução case, quando as labels constituem um intervalo denso, uma jump table permite a implementação mais eficiente, simplesmente computando o valor da expressão e saltando para o endereço correspondente ao braço do case correcto. Se o intervalo é esparso, então uma hash table ou uma busca binária também permitem determinar o endereço com custos constantes ou logarı́tmicos.