• Nenhum resultado encontrado

A linguagem Pascal oferece uma maneira f´acil para acessar os campos de um registro. Isto ´e feito usando-se o comando with que permite referenciar, no escopo do comando, os campos dos registros sem referˆencia aos identificadores dos registros. A sintaxe do comando with ´e a seguinte:

with Lista de Vari´aveis de Registro do Comando ou Bloco de Comandos;

Obs.: na lista de vari´aveis n˜ao deve haver vari´aveis de mesmo tipo, ou vari´aveis que tenham campos com o mesmo nome.

Exemplo 9.2 Vamos escrever a func¸˜ao MulComplex apresentada no quadro anterior usando o comando with. function MulComplex(x,y:complex):complex;{ Retorna a multiplicac¸˜ao de dois n´umeros complexos } var z : complex; begin with z do begin a := x.a∗y.a−x.b∗y.b; b := x.a∗y.b+x.b∗y.a; end; MulComplex := z; end;{ MulComplex } 9.4 Exerc´ıcios

1. Declare um tipo chamado tiporeg, definido como um tipo de registro contendo os seguintes campos: Nome, RG, Salario, Idade, Sexo, DataNascimento; onde Nome e RG s˜ao strings, Salario ´e real, Idade ´e inteiro, sexo ´e char e DataNascimento ´e um registro contendo trˆes inteiros, dia, mes e ano. Declare um tipo de registro chamado TipoCadastro que cont´em dois campos: Um campo, Funcionario, contendo um vetor com 100 posic¸˜oes do tipo tiporeg e outro campo inteiro, Quant, que indica a quantidade de funcion´arios no cadastro.

Todos os exerc´ıcios seguintes fazem uso do tipo TipoCadastro.

2. Fac¸a uma rotina, InicializaCadastro, que inicializa uma vari´avel do tipo TipoCadastro. A rotina atribui a quantidade de funcion´arios como zero.

3. Fac¸a um procedimento, LeFuncionarios, com parˆametro uma vari´avel do tipo TipoCadastro. A rotina deve ler os dados de v´arios funcion´arios e colocar no vetor do cadastro, atualizando a quantidade de elementos n˜ao nulos. Caso o nome de um funcion´ario seja vazio, a rotina deve parar de ler novos funcion´arios. A rotina deve retornar com o cadastro atualizado. Lembre que o cadastro n˜ao suporta mais funcion´arios que os definidos no vetor de funcion´arios.

4. Fac¸a uma rotina, chamada ListaFuncion´arios, que imprime os dados de todos os funcion´arios.

5. Fac¸a duas rotinas para ordenar os funcion´arios no cadastro. Uma que ordena pelo nome, OrdenaNome, e outra que ordena pelo sal´ario, OrdenaSalario.

6. Fac¸a uma rotina, SalarioIntervalo, que tem como parˆametros: um parˆametro do tipo TipoCadastro e dois valores reaisv1 ev2,v1 ≤ v2. A rotina lista os funcion´arios com sal´ario entrev1ev2. Depois de imprimir os funcion´arios, imprime a m´edia dos sal´arios dos funcion´arios listados.

7. Fac¸a uma rotina que dado um cadastro, imprime o nome do funcion´ario e o imposto que ´e retido na fonte. Um funcion´ario que recebe at´e R$1000,00 ´e isento de imposto. Para quem recebe mais que R$1000,00 e at´e R$2000,00 tem 10% do sal´ario retido na fonte. Para quem recebe mais que R$2000,00 e at´e R$3500,00 tem 15% do sal´ario retido na fonte. Para quem recebe mais que R$3500,00 tem 25% do sal´ario retido na fonte.

8. Fac¸a uma func¸˜ao, BuscaNome, que tem como entrada o cadastro e mais um parˆametro que ´e o um nome de um funcion´ario. O procedimento deve retornar um registro (tipo tiporeg) contendo todas as informac¸˜oes do funcion´ario que tem o mesmo nome. Caso a func¸˜ao n˜ao encontre um elemento no vetor

9. Fac¸a uma rotina, AtualizaSalario, que tem como parˆametros o cadastro de funcion´arios. A rotina deve ler do teclado o RG do funcion´ario a atualizar. Em seguida a rotina lˆe o novo sal´ario do funcion´ario. Por fim, a rotina atualiza no cadastro o sal´ario do funcion´ario com o RG especificado.

10. Fac¸a uma func¸˜ao, chamada ListaMaraja, que tem como parˆametro o cadastro e devolve um registro contendo os dados de um funcion´ario que tem o maior sal´ario.

11. Fac¸a uma rotina que tem como parˆametros o cadastro e o RG de um funcion´ario. A rotina deve remover do cadastro o funcion´ario que cont´em o RG especificado. Lembre-se que os elementos n˜ao nulos no vetor do cadastro devem estar cont´ıguos. Al´em disso, caso um elemento seja removido, a vari´avel que indica a quantidade de elementos deve ser decrementada de uma unidade. Caso n˜ao exista nenhum elemento no vetor com o RG fornecido, a rotina n˜ao modifica nem os dados do vetor nem sua quantidade. 12. Fac¸a uma rotina, ListaAniversarioSexo, que tem como entrada um cadastro e trˆes inteiros: dia, mes e ano, que correspondem a uma data e um caracter (sexo) com valor ’F’ ou ’M’. A rotina deve imprimir o nome dos funcion´arios que nasceram nesta data e com sexo igual ao definido pelo parˆametro.

10

Recursividade

Dizemos que um objeto ´e dito ser recursivo se ele for definido em termos de si pr´oprio.

Este tipo de definic¸˜ao ´e muito usado na matem´atica. Um exemplo disto ´e a func¸˜ao fatorial, que pode ser definido como:

n! = (

1 sen = 0 e n · (n − 1)! sen > 0.

Existem muitos objetos que podem ser formulados de maneira recursiva. Este tipo de definic¸˜ao permite que possamos definir infinitos objetos de maneira simples e compacta. Podemos inclusive definir algoritmos que s˜ao recursivos, i.e., que s˜ao definidos em termos do pr´oprio algoritmo. Nesta sec¸˜ao veremos como poderemos usar esta poderosa t´ecnica como estrat´egia para o desenvolvimento de algoritmos.

10.1 Projeto por Induc¸˜ao

Os algoritmos recursivos s˜ao principalmente usados quando a estrat´egia de se resolver um problema pode ser feita de maneira recursiva ou quando os pr´oprios dados j´a s˜ao definidos de maneira recursiva. Naturalmente exitem problemas que apresentam estas duas condic¸˜oes mas que n˜ao se ´e aconselhado usar algoritmos re- cursivos. Um problema que pode ser resolvido de maneira recursiva tamb´em pode ser resolvido de maneira iterativa. Algumas das principais vantagens de usar recurs˜ao s˜ao a possibilidade de se gerar programas mais compactos, programas f´aceis de se entender e o uso de uma estrat´egia para se resolver o problema. Esta estrat´egia ´e a de atacar um problema (projetando um algoritmo) sabendo (supondo) se resolver problemas menores: Projeto por Induc¸˜ao. Note que j´a usamos esta id´eia para desenvolver o algoritmo de busca bin´aria.

Os objetos de programac¸˜ao que iremos usar para trabalhar com a recurs˜ao ser˜ao as func¸˜oes e os procedi- mentos. Assim, uma rotina (func¸˜ao ou procedimento) ´e dita ser recursiva se ela chama a si mesma. Uma rotina recursiva pode ser de dois tipos: se uma rotinaR faz uma chamada de si mesmo no meio de sua descric¸˜ao ent˜aoR ´e uma rotina recursiva direta; caso R n˜ao fac¸a uma chamada a ela mesma, mas a outras rotinas que porventura podem levar a chamar a rotinaR novamente, ent˜ao R ´e uma rotina recursiva indireta.

Quando uma rotina recursiva est´a sendo executada, podemos visualizar uma seq¨uˆencia de execuc¸˜oes, uma chamando a outra. Veja a figura 25.

Variáveis V1,V2,...,Vn. Parâmetros: Par1,...,ParP. Rotina R;

(Instância da rotina R)

Instância suficientemente pequena. Resolução Direta.

Sem chamar recursivamente.

R {Chamada 1} Parâmetros e Variáveis locais: Par1,...,ParP,V1,...,Vn

R {Chamada K} Par. e Var. locais: Par1,...,ParP,V1,...,Vn R {Chamada 4} Parâm. e Variáveis locais: Par1,...,ParP,V1,...,Vn R {Chamada 2} Parâmetros e Variáveis locais: Par1,...,ParP,V1,...,Vn

R {Chamada 3} Parâm. e Variáveis locais: Par1,...,ParP,V1,...,Vn

Figura 25: Seq¨uˆencia das chamadas recursivas de uma rotinaR at´e sua ´ultima chamada recursiva. Quando em uma determinada chamada recursiva a rotina faz referˆencia a uma vari´avel ou parˆametro, esta est´a condicionada ao escopo daquela vari´avel. Note que em cada uma das chamadas recursivas, as vari´aveis e

configurac¸˜ao da mem´oria usada para a execuc¸˜ao do programa, chamada pilha de execuc¸˜ao, no momento em que foi feita ak-´esima chamada recursiva. A seta indica o sentido do crescimento da pilha de execuc¸˜ao.

MC PAR VL Chamada 2 MC PAR VL Chamada 1 MC PAR VL Chamada K Configuração da Pilha de Execução na Chamada K

PAR MC VL

= Memória de Controle (para retorno da chamada) = Memória relativa aos parâmetros da chamada = Memória relativa às variáveis locais da chamada

Figura 26: Configurac¸˜ao da pilha de execuc¸˜ao ap´osk-´esima chamada recursiva.