Escolar Documentos
Profissional Documentos
Cultura Documentos
CAPíTULO 6
Conceituação:
Sub-programas são partes de um programa que podem ser consideradas como tarefas relativamente
independentes das demais. Por isso, podem ser programadas de forma separada, recebem um nome, e depois
podem usadas várias vezes dentro do programa bastando serem “chamadas” pelo nome.
Há duas categorias clássicas de sub-programas: funções e procedimentos.
Funções:
Uma função é um sub-programa que realiza uma tarefa de calcular e produzir como resultado um valor, o qual
será usado por outras partes do programa:
Ex: o programa abaixo usa a função pré-definida sqrt(n), que calcula a raiz quadrada de um real n, e dá como
resultado um valor real:
Exemplo 6-1:
program ex6_1;
var L1,L2,H: real;
begin
L1:= 3.0;
L2:= 4.0;
H:= sqrt(L1*L1+L2*L2);
writeln('A hipotenusa do triangulo retangulo de lados ', L1:3:1, ' e ',
L2:3:1, ' e'' ' ,H:3:1);
end.
No exemplo acima, a função sqrt já vem pré-definida na linguagem Pascal, e pode ser utilizada diretamente.
Note o seguinte:
a) a função tem um argumento real n, ou seja, para usá-la é preciso fornecer um valor real entre parênteses. A
definição de uso é sqrt(n) onde n deve ser um valor real.
b) esse argumento pode ser qualquer expressão real, no exemplo foi L1*L1+L2*L2.
c) a função realiza uma tarefa, através de um algoritmo próprio, para calcular a raiz quadrada. Essa tarefa
constitui o sub-programa, que nesse caso já está armazenado no computador em forma compilada.
d) quando o programa for executar o comando: H:= sqrt(L1*L1+L2*L2);
vai ocorrer o seguinte:
- primeiro, a expressão do argumento será calculada, para obter o seu valor. No caso, será calculado o
valor 3.0*3.0 + 4.0*4.0 que dá 25.0.
- em seguida o programa entrará em um estado de suspensão da sua execução, e o controle da execução
passará para o primeiro comando do sub-programa sqrt.
- antes de iniciar o sub-programa, o valor calculado do argumento, no caso 25.0, será passado como valor
inicial de uma variável especial do sub-programa que representa o argumento da função. Essa variável é
chamada de parâmetro de valor e a operação é chamada de passagem de parâmetro.
- o sub-programa executará seus comandos, e a raiz quadrada do argumento será calculada, obtendo o
valo 5.0, nesse caso.
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 1/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
- ao terminar, o sub-programa repassará o valor obtido de volta para o programa. Isso é feito substituindo
a aplicação da função, sqrt(L1*L1+L2*L2), pelo resultado obtido.
- nesse ponto o controle da execução voltará para o programa no ponto em que havia interrompido, e o
programa executará o comando: H:= 5.0; continuando a execução normalmente a partir desse ponto.
Exemplo 6-2:
program ex6_2;
var
x:integer;
function fat(n:integer): longint;
var
i: integer;
f: longint;
begin
f:=1;
for i:= 2 to n do f:= f*i;
fat:= f;
end; {fim da declaracao da funcao}
As seguintes observações são importantes para um bom entendimento de funções e do programa acima:
a) A declaração da função fica na área de declarações, junto com as declarações de variáveis e constantes:
function fat(n:integer): longint;
var
i: integer;
f: longint;
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 2/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
begin
f:=1;
for i:= 2 to n do f:= f*i;
fat:= f;
end; {fim da declaracao da funcao}
b) O formato da declaração da função é bastante parecido com o de um programa, apenas no cabeçalho a
palavra program é substituída pela palavra function. A declaração da função tem sua própria área de
declarações e sua área de comandos. Mas termina com end; e não com end.
c) Além disso, no cabeçalho da função são declarados os seus argumentos, agrupados por tipo, seguidos do
tipo do resultado que produz. A forma sintática do cabeçalho é:
function <nome da função> (<lista de argumentos>:<tipo>; <lista de argumentos>: tipo; etc):<tipo do resultado>
No caso do fatorial, há apenas um parâmetro inteiro (chamado n) e o resultado será do tipo longint,
porque os fatoriais crescem muito rapidamente:
function fat(n:integer): longint;
d) No corpo da função (parte executável, começando após o primeiro begin) o nome da função deve
receber por atribuição pelo menos uma vez o valor do resultado:
fat:= f;
É dessa forma que o resultado calculado será repassado de volta ao programa, onde irá substituir a
aplicação da função. Note que, apesar de receber um valor por atribuição, o nome da função não é uma
variável. Caso o nome da função receba mais de um valor durante a execução da função, o valor que
finalmente será repassado para o programa será o último valor atribuído ao nome da função antes dela
terminar sua execução.
e) Outro ponto importante a registrar é que os identificadores definidos na função só têm significado
dentro da função, e não para fora dela. Chama-se a isso o escopo dos identificadores. No exemplo
acima, as variáveis n, i e f não são “vistas” pelo programa que usa a função, e são chamadas variáveis
locais da função. A variável n é especial, chamada de parâmetro formal de valor. É ela que receberá o
valor do argumento a ser usado no inicio da execução da função. A partir daí, os parâmetros de valor se
comportam como qualquer outra variável local.
Voltando então para a execução do Exemplo 6-2, vemos que o laço de repetição fará com que a função fat seja
chamada várias vezes, cada vez com um argumento diferente. A cada vez, o programa será interrompido, o
controle será passado para a função, um resultado será obtido e repassado de volta ao programa, substituindo a
aplicação da função.
program ex6_3;
var
frase:string;
i: integer;
function maiuscula(c:char):char;
{essa funcao converte letras minusculas em maiusculas}
begin
case c of
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 3/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
'a'..'z': maiuscula:= chr(ord('A') + ord(c)-ord('a'));
else maiuscula:= c;
end;
end;
begin
writeln('Digite uma frase. Ela sera'' re-escrita em letras maiusculas: ');
readln (frase);
for i:=1 to length(frase) do frase[i] := maiuscula(frase[i]);
writeln(frase);
end.
Note que a função foi aplicada a um argumento do tipo char, e que o valor resultante também é do tipo char.
Para alterar as letras da string frase, foi necessário usar um laço de repetição para aplicar a função
sucessivamente a cada caractere da frase.
No próximo exemplo, a função será aplicada a toda a frase de uma vez (o argumento é do tipo string) e o
resultado também será do tipo string, isto é, a função retorna a frase inteira alterada:
program ex6_4;
var
frase:string;
i: integer;
function maiusc_str(s:string):string;
{essa funcao retorna uma string com todas as letras maiusculas}
var i: integer;
begin
for i:= 1 to length(s) do
case s[i] of
'a'..'z': s[i]:= chr(ord('A') + ord(s[i])-ord('a'));
end;
maiusc_str:= s;
end;
begin
writeln('Digite uma frase. Ela sera'' re-escrita em letras maiusculas: ');
readln (frase);
writeln(maiusc_str(frase));
end.
Uma observação importante: a função não altera a string frase. Ela retorna outra string, com as letras alteradas,
que substituirá a expressão maiusc_str(frase). É essa string retornada que será impressa. O valor original
da string frase não foi alterado.
No exemplo seguinte, a função cripto(c,n) onde c é um caractere, e n é um inteiro, positivo, tem o seguinte
valor:
- se c for uma letra (maiúscula ou minúscula), cripto(c,n) retorna a letra n posições adiante no alfabeto,
considerado circular (depois do ‘z’ vem o ‘a’, depois do ‘Z’ vem o ‘A’). Ex: cripto(‘Z’, 3) retorna
‘C’
- se c for um dígito, cripto(c,n) retorna o dígito n posições adiante, também circular (depois do ‘9’ vem o
‘0’)
Ex: cripto(‘3’, 11) retorna ‘4’.
- para qualquer outro caractere, a função retorna o próprio caractere sem alteração.
Esse exemplo é mais complexo, e é interessante para ressaltar a importância de se separar as tarefas em sub-
programas separados. Dessa forma, o programa que usa a função fica muito mais compreensível, e também a
função pode ser testada e aperfeiçoada independentemente dos programas que a usarão. O programa que usa a
função é bem simples, e toda a complexidade da criptografia fica encapsulada na definição da função.
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 4/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
Exemplo 6-5:
program ex6_5;
var
frase: string;
i,n: integer;
Procedimentos
O exemplo abaixo ilustra a declaração e o uso de um procedimento de nome msg, que faz a tarefa de escrever
uma mensagem (uma string) em um ponto determinado da tela:
Ele utiliza um procedimento pré-definido em Pascal, gotoxy(x,y), que posiciona o cursor no ponto
correspondente à interseção da linha y com a coluna x:
Exemplo 6-6:
program ex6_6;
uses crt; {necessario para usar gotoxy e clrscr}
var linhamedia,colunamedia: integer;
m:string;
procedure msg(frase:string; x,y: integer);
begin
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 5/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
gotoxy(x,y);
write(frase);
end;
begin
clrscr;
msg('esta frase na linha 1 coluna 1', 1, 1);
msg('esta frase na linha 3 coluna 2', 2, 3);
msg('esta frase na linha 5 coluna 3', 3, 5);
m:= 'meio da tela';
linhamedia:=12;
colunamedia:=40;
msg(m,colunamedia-length(m) div 2,linhamedia);
end.
O procedimento msg tem 3 parâmetros formais de valor: frase, x e y. Ele é chamado 4 vezes pelo programa.
Note que cada chamada tem a forma de um comando. A cada chamada, o valor de cada parâmetro é inicializado
com o valor correspondente do argumento usado. Da mesma forma que para as funções, cada argumento usado
na chamada de um procedimento pode ser qualquer expressão que tenha valor do tipo esperado.
Existem vários comandos que usamos normalmente na linguagem Pascal que são na realidade procedimentos
pré-definidos. Os casos mais comuns são os procedimentos de leitura e escrita: read, readln, write, e writeln, são
procedimentos bastante complexos, que têm a faculdade adicional de aceitar um numero variável de
argumentos. Outros comandos, como clrscr, gotoxy, etc também são procedimentos.
Parâmetros de Referência
Até agora todos os parâmetros usados nos exemplos de funções e procedimentos foram parâmetros de valor.
Um parâmetro de valor é uma variável local do sub-programa, que tem a propriedade de receber um valor
inicial passado durante a chamada. Fora disso, comporta-se como uma variável local normal, como as demais
definidas na seção var.
As variáveis locais de um sub-programa existem em um espaço de memória próprio, que só é acessível ao sub-
programa. Por esse motivo, os parâmetros de valor não podem ser ”vistos” pelo programa externo ao sub-
programa. Apenas o resultado do cálculo da função pode retornar ao programa.
Os parâmetros de referência, ou parâmetros variáveis, permitem que valores calculados no sub-programa
possam ser repassados ao programa, de forma diferente do mecanismo de retorno de função.
O mecanismo usado no parâmetro de referência é o seguinte:
a) na definição do procedimento, os parâmetros de referência devem ser precedidos do prefixo var.
b) Na chamada do procedimento, os argumentos usados no lugar de parâmetros de referência devem ser
obrigatoriamente nomes de variáveis do programa, e não expressões.
c) Quando o procedimento é chamado, o parâmetro de referencia recebe, não mais um valor, mas uma
referência para a variável correspondente do programa. Na prática, isso significa que o parâmetro do sub-
programa, e a variável correspondente do programa, passam a ser a mesma variável, como se fossem
sinônimos. O efeito é que tudo que acontece com um parâmetro de referência do sub-programa vai se
refletir imediatamente na variável correspondente do programa. Ou seja, quando o sub-programa termina, e
devolve o controle de execução ao programa, as variáveis passadas por referência para o sub-programa
podem ter sido alteradas.
Inicialmente, os caracteres da string são colocados na matriz linha a linha, ocupando as k primeiras colunas apenas:
1 2 3 4 5 6 7 8 9 10
U N I V E R S I 1
D A D E F E D 2
E R A L D O 3
R I O D E J 4
A N E I R O 5
6
7
8
9
10
A codificação é completada reescrevendo a matriz em forma de string, desta vez escrevendo os caracteres segundo as colunas, a partir
da coluna 1, apenas para as linhas usadas.
Completando o exemplo acima, a frase codificada fica da forma seguinte:
UDERANARINIDAOEVEL IE DRRFDEOSEO ID J
O interessante é que o mesmo processo pode ser usado tanto para codificar como para decodificar. Para decodificar, toma-
se a frase codificada, desta vez com chave (no. de colunas) igual ao número de linhas usado na codificação original,
obtendo a matriz transversa abaixo:
1 2 3 4 5 6 7 8 9 10
U D E R A 1
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 7/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
N A R I N 2
I D A O E 3
V E L I 4
E D R 5
R F D E O 6
S E O 7
I D J 8
9
10
Basta usar o processo de codificação para obter a frase original, lendo coluna a coluna.
O número mínimo de linhas necessárias para codificar uma frase com ncar caracteres, e chave k, é dada pela expressão:
round(ncar/k + 0.4)
A solução abaixo usa 2 procedimentos e 2 funções.
Os procedimentos le_frase e le_chave são usados para solicitar do usuário a frase a ser codificada, e a chave a ser usada.
Ambos usam parâmetros de referência var para passar os valores lidos para o programa.
A função linhas_necessarias(f, k) calcula e retorna o menor número de linhas necessárias para codificar a frase f com a
chave k.
A função codifica(frase,k) é que faz o trabalho de codificar a string frase com a chave k, e retorna a string codificada. A
função utiliza o procedimento limpa_matriz, para inicializar os elementos da matriz com espaços em branco. Note que o
procedimento é interno à função, e que a matriz é acessada como variável global ao procedimento, não sendo necessário
passar parâmetro.
A função usa uma matriz 10x10, podendo acomodar frases de até 100 caracteres.
O programa propriamente dito consiste apenas de chamadas dos procedimentos. Todo o trabalho real é feito nos sub-
programas, o programa apenas coordena a chamada dos mesmos para realizar uma tarefa completa.
program codifica_matr;
{Este programa codifica textos usando o metodo da matriz transposta}
var
frase: string;
chave:integer;
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 8/9
22/08/2018 ALGORITMOS COM PASCAL - CAP. 6
lin:= (i- 1) div colunas+1;
col:= i mod colunas; if col=0 then col:=colunas;
m[lin,col]:= frase[i];
end;
s:='';
for j:=1 to colunas do
for i:= 1 to linhas do s:=s+m[i,j];
codifica:=s;
end; {codifica}
begin
le_frase(frase);
le_chave(chave);
frase:=codifica(frase,chave);
writeln('Frase codificada com a chave ', chave,': ', frase);
chave := linhas_necessarias(frase, chave);
frase:= codifica(frase,chave);
writeln('Decodificando com a chave ', chave, ': ', frase);
readln;
end.
http://www.dcc.ufrj.br/~jonathan/docsPascal/apostila/capitulo6.html 9/9