1 Curso Profissional de Gestão e Programação de Sistemas Informáticos Programação e Sistemas de Informação Módulo 3 Subprogramas Prof. Sandra Pais Soares
Conteúdos Conceitos básicos Variáveis: globais e locais Passagem por parâmetros Subprogramas Estrutura do subprograma: procedimentos e funções recursividade
3 Subalgoritmos As partes em que um algoritmo pode ser dividido são chamadas subalgoritmos. Em programação, os subalgoritmos podem ser designados, genericamente, por subprogramas. Em Pascal, os subprogramas podem ser de dois tipos: procedure (procedimento) subprograma ou rotina que efectua um determinado conjunto de tarefas. function (função) subprograma ou rotina que, para além de poder realizar um conjunto de operações (tal como o procedimento), tem a particularidade de devolver um determinado valor no ou nos pontos do programa em que for chamado ou utilizado. Os subprogramas destinam-se principalmente a: permitir a criação de rotinas ou partes de código que podem ser usadas mais do que uma vez num programa. ajudar a estruturar melhor o programa, permitindo que determinadas porções de código sejam escritas de uma forma mais autónoma e que a leitura do programa resulte mais fácil e compreensível.
4 Subalgoritmos Algoritmo que calcula e escreve uma certa quantidade de múltiplos de um número base, sendo os valores fornecidos pelo utilizador Program Multiplos; Var num, quant, i, mult: integer; writeln( cálculo de múltiplos ); writeln( Introduza um número ); readln(num); writeln( Quantos múltiplos quer? ); readln(quant); for i:=1 to quant do begin end mult := i*num; writeln(mult) Program Multiplos; Var num, quant, i, mult: integer; Procedure OberDados; writeln( cálculo de múltiplos ); writeln( Introduza um número ); readln(num); writeln( Quantos múltiplos quer? ); readln(quant); Procedure CalcularMultiplos; for i:=1 to quant do begin mult := i*num; writeln(mult) end ObterDados; CalcularMultiplos;
5 Subalgoritmos Em Pascal, os subprogramas têm de ser escritos na parte declarativa do programa, portanto, antes de ser iniciada a parte operativa do programa principal. No programa anteriormente apresentado, partimos de dois procedimentos, a que chamamos obterdados e calcularmultiplos. Na parte operativa do programa principal (que começa com begin) são feitas chamadas aos procedimentos anteriormente criados.
6 Bloco de um programa, variáveis globais e locais Noção de bloco de um programa Cabeçalho do programa {opcional em Turbo Pascal} Parte declarativa {do programa principal} Variáveis, etc. Subprograma X; Parte declarativa {do subprograma} Parte operativa {do subprograma} {acções do subprograma} Parte operativa {do programa principal} {acções do programa principal} Um conjunto formado por uma parte declarativa e uma parte operativa forma aquilo que se designa por bloco. Um programa pode ter, para além do bloco principal, outros blocos particulares, que surgem como que encaixados no bloco principal, correspondendo aos subprogramas do programa principal. Quando se declara um subprograma (função ou procedimento), ele assume a forma de um bloco com as suas próprias: parte declarativa onde se declaram os dados de uso local; parte operativa onde se descrevem as operações específicas do subprograma.
7 Variáveis globais e locais Quando uma variável é declarada na parte declarativa do programa principal, diz-se que é uma variável global ou que tem um escopo global querendo isto dizer que pode ser usada em todo o programa, não só na parte operativa do programa principal, mas também dentro de qualquer subprograma. Quando uma variável é declarada na parte declarativa de um subprograma, então diz-se que se trata de uma variável local ou que tem escopo local o que implica que essa variável só pode ser utilizada dentro desse subprograma em que foi declarada. Chama-se escopo de uma variável o âmbito com que ela é declarada, ou seja, a abrangência que essa variável tem em termos de ser válida para a totalidade do programa ou só para determinado subprograma. Quando é que as variáveis devem ser declaradas como globais e quando é que devem ser declaradas como locais? Se uma variável só necessita de ser usada dentro de um subprograma e nunca para além dele, então essa variável deve ser declarada como local. Se uma variável necessita de ser utilizada nas instruções do programa principal ou em mais do que um subprograma, então deve ser declarada como global.
8 Variáveis globais e locais Program Multiplos; Var num, quant, i, mult: integer; writeln( cálculo de múltiplos ); writeln( Introduza um número ); readln(num); writeln( Quantos múltiplos quer? ); readln(quant); for i:=1 to quant do begin end mult := i*num; writeln(mult) Variáveis globais Program Multiplos; Var num, quant: integer; Procedure OberDados; writeln( cálculo de múltiplos ); writeln( Introduza um número ); readln(num); writeln( Quantos múltiplos quer? ); readln(quant); Procedure CalcularMultiplos; Var i, mult: integer; for i:=1 to quant do begin mult := i*num; writeln(mult) end ObterDados; CalcularMultiplos; Variáveis globais Variáveis locais
9 Procedimentos e funções Subprogramas em Pascal Procedure P Function F F:= Valor X Chamada ao procedimento P Programa Principal Com chamadas aos subprogramas { } P; X:=F write (F) { } Chamadas à função F
10 Diferença entre procedimentos e funções Como já vimos, em Pascal os subprogramas podem assumir duas formas distintas: Procedimentos Procedure Funções Function Como também já vimos, existem funções predefinidas da linguagem Pascal; porém, as funções de que estamos agora a tratar são as que podem ser definidas pelo utilizador. Uma função definida pelo utilizador pode ter uma estrutura semelhante à de um procedimento, apenas com uma diferença essencial: uma função devolve sempre um determinado resultado no momento em que for chamada ou utilizada. Isto vai implicar que o modo como uma função é declarada e chamada num programa e ligeiramente diferente do que se passa com um procedimento.
11 Diferença entre procedimentos e funções Como já vimos, existe uma função predefinida em Pascal que se destina a calcular o quadrado de um número. Trata-se da função SQR(x) em que x é o argumento, ou seja, o valor ou expressão a utlilizar para calcular o quadrado. Podemos, nós próprios, escrever um subprograma procedimento ou função para efectuar esse cálculo do quadrado de um determinado valor. Programa CalcularQuadrado; Var N, Q: longint; Procedure PQuadrado; Q:=N*N write ( Introduza um número ); Readln(N); PQuadrado; Writeln( O quadrado de,n, é,q) Programa CalcularQuadrado; Var N, Q: longint; Function FQuadrado: longint; FQuadrado:=N*N write ( Introduza um número ); Readln(N); Q:=FQuadrado; Writeln( O quadrado de,n, é,q)
12 Diferença entre procedimentos e funções No programa da esquerda é utilizado um procedimento (Procedure PQuadrado) para calcular o quadrado da variável global N. No programa da direita, que utiliza a função FQuaddrado (Function FQuadrado) para efetuar o mesmo cálculo. A primeira diferença que sobressai é que o cabeçalho de uma função inclui a indicação de um tipo de dados, o que não acontecia no caso de um procedimento. Neste caso, temos; Function FQuadrado: Longint; - o que quer dizer que a função FQuadrado deve devolver, sempre que for chamada, um valor do tipo longint, ou seja, inteiro longo. Por conseguinte o cabeçalho de uma função deve assumir a seguinte forma: Function Nome_da_função: Tipo_de_Dados
13 Diferença entre procedimentos e funções Uma outra diferença entre uma função e um procedimento reside na forma como cada um destes tipos de subprogramas é chamado. No caso do procedimento, a escrita do seu nome constitui, por si só, uma instrução (por exemplo: PQuadrado). Sempre que isto se verificar, o controlo do fluxo do programa passa para o procedimento e este é executado. No caso de uma função, o seu nome não basta, por si só, para ser considerado uma instrução e, por isso, tem de ser incluído numa expressão ou instrução de atribuição. Exemplo: Q:=FQuadrado; - que atribui à variável Q o valor da função. Em seguida, esse valor é escrito com: Write ( O quadrado de, N, é,q) ou Write ( O quadrado de, N, é,fquadrado); - que escreve diretamente o valor da função
14 Funções e tipos de dados Tal como já vimos, a definição de uma função implica sempre a indicação do tipo de dados que essa função terá de devolver no ponte onde for chamada. Function NomeDaFunção : TipoDeDados; As funções do tipo Booleano não podem ser utilizadas directamente em instruções de escrita, visto que um valor lógico não pode ser escrito. Assim, estas funções só podem ser utilizadas em instruções de atribuição (a variáveis do mesmo tipo Booleano) ou em estruturas de controlo. Program Nomes; Var nome1,nome2: string; Function ObterNome: String; Var nome: string; writeln( Escreva um nome ); Readln(nome) ObterNome:= nome Nome1:=ObterNome; Nome2:=ObterNome; writeln( 1º Nome,nome1, 2º nome, nome2);
15 Subprogramas, parâmetros e argumentos Exemplificação de utilização de parâmetros e argumentos em procedimentos Os parâmetros são elementos semelhantes às variáveis, mas que são inseridos nos cabeçalhos dos subprogramas, procedimentos ou funções (dentro de parênteses) e que, depois, são usados nas chamadas a esses mesmos subprogramas. Os valores indicados no lugar dos parâmetros, quando se faz uma chamada a um subprograma, são chamados argumentos. Por conseguinte: - um parâmetro é um identificador que se inclui no cabeçalho de um subprograma, como se se tratasse de uma variável, portanto, sendo de um determinado tipo de dados; - um argumento é um valor, uma expressão ou uma variável com que se faz a chamada a um subprograma, em correspondência com um determinado parâmetro com que esse subprograma foi definido no seu cabeçalho. Um subprograma pode conter um único parâmetro ou uma lista deles.
16 Subprogramas, parâmetros e argumentos Exemplificação de utilização de parâmetros e argumentos em procedimentos Em relação a cada parâmetro deve indicar-se o tipo a que ele pertence, da mesma forma que se faz com as variáveis. Se os parâmetros forem do mesmo tipo, basta separá-los por vírgulas e indicar o tipo a que pertencem. No caso de existirem parâmetros de tipos diferentes, é necessário indicar o tipo de cada um e separá-los entre si por ponto e vírgula. Uma chamada a um procedimento que tenha parâmetros tem de especificar tantos argumentos quantos os parâmetros com que o procedimento foi definido. Além disso, a ordem dos argumentos deve ter em conta a ordem dos parâmetros, bem como o tipo a que pertencem. Os argumentos utilizados nas chamadas a subprogramas podem ser valores directos, variáveis, expressões, etc., desde que compatíveis com os correspondentes parâmetros.
17 Subprogramas, parâmetros e argumentos Em relação a cada parâmetro deve indicar-se o tipo a que ele pertence, da mesma forma que se faz com as variáveis. Se os parâmetros forem do mesmo tipo, basta separá-los por vírgulas e indicar o tipo a que pertencem. No caso de existirem parâmetros de tipos diferentes, é necessário indicar o tipo de cada um e separá-los entre si por ponto e vírgula. Uma chamada a um procedimento que tenha parâmetros tem de especificar tantos argumentos quantos os parâmetros com que o procedimento foi definido. Além disso, a ordem dos argumentos deve ter em conta a ordem dos parâmetros, bem como o tipo a que pertencem. Os argumentos utilizados nas chamadas a subprogramas podem ser valores directos, variáveis, expressões, etc., desde que compatíveis com os correspondentes parâmetros.
18 Subprogramas, parâmetros e argumentos Exemplificação de utilização de parâmetros e argumentos em procedimentos Nos exemplo apresentados até aqui, os subprogramas (procedimentos ou funções) com parâmetros foram sempre definidos de forma a que, no momento em que eram chamados, os argumentos indicados, mesmo tratando-se de variáveis, apenas passavam os seus valores para o lugar dos argumentos (e nunca as próprias variáveis). Esta forma de passar valores de argumentos e parâmetros é conhecida por passagem por valor. Na passagem por referência, na chamada aos subprogramas, os argumentos correspondentes aos parâmetros têm de ser obrigatoriamente variáveis e são estas que vão ocupar o lugar dos parâmetros. Neste caso o que passa para dentro dos subprogramas não é apenas uma cópia dos valores das variáveis, mas as próprias variáveis. Assim, se os parâmetros sofrerem alterações nos seus valores, os valores das variáveis em causa também sofrem as mesmas alterações. Na passagem por referência, antes do parâmetro passado por referência tem que se escrever a palavra Var.
19 Subprogramas, parâmetros e argumentos Passagem de argumentos a parâmetros por valor e por referência Program PassagemPValor; Var N: integer; Procedure Dobro (X: integer); X:= X+X; Writeln ( X =, X) {programa principal} N:=5; Dobro(N); Write ( N =,N) {N = 5} Program PassagemPRefer; Var N: integer; Procedure Dobro (Var X: integer); X:= X+X; Writeln ( X =, X) {programa principal} N:=5; Dobro(N); Write ( N =,N) {N = 10}
20 Subprogramas, parâmetros e argumentos Passagem de argumentos a parâmetros por valor e por referência No programa da esquerda, quando é feita a chamada ao procedimento Dobro(N), a variável N apenas fornece uma cópia do seu valor (neste caso, 5). Este valor entra para o lugar de X. Como já vimos, este parâmetro sofre uma alteração do seu valor para o dobro; portanto passa a 10. Mas isto em nada altera o valor da variável N. Por isso, na última instrução de escrita do programa da esquerda surgirá: N=5, ou seja, o valor que a variável recebeu no início do programa e que não sofreu qualquer alteração dentro do procedimento Dobro. No programa da direita, quando é feita a chamada ao procedimento Dobro(N), é a própria variável N que vai tomar o lugar do parâmetro X e, assim, ficar sujeita às alterações que este parâmetro sofrer. Neste caso, na instrução X:=X+X é a própria variável global N que vai sofrer a alteração do seu valor para o dobro. Por isso, na última instrução de escrita do programa da direita surgirá: N=10, ou seja, o valor que a variável recebeu dentro do procedimento Dobro.
21 Subprogramas, parâmetros e argumentos Passagem de argumentos a parâmetros por referência Program TrocaValores; Var V1,V2: real; Procedure Troca (Var P1,P2: real); Aux:=P1; P1:=P2; P2:=Aux; 1) V1:= 1.5 V2:= 2.1 2) Troca (V1,V2) Aux:=1.5 V1:=2.1 V2:=1.5 3) V1:=2.1 V2:=1.5 V1:=1.5; V2:=2.1; Troca (V1,V2), writeln( V1 =, V1); writeln( V2 =, V2);
22 Subprogramas, parâmetros e argumentos Passagem de argumentos a parâmetros por valor e por referência Program Soma Valores; Var soma, parcela: integer; Procedure Somar (Var S: integer; P: integer); 1) Soma:=0 Parcela := 5 2) Somar (soma, parcela) S:= S+P; P:=0; Passagem por referência Passagem por valor S:=S+P => S:=0+5 = 5 P:=0 3) Soma:= 5 Parcela := 5 Soma:= 0; Parcela := 5; Somar (soma, parcela), writeln( soma =, soma); writeln( parcela =, parcela);
23 Subprogramas dentro de subprogramas Parte Declarativa.. Subprograma S1 Parte declarativa de S1.. {do bloco principal} Subprograma S1x Parte declarativa de S1x Parte operativa de S1x Subprograma S1y Parte declarativa de S1y Parte operativa de S1y Subprograma S2 Parte declarativa de S2.. parte operativa de S2. Parte operativa do bloco principal.