Beruflich Dokumente
Kultur Dokumente
13 de agosto de 2009
Sumário
1 Introdução 2
4 Operadores 7
5 Estruturas de controle 8
5.1 Estruturas condicionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.2 Laços . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5.2.1 Para . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5.2.2 Repita-Até . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5.2.3 Enquanto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
6 Tipos avançados 13
6.1 Tipos referência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.2 Estruturas ou registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6.3 Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
6.4 Tipos função ou funcionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
8 Exemplos 20
8.1 Algoritmo de ordenação por flutuação . . . . . . . . . . . . . . . . . . . . . . . . 20
8.2 Algoritmo identificar caminho raiz-para-folha de uma árvore ternária . . . . . . . 22
1
Especificação do Portugol v1.0, julho de 2009
1 Introdução
Este documento apresenta uma especificação da linguagem Portugol. O objetivo da linguagem
apresentada neste documento é definir um padrão de representação algorı́tmica a ser adotado
nos três blocos didáticos oferecidos pelo DIMAp: “Introdução a Técnicas de Programação”,
“Estruturas de Dados Básicas” e “Estruturas de Dados Avançadas”.
Toda linguagem possui idiomas próprios (formas padronizadas de resolver determinados pro-
blemas). Elas possuem caracterı́sticas e particularidades, fazendo com que a implementação de
uma determinada ideia siga uma abordagem ou outra. Com o Portugol não será diferente. Po-
rém, procuramos especificar uma linguagem mais genérica possı́vel. A seguir serão apresentados
os componentes da linguagem através de uma definição genérica, seguida de exemplos.
A geração dos algoritmos foi realizada via LATEX, utilizando-se o pacote algorithm2e1 .
2.2 Variáveis
A declaração de variáveis dos tipos básicos é realizada através da palavra reservada var. Mais
de uma variável pode ser declarada ao mesmo tempo, contando que elas sejam do mesmo tipo.
Após declarar uma variável (e seu tipo), pode-se atribuir apenas os valores pertinentes ao tipo
em questão. A atribuição é realizada através do operador ‘←’. A atribuição pode ser feita a
qualquer momento após e/ou durante a declaração da variável. Porém, para evitar confusão
1
http://www.ctan.org/tex-archive/macros/latex/contrib/algorithm2e/
Página 2
Especificação do Portugol v1.0, julho de 2009
de valores, não será permitida a atribuição conjugada com inicialização para situações onde são
declaradas duas ou mais variáveis simultaneamente.
Os exemplos apresentados no Quadro 1 ilustram a declaração de variáveis utilizando os tipos
básicos apresentados anteriormente.
var i : inteiro # 1o : declarando uma única variável inteira ‘i’ (sem inicializaç~ao)
i←0 # 2o : inicializando a variável inteira ‘i’ com zero
# alternativamente podemos combinar as duas operaç~oes acima. Veja:
var i : inteiro ← 0
var x, y : real # declarando duas variáveis reais ‘x’ e ‘y’
var achou : booleano ← falso # declarando e inicializando uma variável lógica ‘achou’
var nome : texto ← “Portugol” # declarando e inicializando uma cadeia de caracteres
var c : caractere ← nome[1] # declarando e inicializando uma variável caractere com ‘o’
var vet : arranjo de 10 real # declarando e fazendo uso de arranjos
var j : inteiro ← tam vet − 1 # ‘j’ é inicializado com o ı́ndice da última posiç~ao de ‘vet’
var z : real ← vet[i] # ‘z’ é inicializado com o valor do último elemento de ‘vet’
# Arranjo unidimensional de 10 inteiros
var V et : arranjo de 10 inteiro
# Arranjo bidimensional de caracteres com 25 linhas e 10 colunas (ordem linha-coluna )
var M at : arranjo de 25 × 10 caractere
# arranjo unidimensional de cadeia de caracteres com 2 posiç~oes, já inicializadas
var MOpcoes : arranjo de 2 texto ← [“Inserir”, “Sair”]
2.3 Constantes
Constantes são variáveis que são declaradas e inicializadas simultaneamente, cujo valor não pode
mais ser modificado. Veja exemplos deste tipo de declaração a seguir, no Quadro 2. É importante
ressaltar que, na definição de valores constantes, não é usado o operador de atribuição ‘←’ (como
ocorre na atribuição de variáveis), e sim o operador de definição ‘≡’. Note, em vermelho na linha
5, uma definição incorreta para uma constante, devido à falta da inicialização.
Página 3
Especificação do Portugol v1.0, julho de 2009
de um tipo é realizada através da palavra reservada tipo, seguida do nome do tipo a ser definido,
do separador ‘≡’ seguido de uma expressão de tipo. Após definido, um novo tipo pode ser usado
de maneira similar aos tipos primitivos de Portugol.
A expressão de tipo pode ser um conjunto de valores predefinidos ou construtores de tipos.
O Quadro 3 ilustra a construção, declaração e uso de um novo tipo, bem como a definição de
novos tipos baseados em outros já existentes.
Quadro 3: Exemplo de uma definição de tipo naipe e outros tipos baseados em arranjos.
Página 4
Especificação do Portugol v1.0, julho de 2009
programa
# declaraç~ao de variáveis locais ao programa principal
1 var nota1: real ← 1.5
2 var nota2: real ← 6.7
3 var nota3: real ← 8.9
4 var media: real
# calcula a média ponderada do aluno e imprime
5 media ← calculaMedia(nota1, nota2, nota3 )
6 imprime(“Fulano Filho”, media)
fim
# calcula a média ponderada de 3 valores reais, retornando o resultado, um real
7 função calculaMedia(nota1: real; nota2: real; nota3: real): real
8 var mediaP onderada: real
9 mediaP onderada ← (4 × nota1 + 5 × nota2 + 6 × nota3)/15
10 retorna mediaP onderada
11 fim
# imprime o nome do aluno e sua média. Repare que n~ao há valor de retorno
12 procedimento imprime(nome: texto; media: real)
13 escreva ( “A média de ”, nome, “ é ”, media)
14 fim
Página 5
Especificação do Portugol v1.0, julho de 2009
Página 6
Especificação do Portugol v1.0, julho de 2009
4 Operadores
Os operadores do Portugol, devido à sua flexibilidade, podem ser definidos à medida que forem
sendo necessários. Os operadores matemáticos têm precedência sobre os relacionais, que por sua
vez têm maior precedência sobre os operadores lógicos. A seguir são apresentados os operadores
mais básicos do Portugol.
As tabelas 1, 2 e 3 apresentam os operadores matemáticos, relacionais e lógicos básicos,
respectivamente. Eles são listados em ordem de precedência, do maior para o menor.
Página 7
Especificação do Portugol v1.0, julho de 2009
5 Estruturas de controle
5.1 Estruturas condicionais
As estruturas condicionais controlam o fluxo de execução de acordo com a avaliação de uma
expressão. Existem vários tipos de estruturas condicionais, que devem ser selecionados de acordo
com o algoritmo. O Quadro 7 ilustra exemplos de uma estrutura condicional simples, uma
composta e uma encadeada.
A estrutura condicional se encadeada permite definir vários blocos, onde apenas um será
executado. Os testes são efetuados do primeiro ao último bloco. O bloco cujo teste se averiguar
verdadeiro primeiro será executado, e os demais desprezados. Uma outra forma de realizar essa
escolha de blocos é através da estrutura de seleção múltipla, ou caso. A diferença é que esta
prevê uma comparação de igualdade entre uma variável e cada um dos casos definidos. Ela
é, portanto, mais fácil de se ler nesses casos especı́ficos. Opcionalmente, pode-se definir uma
última opção que será executada, caso nenhuma igualdade seja validada. O Quadro 8 apresenta
um exemplo desta estrutura de controle.
Página 8
Especificação do Portugol v1.0, julho de 2009
Página 9
Especificação do Portugol v1.0, julho de 2009
5.2 Laços
Os laços são estruturas de controle que executam um bloco de comandos um certo número de
vezes. O controle sobre a quantidade de vezes que o bloco é executado pode ser:
. de acordo com uma certa condição testada no inı́cio do bloco (executa o bloco de 0 à N
vezes);
. de acordo com uma certa condição testada no fim do bloco (executa o bloco de 1 à N
vezes);
. por um número pré-determinado de vezes (executa o bloco de 0 à N vezes); ou
. para cada ocorrência em um conjunto de entradas.
5.2.1 Para
Existem várias formas de se definir um laço através da estrutura para. O mais comum possui
um número de execuções pré-determinado, definido numericamente. Este tipo de controle de
laço é ideal, por exemplo, quando se deseja acessar variáveis indexadas, como arranjos e textos.
Neste caso, o ı́ndice utilizado para controlar a iteração do laço pode ser usado como indexador
do arranjo (usado, por exemplo, para implementar um vetor ou matriz).
Outra forma de utilizar a estrutura para é percorrer os elementos de um conjunto (arranjos
ou tipos abstratos de dados, a serem explicados mais a frente; por hora, considere um conjunto
como um elemento matemático abstrato). De fato, quando se deseja percorrer elementos em um
conjunto, o laço para é a melhor opção por manter um bom nı́vel de abstração (não interessa
saber, no momento, como cada um dos elementos do conjunto é acessado). Neste caso, a forma
de utilizá-lo é, entretanto, ligeiramente diferente. Utiliza-se a expressão para todo seguida de
uma variável que assumirá o valor de um elemento do conjunto a cada iteração do laço e a
expressão de pertinência a um conjunto.
O Quadro 9 apresenta vários exemplos de uso desse tipo de laço.
5.2.2 Repita-Até
Outro tipo comum de laço realiza o teste de parada ao final de cada iteração do bloco. O
comando ‘repita-até’ é a estrutura de controle com esta caracterı́stica. Nessa estrutura, o laço
termina quando a expressão no final do bloco se torna verdadeira. O uso dessa estrutura é
recomendado quando se deseja que o bloco seja executado pelo menos uma vez. O Quadro 10
provê um exemplo desta estrutura de controle.
5.2.3 Enquanto
Outra estrutura de controle de laço bastante comum é o enquanto, que realiza o teste de
continuidade do laço antes de cada iteração do bloco. Nessa estrutura, o laço termina quando a
condição especificada no inı́cio do bloco passa a ser falsa. Diferentemente da estrutura repita-
até, o uso dessa estrutura é recomendado quando o bloco pode não ser executado. Ou seja, se a
expressão condicional no inı́cio do bloco for falsa, não haverá iteração alguma e a sequência de
instruções passa para o comando após o bloco. O Quadro 11 fornece alguns exemplos de laço
enquanto.
Página 10
Especificação do Portugol v1.0, julho de 2009
s←0
para i de 1 até 100 faça # a cada iteraç~ao, i assume o valor de 1 a 100
se i%2 = 0 então
s ← 1/i
senão
s ← −(1/i)
fim
fim
escreva ( “O resultado da série é:”, s )
# ainda pode ir de trás pra frente, alterando-se o ‘passo’.
para j de 10 até 1 com passo −1 faça # j vai decrementando de 10 a 1
escreva (“Mensagem #”, j, “impressa!”)
fim
# acessando elementos de um vetor
produtoInterno ← 0
para k ← 0 até 2 faça
produtoInterno ← produtoInterno + (V et1[k] × V et2[k])
fim
para todo i ∈ S1 faça # a cada iteraç~ao, i assume um elemento do conjunto S
remova i de S1
insira i no conjunto S2
fim
Página 11
Especificação do Portugol v1.0, julho de 2009
Página 12
Especificação do Portugol v1.0, julho de 2009
6 Tipos avançados
6.1 Tipos referência
Uma referencia2 é um tipo que contém o endereço (daı́ o nome, referência) de uma variável de
um tipo qualquer. A declaração de variáveis do tipo referencia é realizada através do operador
ref seguido do tipo da variável que será referenciada.
Além do operador ref, usado na declaração da variável, há dois outros operadores associados
às referências. O primeiro é o operador de endereço (end) que, quando aplicado a uma variável,
retorna o endereço (referência) onde o valor desta variável está sendo armazenado na memória.
O segundo operador é chamado o operador de desreferência, que age no sentido inverso ao pri-
meiro operador. Ou seja, ele tem o papel de consultar o conteúdo de uma variável através de sua
referência. Para acessar o conteúdo, usamos o operador de acesso ‘[ ]’. Por fim, existe também
uma palavra reservada para representar o valor de uma referência vazia (que não está endere-
çando variável alguma), também chamada de referência (ou ponteiro) nulo ou representado pelo
sı́mbolo ⊥. O Quadro 12 ilustra o uso desses operadores.
Página 13
Especificação do Portugol v1.0, julho de 2009
Página 14
Especificação do Portugol v1.0, julho de 2009
6.3 Tuplas
Tipos tuplas são tipos compostos heterogêneos (como os tipos registros). Porém, ao invés de
selecionar os componentes pelo nome, a seleção é realizada por posição, como em um arranjo.
Tipos tuplas também podem ser interpretados como o equivalente computacional do produto
cartesiano da matemática. Cada componente de uma tupla pode ser acessado em leitura ou em
escrita individualmente. O Quadro 16 ilustra seu uso.
Quadro 15: Declaração de tipo heterogêneo (tupla), e de uma variável desse tipo com inicialização.
3
Um exemplo clássico é a função qsort fornecida pela biblioteca padrão de C.
Página 15
Especificação do Portugol v1.0, julho de 2009
Quadro 16: Declaração de 3 funções com a mesma assinatura (parâmetros e retorno), seguida da declaração de
um tipo função com a mesma assinatura. Assim variáveis do tipo função podem assumir o valor de qualquer uma
das 3 funções definidas anteriormente.
Página 16
Especificação do Portugol v1.0, julho de 2009
4
Normalmente estes elementos, quando traduzidos para uma linguagem de programação, são armazenados em
arquivos separados.
Página 17
Especificação do Portugol v1.0, julho de 2009
Página 18
Especificação do Portugol v1.0, julho de 2009
Quadro 18: Declaração de tipo TAD, com interface separada da implementação e do código cliente.
Página 19
Especificação do Portugol v1.0, julho de 2009
8 Exemplos
Nesta seção apresentaremos alguns exemplos de algoritmos completos, ilustrando o máximo
possı́vel de estruturas de controle através de exemplos apresentados na disciplina de Algoritmos
e Estruturas de Dados I.
Os exemplos aqui exibidos possuem uma diferença sutil para os exemplos apresentados em
seções anteriores. Utilizando-se de uma caracterı́stica de configuração do pacote algorithm2e,
é possı́vel substituir a palavra fim que marca o fim de um bloco de comandos por uma linha
simples. Com isso, obtém-se um código mais compacto, ideal, por exemplo, para slides de aula.
Página 20
Especificação do Portugol v1.0, julho de 2009
Quadro 19: Exemplo de algoritmo que realiza a ordenação por flutuação (bubble sort) sobre uma lista encadeada
simples. Os elementos a serem ordenados são inteiros e serão dispostos em ordem não decrescente pelo algoritmo.
Página 21
Especificação do Portugol v1.0, julho de 2009
5
/ | \
4 7 8
/ | / | \
11 13 4 6 21
/ \ \ /
7 2 1 3
caminho 1: 5 4 11 7
caminho 2: 5 4 11 2
caminho 3: 5 7 13
caminho 4: 5 8 4 1
caminho 5: 5 8 6
caminho 6: 5 8 21 3
Forneça a estrutura correspondente ao nó de uma árvore ternária e escreva a função impri-
meCaminhos() que, dado uma árvore ternária, imprime todos seus caminhos raiz-para-folha, um
por linha. O Quadro 21 apresenta uma solução para este problema.
Página 22
Especificação do Portugol v1.0, julho de 2009
Quadro 20: Algoritmo que identifica os caminhos para raiz de uma árvore ternária.
Página 23