Thanks to visit codestin.com
Credit goes to pt.scribd.com

0% acharam este documento útil (0 voto)
146 visualizações49 páginas

Algoritmos e CLP: Guia Completo

O documento discute representações de algoritmos, incluindo fluxogramas, pseudocódigo e linguagens de programação. Ele explica que algoritmos podem ser representados graficamente ou textualmente e destaca o pseudocódigo como uma forma genérica de escrever algoritmos usando uma linguagem simples sem conhecimento de sintaxe.

Enviado por

Rafael Bonatto
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
146 visualizações49 páginas

Algoritmos e CLP: Guia Completo

O documento discute representações de algoritmos, incluindo fluxogramas, pseudocódigo e linguagens de programação. Ele explica que algoritmos podem ser representados graficamente ou textualmente e destaca o pseudocódigo como uma forma genérica de escrever algoritmos usando uma linguagem simples sem conhecimento de sintaxe.

Enviado por

Rafael Bonatto
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 49

Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Estudo de Algoritmos com comentários para CLP


(Controlador Lógico Programável)

Paulo Ricardo Siqueira Soares

Data: Dezembro/2018

p. 1 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Sumário
Algoritmos................................................................................................................................. 3
1.1 Formas de Representação de um Algoritmo ........................................................... 4
1.2 Execução de Algoritmos de Pseudocódigos ............................................................. 7
1.3 Estruturas de Controle............................................................................................ 20
1.4 Variáveis Indexadas ................................................................................................ 31
1.5 Vetores Dinâmicos .................................................................................................. 34
1.6 Modularização ........................................................................................................ 35
1.7 Recursividade.......................................................................................................... 38
1.8 Caderno de Exercícios ............................................................................................. 39

p. 2 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Algoritmos

Para resolver um problema no computador é necessário que seja primeiramente


descrever este problema de uma forma clara e precisa. Com a descrição do problema
em mãos, é necessário elaborar uma sequência de passos que permitam solucionar o
problema de uma maneira automática e se necessário repetitiva. Além disto, é preciso
definir como os dados que serão processados, irão ser armazenados no computador.
Portanto, a solução de um problema através de um sistema controlado por computador
ou qualquer tipo de autômato, é baseada em dois pontos: a sequência de passos e a
forma como os dados serão armazenados no computador. A sequência de passos é o
que chamamos de algoritmo. O exemplo mais clássico de um algoritmo é a receita de
um bolo, por isso é comum falar que o algoritmo é a receita de como resolver o
problema.

“Diferentes algoritmos podem realizar a mesma tarefa usando um conjunto diferenciado


de instruções em mais ou menos tempo, espaço ou esforço do que outros. Tal diferença
pode ser reflexo da complexidade computacional aplicada, que depende de estruturas
de dados adequadas ao algoritmo. Por exemplo, um algoritmo para se vestir pode
especificar que você vista primeiro as meias e os sapatos antes de vestir a calça enquanto
outro algoritmo especifica que você deve primeiro vestir a calça e depois as meias e os
sapatos. Fica claro que o primeiro algoritmo é mais difícil de executar que o segundo
apesar de ambos levarem ao mesmo resultado.” (Wikipédia:
http://pt.wikipedia.org/wiki/Algoritmo)

Um programa de computador ou de CLP (Controlador Lógico Programável) é


essencialmente um algoritmo que diz a unidade automata os passos específicos e em
que ordem eles devem ser executados, como por exemplo, os passos a serem tomados
para calcular a quantidade de peças produzidas por uma determinada máquina. Logo, o
algoritmo pode ser considerado uma sequência de operações que podem ser simuladas
por uma máquina de Turing completa.

Nota de Curiosidade:
É um dispositivo imaginário que formou a estrutura para fundamentar a ciência da
computação moderna. Seu inventor, o matemático Alan Mathison Turing, mostrou que
a computação das operações de leitura, escrita e exclusão de símbolos binários
poderiam ser satisfeitas por uma máquina que continha uma fita de comprimento
ilimitado, com quadrados de tamanho definido sobre ela e um dispositivo com um
número finito de estados, que realizava as operações na fita.
Em 1936 foi formalizado o termo algoritmo: um conjunto finito de instruções simples e
precisas, que são descritas com um número finito de símbolos.
“Qualquer processo aceito por nós homens como um algoritmo é precisamente o que
uma máquina de Turing pode fazer” (Alonzo Church, matemático).
O Procedimento de execução de um algoritmo, envolve o processamento dos dados a
partir da leitura de uma fonte de entrada que após ser processada conforme a lógica
contida nos passos do algoritmo, retorna um valor em uma saída com o resultado do
processamento, sendo geralmente este processamento realizado com o auxilio de uma
ou mais estrtura de dados.

p. 3 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

1.1 Formas de Representação de um Algoritmo

Um algoritmo pode ser representado através de algumas formas, por exemplo:

a) Através de uma língua (português, inglês, etc.): forma utilizada nos manuais de
instruções, nas receitas culinárias, bulas de medicamentos, etc.;
b) Através de uma linguagem de programação (Pascal, C, Delphi, Java, SCL, C#,
etc.): Esta é a forma utilizada geralmente por programadores experientes, que pulam a
etapa de desenvolvimento de um algoritmo formal antes de iniciar sua programação;
c) Através de representações gráficas: são muito recomendáveis, já que a
ilustração gráfica do problema, muitas vezes substitui várias palavras e torna a
assimilação mais fácil, principalmente para os programadores iniciantes.

Cada uma dessas formas de representar um algoritmo, possuem suas particularidades


atribuindo a elas, vantagens e desvantagens, a melhor forma de se apresentar será a
qual o programador ou o grupo de programadores está mais familiarizado ou se
sentem mais confortáveis para elaborar seus algoritmos.

Neste caso vamos falar um pouco mais sobre algumas formas de representação de
algoritmos:

Fluxograma (Diagrama de Fluxo)

Os Fluxogramas ou Diagramas de Fluxo são uma representação gráfica que utilizam


formas geométricas padronizadas ligadas por setas de fluxo, para indicar as diversas
ações (instruções) e decisões que devem ser seguidas para resolver o problema em
questão. Eles permitem visualizar os caminhos (fluxos) e as etapas de processamento de
dados possíveis e, dentro destas, os passos para a resolução do problema.

Desvantagens:
• Fluxogramas detalhados podem obscurecer a estrutura do programa.
O detalhamento através de textos dentro da estrutura gráfica causa confusão visual,
obscurecendo a estrutura principal do programa.

p. 4 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Simbologia para Fluxogramas:

Início e Final de Fluxograma

Operação de Entrada de Dados

Operação de saída de Dados

Atribuição de Valores, Cálculos,


Expressões e Processo

Decisões

Português Estruturado (Pseudocódigo, Portugol ou Pseudolinguagem)

O Pseudocódigo será abordado de maneira mais profunda nesse material, por ser a
base para a programação em linguagens não gráficas, a qual pertence a S7-SCL,
Schneider ST (Structured Text ST), Rockwell Structured Text, Beckhoff Structured Text,
etc.

Pseudocódigo é uma forma genérica de escrever um algoritmo, utilizando uma


linguagem simples sem necessidade de conhecer a sintaxe de nenhuma linguagem de
programação. Um pseudocódigo, não pode ser executado num sistema real
(computador) — de outra forma deixaria de ser pseudo, assim, o português Estruturado
na verdade é uma simplificação extrema da língua portuguesa, limitada a pouquíssimas
palavras e estruturas que têm significado pré-definido, pois se deve seguir um padrão.

Os livros sobre a ciência de computação utilizam frequentemente o pseudocódigo para


ilustrar os seus exemplos, de forma que todos os programadores possam entendê-los
(independentemente da linguagem que utilizem).

No caso da língua portuguesa existam alguns interpretadores de pseudocódigo, nenhum


tem a projecção das linguagens C, Pascal ou BASIC, que no caso da língua inglesa se
assemelham bastante a um pseudocódigo.

p. 5 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Um programa para compilar um código em portugol é o VisuALG pode ser baixados


gratuitamente de qualquer site de busca como o Google.
Embora o Português Estruturado seja uma linguagem bastante simplificada, ela possui
todos os elementos básicos e uma estrutura semelhante à de uma linguagem de
programação de computadores.
Portanto, resolver problemas com português estruturado pode ser uma tarefa tão
complexa quanto à de escrever um programa em uma linguagem de programação
qualquer só não tão rígida quanto a sua sintaxe, ou seja, o algoritmo não deixa de
funcionar porque nos esquecemos de colocar um ‘;' (ponto-e-vírgula), por exemplo, já
um programa não funcionaria.

Os vocábulos desta metodologia são divididos em duas categorias: de aplicação pré-


determinada, chamadas palavras reservadas e de definição customizada (durante
criação do algoritmo), mas com regras pré-estabelecidas. Palavras reservadas podem
ser comandos ou elementos de estruturas. Os comandos são invocações de tarefas
específicas nos algoritmos, por exemplo, um comando de impressão deve imprimir uma
mensagem de texto. A invocação de um comando é conhecida como chamada do
comando. Os elementos de estruturas associam-se nas estruturas de controle para
efetuar decisões ou repetições (dependendo do contexto).
As regras de sintaxe de um algoritmo tratam-se das restrições pré-estabelecidas para
possibilitar a criação de pseudocódigos. Neste texto são definidas várias regras de
sintaxe e mantidas até o final. É bom lembrar que tais regras não são universais, mas
que em qualquer apresentação de metodologia algorítmica, um conjunto de regras de
sintaxe se mostrará necessário para garantir concisão e clareza dos algoritmos.
A palavra semântica será esporadicamente utilizada para se referir ao significado lógico
dos elementos ou estruturas que constituem um algoritmo.
Isso é importante porque muitas construções feitas não são intuitivas e a compreensão
só será possível se houver prévio conhecimento do que elas se propõem a fazer.
Algoritmos em pseudocódigo apresentam-se como um texto contendo diversas linhas
de código. Uma mesma linha pode conter um ou mais comandos ou ainda estruturas de
controle. Várias linhas de código podem estar encapsuladas por um conceito lógico
denominado bloco. O código de um bloco possui dessa forma início e fim e representa
um sub-processo do processo geral de execução do algoritmo. Veja o exemplo
esquemático:

//bloco de instruções
instrução 1
instrução 2
instrução 3

Um mesmo algoritmo pode conter diversos blocos seriados ou blocos dentro de outros
blocos. Se um bloco está dentro de outro dizemos que há aninhamento de blocos. O
aninhamento é construído por indentação, ou seja, colocando-se recuos no texto-
código para produzir uma hierarquia. Veja o exemplo esquemático:

//bloco 1
instrução 1-1
instrução 1-2
// bloco 2 indentado
instrução 2-1
instrução 2-2

p. 6 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

instrução 2-3
instrução 1-3

Neste exemplo o bloco 2 é parte integrante do bloco 1, mas tem significado lógico
independente dentro deste bloco e desta forma é indentado.
Vários níveis de indentação são permitidos num mesmo pseudocódigo.

Blocos também permitem a criação de módulos. Módulos são blocos do pseudocódigo


com ações a executarem através de uma chamada, ou seja, são comandos
personalizados. Um mesmo algoritmo pode possuir diversos módulos onde um deles,
exatamente aquele onde a execução principia, é chamado bloco principal ou função
principal.

O par de barras //, utilizado nos exemplos esquemáticos anteriores, marca a linha como
comentário de forma que a mensagem que ele precede possui apenas valor informativo.

1.2 Execução de Algoritmos de Pseudocódigos

Executar um algoritmo significa executar sequencialmente cada uma das linhas que
formam o bloco principal onde pode haver dezenas ou mesmo centenas de linhas. Não
necessariamente todas as linhas serão processadas.
Poderão ocorrer as seguintes possibilidades:
• Algumas linhas poderão ser saltadas;
• Um grupo de linhas poderá ser diversas vezes repetido;
• Um comando ou módulo poderá ser chamado principiando o processamento de
linhas de outro bloco processamento;
• Execução é encerrada porque a última linha foi executada ou porque foi suspenso
explicitamente.

O salto e a repetição em algoritmos serão estudados mais adiantes. Para suspender um


algoritmo antes da última linha utilizaremos o comando pare, como segue.

instrução 1
instrução 2
pare
instrução 3
instrução 4

Neste exemplo a execução de pare implica suspensão imediata de processamento (sem


realização das duas últimas linhas).

Linhas são elementos construtivos de textos e normalmente tem significado impreciso


em algoritmos. Ao invés de linhas consideraremos o conceito de instruções. Uma
instrução corresponde a cada porção do pseudocódigo tomada para execução.
Comumente há uma instrução por linha (o que torna linhas e instruções sinônimas),
entretanto há instruções montadas normalmente utilizando mais de uma linha.

Entrada e Saída

Dispositivo E/S

p. 7 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Dispositivos de entrada e saída, ou simplesmente E/S, são todos e quaisquer hardwares


responsáveis pelo fornecimento ou leitura de informações do/para o computador ou
equipamento autômato. A forma mais tradicional de entrada de dados ainda é a
alfanumérica e é feita através de teclados, da mesma forma por similaridade, a mais
tradicional saída de dados é visual e ocorre via monitores. Assim temos como elementos
de entrada padrão e saída padrão nos computadores teclados e monitores, porém
quando tratamos de controladores lógicos programáveis, veremos que as entradas mais
comuns são as entrada físicas digitais e as saídas mais comuns, são as saídas físicas
digitais, nesse momento iremos nos ater aos conceitos de programação para
computadores que serão utilizados também para programação de CLP, os elementos de
entrada e saída de um CLP serão discutidos mais a frente onde iremos detalhar o
funcionamento do mesmo.

Entrada Padrão

Como definimos anteriormente, o teclado é o dispositivo padrão de entrada. Todas as


informações fornecidas por teclado são alfanuméricas, ou seja, letras, números e alguns
símbolos. O processo de entrada de dados através de teclados funciona da seguinte
forma: Cada tecla pressionada gera um caractere que é armazenado num buffer.
Quando uma tecla de confirmação é por fim pressionada (ENTER), ocorre a transferência
da informação contida no buffer (esvaziamento de buffer) para seu destino final. A
sintaxe que evoca a entrada padrão será construída com a palavra reservada, leia, como
no exemplo:

leia x

Observe que todos os detalhes funcionais do dispositivo físico são ocultados e


simplificados num único comando imperativo (neste caso, “leia”).

Saída Padrão

Como já definido, a associação placa de vídeo/monitor é a saída padrão

A sintaxe que evoca o envio de dados para a saída padrão é construída aqui com a
palavra reservada, escreva, como no exemplo:

escreva ‘olá mundo!!’

Este exemplo ilustra o uso mais simples de escreva: a impressão de mensagens. Uma
mensagem é simplesmente um agregado de caracteres entre aspas simples. Uma
mensagem aparecerá na saída padrão tal como foi escrita no pseudocódigo.

Variáveis

A Memória Principal e as Variáveis

A memória principal é a memória volátil do computador ou a memória de trabalho de


um CLP, ou seja, só armazenará alguma informação enquanto corrente elétrica cruzar
seus circuitos (A memória projetada para manter informações, mesmo com o
equipamento desligado, é a memória secundária, como por exemplo, os discos rígidos

p. 8 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

nos computadores e os cartões de memória e EPROM de Sistema do CLP). Na memória


principal serão colocados os programas para que sejam executados.
Estes por sua vez precisarão de memória adicional para realizar suas tarefas.
Nos computadores modernos muitos programas podem estar em execução ao mesmo
tempo e assim concorrerem pela mesma memória livre no momento em que suas
atividades requererem mais espaço, para CLP’s devemos nos lembrar de que a
quantidade de memória é infinitamente limitada em comparação aos computadores,
por tanto deve-se sempre verificar se aplicação não irá ser maior que a memória
disponível (a quantidade de memória disponível varia com o modelo e marca de cada
CLP).
A problemática geral sobre o gerenciamento de memória em computadores é a
seguinte: como impedir que programas distintos não sejam gravados na mesma área de
memória e ainda, como impedir que eles concorram pela mesma região livre de
memória no momento em que requerem espaço adicional? De fato, esta
responsabilidade é do sistema operacional através do gerenciador de memória, o
mesmo ocorre no caso dos CLPs.

Quando falamos de CLPs não devemos nos esquecer de que os acessos a suas entradas
e saídas é através de memórias e não entradas e saídas físicas, pois no seu ciclo de
funcionamento a primeira coisa que o CLP faz é atualizar suas tabelas de entradas que
são nada mais do que áreas de memórias especiais onde o CLP armazena o estado atual
das entradas no início do scan (ciclo de execução) e no final atualiza o estados das saídas
físicas, baseado na tabela de saídas da área especial da memória destinada a ela,
falaremos mais sobre essas características em outro capítulo desse material.

E como os programas gerenciarão internamente? Para tanto existe um mecanismo


denominado vinculação: ele consiste em ligar uma entidade abstrata interna definida
no código do programa (pelo programador) a uma parte da finita memória, essas
entidades são denominadas variáveis do programa e a região a que são vinculadas de
células de memória.
Um programa pode requerer quantas células de memória adicional precisar através do
uso de variáveis. Cada variável conterá seu próprio nome e seu tipo. Devido ao caráter
formal de requisição de memória as variáveis precisam ser referenciadas no programa
antes de serem utilizadas. Esse referenciamento é denominado declaração de variáveis.

Variáveis podem ser primitivas ou derivadas. As variáveis primitivas tratam da


representação de dados elementares como números e caracteres.

Existem categorias distintas de variáveis primitivas as quais se diferenciam basicamente


pelo tipo de dados que se propõem a armazenar e pela faixa de representação destes
dados.

Variáveis derivadas (como os vetores) são aquelas constituídas por mais de um


elemento primitivo.

Os tipos de variáveis

São quatro os principais tipos primitivos de variáveis: Inteiros, Reais, Caracteres e


Lógicos. A seguir fazemos a descrição de cada um.

Tipos Numéricos: Inteiros E Reais

p. 9 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

É muito comum em programação de computadores o uso de valores numéricos. Eles


dividem-se basicamente em dois grandes grupos: o dos inteiros e o dos reais.
Frequentemente há confusão entre o conceito de inteiros e reais em computação e em
matemática. Nestas últimas tais definições correspondem a conjuntos com quantidade
infinita de números além do fato de o conjunto dos inteiros ser contido no dos reais. Em
computação valores inteiros e reais também representam conjuntos de números, mas
neste caso de quantidade finita de elementos. Além do mais a ideia de inteiros contido
nos reais não se aplica com exatidão neste caso.

Por que há finitos inteiros e reais nos tipos numéricos dos computadores?

A resposta é simples: cada célula de memória possui uma quantidade finita de bits.
Assim cada número em base decimal é representado em circuito por um layout de um
grupamento de bits (base binária) previamente vinculado a uma variável. De fato, o que
se faz é pré-estabelecer uma quantidade fixa de bytes para variáveis de um dado tipo e
verificar que faixa de valores pode ser representada. Por exemplo, com 1-byte podem-
se montar até no máximo 256 combinações de zeros e uns que poderão tanto
representar números inteiros entre -128 e 127 (denominados inteiros de 1-byte com
sinal) quanto de 0 a 255 (inteiros de 1-byte sem sinal).

Tipo Caractere

A maior parte da informação em formato eletrônico contido nos computadores em todo


mundo é textual, ou seja, é formada de caracteres das diversas linguagens naturais
(português, inglês, francês, alemão etc.). É obviamente importante desenvolver
métodos computacionais seguros que permitam o armazenamento e recuperação deste
tipo de informação.

Como uma máquina intrinsecamente numérica pode armazenar texto?

Na realidade qualquer informação registrada e recuperada por computadores ou CLPS


será binária, e ainda, após um tratamento de conversão, por exemplo, binário para
decimal, estas sequências de bits se apresentarão como números inteiros.

Então onde entram os caracteres?

Estes são mantidos por tabelas existentes em várias categorias de softwares como
editores de textos ou mesmo o próprio sistema operacional, no caso do podem ser pelo
sistema operacional ou somente dentro do software de desenvolvimento que irá fazer
a compilação para envio ao CLP para execução, irá depender da geração e tecnologia de
cada CLP e opção de seus respectivos fabricantes. Nestas tabelas há duas colunas
relacionadas: na primeira encontram-se números normalmente inteiros sem sinal; na
segunda um conjunto de grafemas de uma ou mais línguas naturais: são os caracteres.
Nestas tabelas existe um único inteiro para cada caractere e vice-versa. As tabelas de
caracteres podem ter tamanhos variados de acordo com a quantidade de bits dedicados
a representação dos valores inteiros da primeira coluna. Com 1-byte, por exemplo, tem-
se 8-bits e logo números entre 0 e 255: assim com 1-byte 256 caracteres distintos podem
ser representados.

p. 10 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Uma das mais comuns tabelas de caracteres utiliza 7-bits e denomina-se ASCII (American
Standard Code for Information Interchange, que em português significa "Código Padrão
Americano para o Intercâmbio de Informação”). Este padrão tem uso difundido em todo
o mundo e é aceito praticamente por todos os softwares de edição de texto. Neste texto
os algoritmos tomarão seus caracteres do padrão ASCII. A representação em
pseudocódigo ora aparecerá como número (que neste caso está na faixa 0 a 27-1, ou
seja, 0 a 127) ora aparecerá como o caractere propriamente dito (grafema). Neste
último caso os grafemas correspondentes serão escritos sempre entre aspas simples (‘ ’).
A seguir ilustramos parcialmente a tabela ASCII fazendo pares do valor numérico com o
caractere (entre aspas simples) equivalente:

E como funcionam os tipos caracteres em programação?

Cada variável declarada como caractere num programa armazena de fato um número
inteiro. Na maioria das implementações de linguagens de programação, as células de
memória vinculadas são de 1-byte.

Então quando se recorrem às tabelas de caracteres?

Isso acontece na impressão. A impressão é o momento onde informação é enviada para


um dispositivo (hardware) de saída como uma impressora, um disco ou a tela. Cada
hardware reage de forma diferente ao recebimento de dados para impressão: a
impressora deposita tinta em papel, no disco arquivos são criados ou têm alterados seus
conteúdos; e na tela são impressos momentaneamente imagens para leitura. Em todas
essas ações a informação textual recebe arte final pela recorrência às tabelas de
caracteres.

Tipo Lógico

Uma variável é lógica quando ela possui apenas dois valores possíveis: genericamente
Verdadeiro e Falso, ou ainda 0 e 1. Tais notações provêm da álgebra booleana e por
essa razão este tipo de dados é comumente denominado também tipo booleano.

p. 11 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Em termos de memória 1-bit seria necessário para representar variáveis lógicas.


Entretanto o que se vê na prática é o uso de 1-byte. Isso se deve ao modelo de
endereçamento das máquinas modernas efetuado byte a byte (o endereçamento bit a
bit seria custoso e ineficiente). O uso de um byte completo por booleanos é resolvido
da seguinte forma: uma variável lógica será falsa se todos os oito bits forem zeros, do
contrário será verdadeira. (Esse conceito é utilizado somente para computadores, porém
é válido aprender afinal além de CLP um programador industrial, deve conhecer IHM
(Interface Homem-Máquina) e Sistemas supervisórios que irão incorporar conceitos que
podemos afirmar serem mais computacionais).

Em algumas linguagens de programação há uma relação direta entre variáveis inteiras


de 1-byte e variáveis lógicas. Se x é uma variável lógica, por exemplo, ao receber um
valor inteiro, caso seja nulo (todos os bits iguais a 0) então a x será atribuído de fato o
valor Falso; caso contrário a x será atribuído verdadeiro. Analogicamente se y é inteiro
e a y é atribuído Falso, tal variável receberá 0; do contrário se a y for atribuído
Verdadeiro, tal variável receberá 1.

A declaração de variáveis

A primeira parte de um algoritmo computacional é normalmente a declarativa, ou seja,


nela são definidas as variáveis que serão utilizadas no restante do código. Considere o
exemplo a seguir:

declare
i: inteiro
x, y: real
b: lógico
c: caractere
//instruções do bloco de código

Este pseudocódigo ilustra como funciona a declaração de cinco variáveis: uma inteira,
chamada i, duas reais, chamadas x e y; uma lógica, chamada b; e uma de tipo caractere
chamada c. A sessão de declaração de variáveis possui a seguinte sintaxe fixa: a palavra-
chave declare marcando o início da sessão e logo abaixo a lista de variáveis endentada
em um nível para representar o bloco de variáveis. Cada linha desta lista é constituída
por um subgrupo de uma ou mais variáveis de mesmo tipo; caso haja mais de uma
variável por subgrupo, elas serão separadas por vírgulas (como ocorreu a x e y). Cada
subgrupo de variáveis encerrará em dois pontos (:) seguido pelo tipo base do subgrupo.
Os tipos primitivos base terão os nomes inteiro, real, caractere e lógico (cada qual
referindo-se aos tipos já apresentados).

O nome das variáveis normalmente aparece como um único caractere: entretanto isso
não é obrigatório. Nomes completos são legais e as regras para criá-los são as seguintes:
não são usadas palavras reservadas (como declare, pare, etc.); não são usados
caracteres especiais na grafia (como *, # ou &); não são usados espaços em branco em
um mesmo nome; números são permitidos desde que não estejam no começo do nome
(exemplo, x88 é válido, mas 5w não é); uso de underline (_) é legal. Exemplos:

declare
alpha, beta: inteiro
dia _ de _ sol: lógico

p. 12 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

x200, y _ 90, hx: real


ch _ base _ 5: caractere

Após a sessão declarativa de variáveis segue o bloco principal do algoritmo. Variáveis


declaradas e não utilizadas neste bloco deverão ser removidas.

Entrada e saída com variáveis

Depois de declaradas cada variável funcionará como uma “caixa” onde se podem colocar
valores e de onde também se podem lê-los. É importante observar que tais caixas
suportam um valor de cada vez e que desta forma a ideia de empilhamento de mais de
um valor naquele mesmo espaço é inconcebível.

Outra ideia inconcebível é a de “caixa vazia”: sempre haverá uma informação disponível
numa variável, mesmo logo após sua declaração. Normalmente esta informação não
tem sentido algum no contexto da codificação sendo meramente projeção do conteúdo
digital presente naquela célula de memória no momento da declaração.

A entrada de variáveis é feita com o comando leia ao passo que a saída pelo comando
escreva. Vejamos o exemplo a seguir:

declare
x: inteiro
leia x
escreva ‘valor fornecido =’, x

Neste exemplo leia provoca uma parada provisória da execução, aguardando a entrada
de informação seguida de uma tecla de confirmação (ENTER), uma vez que a informação
é confirmada é processada e enviada para ser armazenada no espaço (célula) de
memória reservada para a variável “x”.

A próxima instrução executada é uma chamada a escreva ele é responsável por enviar
a saída padrão o conteúdo textual contrário, envia à saída padrão (neste caso a tela)
conteúdo textual. Neste exemplo a informação escrita tem duas partes separadas por
uma vírgula: a primeira é uma mensagem de texto que será enviada para a tela tal como
foi escrita; a segunda é uma referência a célula x e neste caso a CPU necessita recorrer
à memória principal, buscar pelo conteúdo numérico em x, transformar este conteúdo
em texto e por fim enviá-lo à saída padrão.

De fato, apenas uma mensagem de texto é enviada à saída padrão: se duas ou mais
partes separadas por vírgulas estão presentes o processamento em série individual será
feito, várias componentes textuais geradas e por fim concatenadas numa única a qual
será enviada. O termo concatenação surge comumente em computação representando
a fusão de informação numa só, normalmente textual.
(Para a programação de CLPs sempre que falamos em concatenação nos referimos a
caracteres).
As vírgulas possuem papel importante tanto em leia como em escreva. Para o
comando leia a vírgula permite leitura de vários valores em uma única chamada do
comando. Veja o exemplo a seguir:

declare

p. 13 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

x, y: inteiro
leia x, y
escreva ‘A soma vale =’, x+y

Uma observação, valores lógicos não podem ser lidos ou escritos diretamente com leia
e escreva.

Se o comando leia aguarda por valores numéricos e, por exemplo, texto é digitado,
então uma conversão apropriada não poderá ser feita pela CPU e ocorrerá um erro em
tempo de execução. Nesta abordagem sobre algoritmos, quando um erro ocorre
necessariamente a execução é suspensa.

Operadores

Variáveis são vinculações com a memória real do computador e funcionam como meros
armazenadores temporários de informação digital.
Entretanto, para a construção de algoritmos funcionais, deve ser possível também
operar as variáveis entre si. Nesse contexto significa tanto alterar o conteúdo de uma
variável quanto associar duas ou mais destas em uma expressão válida para se obter um
novo valor.

Operadores são objetos de construção de algoritmos, de simbologia própria e semântica


bem definida, destinados às operações com ou entre variáveis. Por exemplo, na
expressão, a+b, o símbolo + é um operador e sua semântica é a execução da soma entre
os valores nas variáveis a e b.

Operadores podem ser unários ou binários, ou seja, podem ou operar um ou dois


operandos respectivamente.

Unários:

O exemplo mais comum de operador unário é o de mudança de sinal. A sintaxe é -x,


onde o sinal de menos é o operador, x é a variável e o valor retornado é o valor na
variável (numérica) com sinal invertido. Outro exemplo de operador unário é valor
absoluto.
A sintaxe é |x|, onde as duas barras verticais representam o operador, x é a variável e
o valor retornado é o módulo do valor na variável (numérica).

Binários:

São os que atuam em mais de uma variável como os operadores aritméticos de adição
(+) e subtração (-).

Operadores Aritméticos

Operadores unários, isto é, são aplicados a um único operando. São os operadores


aritméticos de maior precedência. Exemplos: -3, +x. Enquanto o operador
+,-
unário - inverte o sinal do seu operando, o operador + não altera o valor em nada o
seu valor.

p. 14 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Operador de divisão inteira. Por exemplo, 5 \ 2 = 2. Tem a mesma precedência do


\
operador de divisão tradicional.
Operadores aritméticos tradicionais de adição, subtração, multiplicação e divisão. Por
convenção, * e / têm precedência sobre + e -. Para modificar a ordem de avaliação
+,-,*,/
das operações, é necessário usar parênteses como em qualquer expressão
aritmética.
MOD Operador de módulo (isto é, resto da divisão inteira). Por exemplo, 8 MOD 3 = 2. Tem
ou % a mesma precedência do operador de divisão tradicional.
Operador de potenciação. Por exemplo, 5 ^ 2 = 25. Tem a maior precedência entre os
^
operadores aritméticos binários (aqueles que têm dois operandos).

Operadores de Caracteres

Operador de concatenação de strings (isto é, cadeias de caracteres), quando usado


+ com dois valores (variáveis ou constantes) do tipo "caractere". Por exemplo: "Rio " +
" de Janeiro" = "Rio de Janeiro".

Operadores Relacionais

Respectivamente: igual, menor que, maior que, menor ou igual a, maior ou igual a,
=, <, >,
diferente de. São utilizados em expressões lógicas para se testar a relação entre dois
<=, >=,
valores do mesmo tipo. Exemplos: 3 = 3 ( 3 é igual a 3?) resulta em VERDADEIRO ; "A"
<>
> "B" ("A" está depois de "B" na ordem alfabética?) resulta em FALSO.

Importante: para quem for utilizar o software para o estudo de algoritmos VisuAlg, as
comparações entre strings não diferenciam as letras maiúsculas das minúsculas.
Assim, "ABC" é igual a "abc". Valores lógicos obedecem à seguinte ordem: FALSO <
VERDADEIRO.

Operadores Lógicos

Operadores lógicos são aqueles que operam valores lógicos e retornam valores lógicos.
Utilizando a notação mais usual da álgebra booleana, montamos a listagem dos
operadores lógicos, juntamente com seus nomes conforme tabela a seguir.
Não Operador unário de negação. nao VERDADEIRO = FALSO, e nao FALSO =
¬ Negação VERDADEIRO. Tem a maior precedência entre os operadores lógicos.
Ou Operador que resulta VERDADEIRO quando um dos seus operandos lógicos
∨ Disjunção for verdadeiro.
E Operador que resulta VERDADEIRO somente se seus dois operandos
∧ Conjunção lógicos forem verdadeiros. Equivale ao AND do Pascal.
Xou
Operador que resulta VERDADEIRO se seus dois operandos lógicos forem
⊕ Disjunção
diferentes, e FALSO se forem iguais. Equivale ao XOR do Pascal.
Exclusiva

As seguintes expressões são chamadas de expressões lógicas, compostas por variáveis


lógicas e operadores lógicos, o resultado de sua avaliação é também um valor lógico.

p. 15 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Sabendo que cada variável só pode assumir os valores Falso ou Verdadeiro, é possível
fazer uma listagem das possibilidades, essas listagens são chamadas tabelas da verdade.

Expressões:

A∧B, A∨B, A⊕B, ¬A

Tabelas da Verdade

Usualmente a maioria dos operadores binários é usada infixamente e dos unários pré-
fixamente. Há situações em que operadores tradicionalmente infixos são utilizados
como pré ou pós-fixação. Em notação polonesa inversa (PEREIRA;2006), por exemplo, a
expressão, AB+, é legal e denota a soma das variáveis A e B com operador de adição pós-
fixado. Esta notação é conveniente aos computadores no que diz respeito a avaliação
de expressões (úteis no projeto de compiladores, por exemplo).

Operadores são funções, ou seja, ao invés da notação apresentada até então uma dada
operação pode ser expressa utilizando uma função nomeada com seus operandos entre
parênteses e separados por vírgula. Assim, por exemplo, a expressão, SOMA(A, B), tem
exatamente o mesmo efeito de, A+B. Na notação funcional o símbolo + é substituído
pela função SOMA(). Em outras sintaxes propostas para algoritmos, ou mesmo em
linguagens de programação, operadores são introduzidos apenas pela notação funcional.
Se um operador
não possui símbolo que permita prefixação, in-fixação ou pós-fixação, então a notação
funcional é única opção. Exemplos: logaritmo natural LN(), função exponencial EXP(),
funções trigonométricas (SEN(), COS() e etc.) entre outras.

A Atribuição

O operador de atribuição é o elemento de construção de algoritmos que expressa mais


genuinamente a essência da máquina de von Neuman (FERNANDEZ; 2009). Este
operador é o responsável pela modificação do conteúdo das células de memória
(variáveis) alocadas. Cada atribuição corresponde a uma ação da CPU que envia dados
de seus registradores para uma célula de memória alvo e cujo valor só se modificará
novamente por outra atribuição.

Atribuições podem ser explícitas ou implícitas. Numa atribuição explícita o operador ←


é utilizado para indicar que o lado direito da expressão é alvo do lado esquerdo, ou seja,
uma variável do lado esquerdo terá seu valor modificado para o valor avaliado no lado
direito. Veja o exemplo a seguir.

declare

p. 16 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

a: inteiro
x, y: real
c: caractere
a←120
x←3.253
y←a+x+23
c←’w’
escreva b, y, c

No pseudocódigo acima às variáveis a e x são atribuídos valores numéricos diretamente;


à variável y é atribuído o resultado da avaliação prévia da expressão, a+x+23 (a soma é
calculada primeiramente para então y ser modificado); à variável c é diretamente
atribuído o código ASCII de caractere ‘w’; por fim na última instrução, escreva converte
para texto, concatena e imprime b, y e c.
Se uma variável é lógica, a atribuição explicita em código dos valores Verdadeiro e Falso
é feita mediante as palavras chave V e F respectivamente.
Exemplo:

declare
a, b: lógico
a←V
b←F

De uma forma geral o lado direito de uma atribuição é primeiramente resolvido para
então o resultado encontrado ser redirecionado para à célula de memória vinculada a
variável do lado esquerdo desta atribuição. Esta forma de processamento permite que
a seguinte expressão seja legal:

x←x+y

Em casos como este a variável que aparece em ambos os lados da atribuição possui um
valor antes e outro depois da atribuição e comumente chamados de valor antigo e valor
novo da variável respectivamente. A Arquitetura de von Neuman (de John von Neuman),
é uma arquitetura de computador que se caracteriza pela possibilidade de uma máquina
digital armazenar seus programas no mesmo espaço de memória que os dados,
podendo assim manipular tais programas. A máquina proposta por Von Neumann reúne
os seguintes componentes:(1) uma memória, (2) uma unidade aritmética e lógica (ULA),
(3) uma unidade central de processamento (UCP), composta por diversos registradores,
e (4) uma Unidade de Controle (UC).

O processamento ocorre da seguinte forma: o conteúdo das células x e y são copiados


para registradores distintos da CPU; em seguida a unidade lógica aritmética desta efetua
a soma e a coloca num terceiro registrador; por fim o valor da soma é transmitido para
a célula de memória vinculada a x onde ocorrerá sobreposição de valor. Este último
passo corresponde a atribuição propriamente dita.

Atribuições implícitas ocorrem quando o comando leia é invocado. O mesmo


mecanismo de envio de uma informação para uma célula de memória alvo acontece,
porém, a origem da informação é a entrada padrão. Veja o exemplo:

declare

p. 17 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

x, y: inteiro
leia x
y←x+10
escreva ‘Resposta: ’, y
Neste pseudocódigo a variável x tem atribuição implícita ao passo que y tem atribuição
explícita, ou seja, o conteúdo na célula vinculada a x muda por ação de leia ao passo que
aquela vinculada a y muda por ação do operador ← após resolução da expressão, x+10.
Funcionalmente a execução deste algoritmo implica na leitura de um valor dado pelo
usuário e sua impressão acrescentada de 10. Veja o esquema de execução a seguir:

34 <ENTER>
Resposta: 44

Expressões

Expressões podem ser constituídas pela associação de diversas variáveis de tipos não
necessariamente compatíveis, mas que se arranjem de forma lógica e avaliável. Uma vez
definidas tais expressões, a avaliação implica num processo sistemático que finaliza num
valor final cujo tipo dependerá da expressão.

Por exemplo, na expressão, x+1 > y-p*p, resolvem-se primeiramente as expressões


aritméticas em cada lado do operador relacional para depois fazer a comparação que
resultará num valor lógico. Este procedimento de escolha de “quem operar primeiro”
numa expressão segue na verdade dois conjuntos de regras de operadores. São eles o
de precedência de operadores e de associatividade de operadores.

Precedência de Operadores

Nas primeiras lições sobre matemática ensina-se que numa expressão numérica
primeiramente devem-se fazer as divisões e multiplicações para pôr fim fazer as adições
e subtrações. Ensina-se também que se existem componentes entre parênteses elas são
prioritárias na ordem de resolução.
Sem tais regras uma expressão como, 2+4*7, seria ambígua, ou seja, com duas
possibilidades de resposta dependo de qual operação fosse realizada em primeiro lugar.
Esta predefinição de quem opera primeiramente numa família de operadores é
comumente chamada de precedência de operadores.

A ordem convencional de precedência dos operadores aritméticos, do de maior para o


de menor, é a seguinte:

(maior precedência)
abs
+, – (unários)
*, /, mod, div
(menor precedência)
+, - (binários)

A precedência convencional dos operadores lógicos é a seguinte:

(maior precedência)
¬

p. 18 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos



(menor precedência)

Por exemplo, na expressão, A⊕B∧¬C, o booleano C é primeiro invertido, depois a


conjunção entre este valor e B é feita; por fim a disjunção exclusiva fecha o processo
de avaliação e um valor final lógico é obtido.
Convencionalmente não existe precedência entre operadores relacionais, o que será
mais bem compreendido na sessão seguinte.

Associatividade de Operadores

Permitir a associatividade de operadores significa permitir que dois operadores de uma


mesma família (aritmético, relacional ou lógico) e de mesma precedência apareçam
adjacentes em uma mesma expressão sem afetar operabilidade. Por exemplo, na
expressão, A+B-C, quem deve ser feita primeira? Adição ou subtração? A forma usual
de resolver a associatividade é definindo um sentido fixo de avaliação; por exemplo, da
direita para a esquerda (no exemplo anterior a subtração seria então feita primeiro).
A associatividade nem sempre é possível. Para que dois operadores possam ser
associados o tipo da saída do operador deve ser do mesmo tipo dos operandos, do
contrário ocorrerá inconsistência. Por exemplo, a avaliação da expressão, A+B-C, da
esquerda para a direita, possui o seguinte esquema:

A+B-C
<número>+<número>-<número>
<número>+<número>
<número>

Cada redução na resolução acima transforma um par de números num novo número
que entra na etapa seguinte da avaliação. De uma forma geral, operadores aritméticos
são sempre associáveis. O mesmo não acontece na expressão, A>B>C, onde A, B e C são
inteiros. O processo de avaliação desta expressão, da esquerda para direita, é
interrompido por uma inconsistência, como se vê a seguir:
A>B>C
<número> > <número> > <número>
<número> > <lógico> //inconsistência! Não pode continuar

Este exemplo demonstra a ausência de associatividade entre operadores relacionais e


consequentemente a inexistência de precedência entre eles. A associatividade entre
operadores lógicos funciona similarmente aos operadores aritméticos.

Expressões Booleanas

Expressões booleanas são expressões cujo valor da avaliação é um lógico, ou seja,


Verdadeiro ou Falso. Expressões booleanas podem conter componentes aritméticas,
relacionais ou mesmo lógicas. A sequência de avaliação por ordem de natureza de
componentes é a seguinte:
(1). Componentes aritméticas;
(2). Componentes relacionais;
(3). Componentes lógicas

p. 19 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Se existem parênteses nas expressões então o conteúdo entre eles deve ser avaliado
primeiro obedecendo naturalmente, neste escopo, a sequência anterior. Considere o
exemplo a seguir:

x+y>50 ⊕ w<100+r ∧ w≠y-5

A seqüência esquemática de avaliação desta expressão é a seguinte:

x+y > 50 ⊕ w < 100+r ∧ w ≠ y-5


<número> > <número> ⊕ <número> < <número> ∧ <número> ≠ <número>
<lógico> ⊕ <lógico> ∧ <lógico>
<lógico> ⊕ <lógico>
<lógico>

Caso a disjunção exclusiva deva ser avaliada antes da conjunção, então o uso
apropriado de parênteses transforma a expressão em:

(x+y>50 ⊕ w<100+r) ∧ w≠y-5

Cujo esquema de avaliação agora é:

(x+y > 50 ⊕ w < 100+r) ∧ w ≠ y-5


(<número> > <número> ⊕ <número> < <número>) ∧ <número> ≠ <número>
(<lógico> ⊕ <lógico>) ∧ <lógico> //prioridade de parênteses
<lógico> ∧ <lógico>
<lógico>

1.3 Estruturas de Controle

Na criação de algoritmos, utilizamos os conceitos de bloco lógico, entrada e saída de


dados, variáveis, constantes, atribuições, expressões lógicas, relacionais e aritméticas,
bem como comandos que traduzam estes conceitos de forma a representar o conjunto
de ações. Através das estruturas básicas de controle do fluxo de execução
(sequencialização, seleção e repetição) e da combinação delas poderemos criar um
algoritmo para solucionar qualquer problema.

Estrutura Sequencial

É o conjunto de ações primitivas que serão executadas numa sequência linear, de cima
para baixo e da esquerda para a direita.

Estruturas de Seleção

Uma estrutura de seleção permite a escolha de um grupo de ações a serem executadas


quando determinadas condições, representadas por expressões lógicas, são ou não
satisfeitas.

Seleção Simples

p. 20 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

A estrutura de seleção simples é composta pelo comando “se-então”, onde a estrutura


faz uma análise de uma expressão lógica e caso ela seja verdadeira, a cadeia de
comandos aninhados a estrutura é executada, o fim dessa cadeia de comandos é
identificada pelo comando fim_se.

se condição A então
comando 1;
comando 2;
comando 3;
fim se;

Seleção composta

A estrutura de seleção composta é como uma extensão da seleção simples no qual o


operador “senão”, que entra em ação caso a expressão lógica analisada pelo comando
“se-então”, seja falsa, nesse caso o conjunto de comandos aninhados do bloco senão é
executado, identifica-se o fim da estrutura composta através do comando fim_se.

se condição A então
comando A1;
comando A2;
comando A3;
senão
comando B1;
comando B2;
comando B3;
fim se;

OBS: “Comandos B” só serão executados quando o resultado de “Condição A” for


falso.

Decisão múltipla

Em algoritmos, a decisão múltipla é um processo de decisão que envolve muitas


entradas, ou seja, entre várias rotas possíveis de código será escolhida uma, e apenas
uma, para ser executada. Devido à natureza binária das expressões booleanas, elas não
se aplicam em processos da decisão múltipla.
Ao invés disso é utilizada uma expressão aritmética com valor resultante inteiro
(usualmente expressões de controle aparecem como uma única variável de tipo inteiro
conhecida como variável de controle). Espera-se naturalmente da expressão de
controle que o valor proveniente da avaliação esteja numa faixa finita de valores inteiros.
Cada um destes valores deve conduzir ao seu próprio bloco de código. Se a avaliação
resulta um valor fora da faixa então nenhum bloco é executado e o processo de decisão
encerrado. Blocos em decisões múltiplas precisam de um rótulo para indicar onde
principiam. O rótulo deve conter o valor inteiro esperado pela avaliação da expressão
de controle que induza a execução do bloco que rotula. A estrutura de decisão múltipla,
conhecida como caso...seja..., possui a seguinte sintaxe geral:

caso <varável ou expressão de controle> seja


<rótulo 1>: <bloco 1>
<rótulo 2>: <bloco 2>

p. 21 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

...
<rótulo n>: <bloco n>

Cada rótulo da estrutura acima possui o próprio bloco e é separado dele pela marca,
(dois pontos). Todos os rótulos são dispostos um nível de indentação acima no nível
onde está a palavra-chave seja. Blocos dispõem-se um nível de indentação acima
daquele onde estão os rótulos.
Em síntese, após a avaliação da expressão (ou variável) de controle um valor inteiro é
obtido, o rótulo com este valor selecionado e por fim o bloco executado. Quando a
execução encerra, ocorre um desvio para fora da estrutura para que outros blocos não
sejam executados.
O exemplo a seguir ilustra a estrutura caso...seja:

declare
n: inteiro
leia n
caso (n) seja
1: escreva ‘Olá mundo!’
2: escreva ‘Hello world!’
3: escreva ‘Hallo Welt!’

A execução deste pseudocódigo implica impressão de uma entre três mensagens (caso
o valor em n seja 1, 2 ou 3) ou em finalização sem impressão alguma (caso outros
valores sejam fornecidos). Nunca duas mensagens são simultaneamente impressas.

A estrutura caso..seja pode ser estendida na sintaxe seguinte:

caso <varável ou expressão de controle> seja


<rótulo 1>: <bloco 1>
<rótulo 2>: <bloco 2>
...
<rótulo n>: <bloco n>
senão <bloco n+1>

A palavra-chave senão funciona neste contexto como um rótulo alternativo a todos os


valores não rotulados anteriormente. Ou seja, se a avaliação da variável ou expressão
de controle resulta um valor fora da faixa dos rótulos, então o bloco n+1 será executado.
Neste contexto sempre algum bloco é executado. Uma prática bastante comum é o uso
da sessão senão para imprimir mensagens de erro. Veja o exemplo:
declare
n: inteiro
leia n
caso (n) seja
1: escreva ‘Olá mundo!’
2: escreva ‘Hello world!’
3: escreva ‘Hallo Welt!’
senão
escreva ‘Opção inválida!!’

p. 22 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Se for fornecido a variável n um valor diferente de 1, 2 e 3 então a mensagem de erro


‘Opção inválida!!’ será impressa. O exemplo a seguir contém blocos, numa estrutura
caso..seja, com mais de uma linha de instrução:

declare
ch: caractere
raio, base, altura, lado: inteiro
escreva ‘pressione: C para cículo, T para triângulo, Q para
quadrado’
ch ← tecla
caso ch seja
‘C’: escreva ‘Valor do raio:’
Leia raio
escreva ‘área = ’, 3.14159235*raio*raio
‘T’: escreva ‘Valores da base e da altura: ’
leia base, altura
escreva ‘área = ’, base*altura/2
‘Q’: escreva ‘Valor do lado: ’
leia lado
escreva ‘área = ’, lado*lado
senão
escreva ‘Opção inválida!!’

Este algoritmo efetua cálculo da área de três categorias de figuras geométricas: círculo,
triângulo ou quadrado. De acordo com a tecla pressionada a execução é direcionada
para um rótulo apropriado. Cada bloco possui mensagem de entrada, leitura de
variáveis e apresentação de resultados (área da figura). A variável de controle é de tipo
caractere e como caracteres são tipos especiais de inteiros então podem ser usados em
estruturas caso...seja.
O uso de uma decisão com se..então..senão em um bloco de caso...seja é perfeitamente
legal e bastante usual. No exemplo seguinte simula-se uma calculadora cujos operandos
são fornecidos primeiro e a operação (soma, subtração, multiplicação ou divisão) depois
com um pressionar de tecla:

declare
op: caractere
x, y: inteiro
escreva ‘fornecer valores: ’
leia x, y
escreva ‘forcecer opção : + - * /’
op ← tecla
caso op seja
‘+’: escreva ‘Soma: ’, x+y
‘-’: escreva ‘Subtração: ’, x-y
‘*’: escreva ‘Multiplicação: ’, x*y
‘/’: se (b≠0) então
escreva x/y
senão
escreva ‘divisão por zero!’
senão escreva ‘Opção inválida!!’

p. 23 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Se a tecla com o caractere ‘/’ for pressionada então a operação de divisão é selecionada.
Isso inicia um processo de decisão com se..então..então que trata a possibilidade de
divisão por zero. A mensagem ‘divisão por zero!’ é impressa quando o valor em b é nulo.
A mensagem ‘Opção inválida!!’ é impressa quando uma tecla operacional inválida é
pressionada.

Aninhamento de Decisões

A estrutura se...então(...senão) permite o aninhamento, ou seja, a possibilidade de


construção de outras estruturas se...então(...senão) dentro de seus blocos. Este
encapsulamento de decisões pode se estender em muitos níveis dependendo das
unicamente das necessidades de expressão do algoritmo. A seguir um exemplo
esquemático:

se (...) então
// bloco
se (...) então
// bloco
senão
se (...) então
// bloco
senão
se (...) então
// bloco
senão
// bloco

Repetição

As estruturas de decisão permitem a modelagem de apenas parte dos problemas


resolvidos por algoritmos. As estruturas de controle de repetição estendem largamente
esta capacidade de modelagem. Elas fornecem meios de repetição de execução de
blocos de códigos específicos. A associação entre capacidades de decisão e repetição
constitui prática comum na construção de algoritmos. Uma estrutura de controle de
repetição encapsula apenas um bloco de código e o repete mediante um critério que
notavelmente muda durante o processo (Naturalmente este bloco pode conter
internamente outros blocos com nível de indentação acima e que também terão
execução repetida). Cada repetição é conhecida como iteração. Estruturas de repetição
são comumente chamadas de laços ou loops. A seguir são estudadas as principais
estruturas de laços utilizadas na construção de algoritmos.

Laços controlados por Contador

Um laço é controlado por contador quando uma variável auxiliar, chamada contador,
usualmente de tipo inteiro, é responsável pela contabilização das iterações. A estrutura
de controle para laço com contador é, para...até...faça, e possui a seguinte sintaxe geral:

para <contador> ← <limite inferior> até <limite superior> faça


<bloco>

p. 24 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Esta estrutura efetua a repetição sistemática do código presente no bloco encapsulado


posto nas linhas logo abaixo do cabeçalho da estrutura e indentado um nível acima deste.
A execução deste laço se faz pela progressão aritmética do contador desde o limite
inferior até o limite superior. Esta progressão é automática e acrescenta uma unidade
ao contador ao final de cada iteração. Consequentemente em cada iteração todo o bloco
encapsulado executa com o mesmo valor de contador que terá uma unidade a mais na
iteração seguinte. Quando o laço encerra o último valor atribuído a variável de
contagem é o do limite superior. O operador ← é constituinte desta estrutura
enfatizando que em cada iteração do laço ocorre uma atribuição (ao contador). O
exemplo a seguir ilustra o uso desta estrutura:

declare
i: inteiro
para i ← 1 até 100 faça
escreva i

A execução deste algoritmo imprime os números de 1 a 100 na saída padrão. O bloco da


estrutura é formado por uma única linha de instrução. Um outro exemplo:

declare
i, x: inteiro
para i ← 1 até 50 faça
x ← 2*i
escreva x

A execução deste algoritmo imprime na saída padrão os números pares entre 2 e 100.
Em cada iteração o valor em x é recalculado em função do valor do contador i.
Uma alternativa sintática ao laço com contador, e que melhora o desempenho de muitos
algoritmos, é o uso do passo. Por definição o passo é um valor inteiro que deve ser
somado ao contador quando encerrar uma iteração de laço e iniciar outra. O passo nos
laços mostrados anteriormente vale 1. A sintática básica do laço com contador e passo
é a seguinte:
para <contador> ← <limite inferior>, <limite superior>, <passo> faça
<bloco de pseudocódigo>

As mudanças nesta nova versão em relação à anterior foram: removeu-se a palavra-


chave até e no seu lugar colocou-se uma vírgula; após o limite superior marcou-se uma
nova vírgula seguindo-a com o valor do passo; por fim a palavra-chave faça. O exemplo
dos números pares pode ser reescrito da seguinte forma:

declare
i: inteiro
para i ← 2, 100, 2 faça
escreva i
Neste algoritmo o contador i inicia com valor 2 e em cada iteração é incrementado de 2
(passo) até atingir 100.
Note que dependendo do passo o contador pode passar por cima do limite superior.
Quando isso acontece o laço encerra naturalmente quando o contador atinge o primeiro
valor acima do limite superior, mas sem processá-lo.

Exemplo:

p. 25 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

declare
i: inteiro
para i ← 7, 30, 3 faça
escreva i, ‘ ’

Este laço imprimirá:


7 10 13 16 19 22 25 28

O valor 31 não será impresso porque extrapola o limite superior do laço.

Quando o valor do passo é negativo é possível montar laços com contador decrescente
porque neste caso ocorre sucessivamente a subtração ao invés da adição. Exemplo:

declare
i: inteiro
para i ← 20, 0, -1 faça
escreva i, ‘ ’

Este último laço imprimirá na saída padrão os números de 0 a 20 em ordem


decrescente e separados por um espaço.

Estudo de Caso – Fatorial: (este é um caso clássico, citado em praticamente todas as


literaturas sobre algoritmos) O fatorial de um número inteiro é igual ao produto entre
ele e todos os seus anteriores positivos maiores que zero. O algoritmo seguinte resolve
o problema do fatorial:

declare
n, i, fat: inteiro
leia n
fat ← 1
para i ← 1 até n faça
fat ← fat*i
escreva fat

O funcionamento deste algoritmo é explicado a seguir. A variável n é implicitamente


modificada pelo comando leia e mantém seu valor até o fim da execução. A variável fat
é inicializada com o elemento neutro da multiplicação, 1. Em cada iteração do laço para
o valor em fat é multiplicado pelo valor no contador i e o resultado atribuído à própria
variável fat. Assim, em cada iteração, fat irá conter o fatorial do valor corrente no
contador i. Como o contador de estende até o valor em n, então o último valor atribuído
a fat é o fatorial do valor em n.

Este processo de constante atualização de uma variável em um laço por operações de


multiplicação é denominado de acumulação por produto e é arquétipo de diversos
outros algoritmos. A variável modificada normalmente é inicializada com o elemento
neutro da multiplicação para não afetar o resultado gerado no processo iterativo.

Laços controlados por teste

Cada iteração de um laço está associada a um teste que será responsável pela finalização
ou continuação deste. Nos laços com contador este teste está embutido na própria

p. 26 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

estrutura: ele consiste em verificar se o contador já alcançou ou ultrapassou o limite


superior. Há, entretanto laços onde tais testes são explícitos e aparecem como
expressões booleanas. Há dois tipos importantes de laços com teste: de pré-teste e de
pós-teste. Analisaremos cada um deles nas linhas seguintes.
Laços de pré-teste são aqueles que no começo de cada iteração realizam um teste
para determinar sua continuidade. A estrutura de controle para pré-teste é,
enquanto...faça, e possui sintaxe geral como segue:

enquanto <expressão booleana> faça


<bloco>

A semântica funcional desta estrutura é descrita a seguir. O bloco encapsulado é


repetido diversas vezes (iterações). Antes de cada iteração a expressão booleana à
entrada é avaliada. Se seu valor for Verdadeiro significa que a próxima iteração deverá
ocorrer do contrário o laço deverá encerrar-se. Nenhuma instrução do bloco é
executada se na primeira avaliação o resultado for Falso. Segue um exemplo:

declare
x: inteiro
x←0
enquanto (x<20) faça
escreva x, ‘ ’
x←x+2

Neste algoritmo, enquanto a expressão, x<20, for Verdadeira as duas instruções


encapsuladas serão executadas. É importante observar que a variável n funciona como
contador, apesar de não ser integrante da estrutura. Por essa razão o valor nesta
variável precisa ser explicitamente inicializado fora do laço (x←0, na terceira linha) e
modificado manualmente dentro do laço (x←x+2, na última linha). A saída deste
algoritmo é a seguinte:

0 2 4 6 8 10 12 14 16 18

O valor 20 não é impresso porque não satisfaz a expressão booleana (20 é igual a 20 e
não menor).
Observe que, ao contrário do que ocorre nos laços por contador, é possível mudar o
local onde a variável de controle se modifica. Se, por exemplo, as duas linhas do bloco
encapsuladas por enquanto no algoritmo anterior fossem trocadas de posição o código
ainda seria válido, mas a saída impressa se modificaria para:

2 4 6 8 10 12 14 16 18 20

Esta saída deixa de imprimir o 0 e imprime 20 simplesmente porque as impressões agora


veem depois da modificação da variável x.. Laços de pós-teste são aqueles que ao final
de cada iteração realizam um teste para determinar sua continuidade. A estrutura de
controle para pós – teste é, repita...até, e possui sintaxe geral como segue:
repita
<bloco>
até <expressão booleana>

p. 27 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

A semântica funcional desta estrutura é descrita a seguir. O bloco encapsulado é


repetido diversas vezes (iterações). Após o final de cada iteração a expressão booleana
à saída é avaliada. Se seu valor for Falso significa que a próxima iteração deverá ocorrer
do contrário o laço deverá encerrar-se.
O bloco encapsulado é executado pelo menor uma vez independente da expressão
booleana. Ao passo que a estrutura enquanto...faça executa código enquanto algo é
verdade, repita..até executa código até que algo seja verdade.
Segue um exemplo:

declare
x: inteiro
x←0
repita
escreva x, ‘ ’
x←x+2
até (x>20)

O funcionamento deste algoritmo e similar ao último algoritmo com pré-teste


apresentado. Como o teste fica na saída, o valor em x é sempre impresso na primeira
iteração (mesmo que fosse maior que 20). O laço só é interrompido quando o valor em
x atinge 22 (o qual não é impresso). A saída deste algoritmo é:

0 2 4 6 8 10 12 14 16 18 20

Aninhamento de Laços

Aninhar laços significa encapsular laços dentro de outros. Se um laço A é encapsulado


por um laço B então para cada iteração de B o laço A efetuará sistematicamente todas
suas possíveis iterações naquele contexto. Por exemplo:

declare
i, j: inteiro
para i ← 1 até 10 faça
para j ← 1 até 10 faça
escreva i+j

Os dois laços no algoritmo anterior são construídos para executar 10 vezes cada. O
primeiro tem contador em i e o segundo contador em j. Entretanto o primeiro lado
encapsula o segundo laço (posto um nível de endentação acima). Isso faz com que cada
iteração do primeiro laço execute todas as 10 iterações do segundo laço e
consequentemente execute 100 vezes a instrução escreva (posta um nível de
endentação acima do segundo laço).

Os limites dos contadores dos laços podem ser expressos como função de qualquer
variável inteira do programa (exceto o próprio contador). Isso inclui também os
contadores de laços hierarquicamente acima em um dado aninhamento. Veja o
exemplo:

declare
i, j, cnt: inteiro
cnt ← 0

p. 28 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

para i ← 1 até 10 faça


para j ← i até 10 faça
cnt ← cnt + 1
escreva cnt

Neste algoritmo o segundo laço é aninhado no primeiro. O limite inferior do segundo


laço (de contador j) é o valor corrente do contador do primeiro laço, i. À proporção que
o primeiro laço avança o número de iterações do segundo laço diminui como indica a
tabela a seguir:

Valor de i 1 2 3 4 5 6 7 8 9 10
Número de iterações do segundo laço 10 9 8 7 6 5 4 3 2 1

O algoritmo utiliza acumulação por soma para guardar na variável cnt o total de
iterações. Este valor também pode ser calculado pela somatória dos valores na segunda
linha da tabela anterior, ou seja, 10+9+8+7...+1 = 55. Este será o valor impresso na saída
padrão.

Não há restrições sobre os tipos de estruturas de repetição aninhadas. Assim, por


exemplo, laços de contagem podem estar aninhados a laços de teste ou vice-versa.
Também não há restrições sobre aninhamento entre estruturas de decisão e de
repetição. De fato a associação coerente de todas estas estruturas é que possibilita a
criação de algoritmos aplicáveis.

Quebra e continuação de laços

Um laço controlado por teste é denominado laço infinito quando a expressão booleana
de controle é sempre avaliada como Verdadeira (no caso de enquanto...faça) ou sempre
como Falsa (no caso de repita...até). Laços infinitos são aplicados em situações onde o
critério de parada não se encaixa na entrada (ou na saída) do laço. Quando instruções
internas ao bloco de laço promovem sua suspensão forçada (sem uso da expressão
booleana de controle) diz-se que houve quebra de laço. Uma quebra de laço é
construída utilizando o comando pare. Veja o exemplo:

declare
ch: caractere
enquanto (V) faça
ch ← tecla
caso (ch) seja
‘x’: escreva ‘olá mundo!!’
‘y’: escreva ‘hello world!’
‘z’: escreva ‘hallo Welt!!’
senão pare

No algoritmo anterior o laço construído com enquanto é infinito devido à expressão de


controle ter sido substituída por um V (Verdadeiro). Em cada iteração uma tecla é
solicitada pelo comando tecla e seu caractere armazenado na variável ch. Caso o valor
em ch seja ‘x’, ‘y’ ou ‘z’ então uma de três mensagens é enviada a saída padrão e o laço
inicia novamente com nova solicitação de tecla. Se a tecla pressionada não é nenhuma

p. 29 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

das três então o pare do bloco rotulado senão é executado suspendendo o laço. As
regras de funcionamento do comando param são as seguintes:
• Se pare for executado fora de laços, mesmo encapsulado por alguma estrutura de
decisão, ocorrerá suspensão da execução do algoritmo como um todo.
• Se pare for executado dentro de um laço sem aninhamento com outros laços, mesmo
que esteja encapsulado por alguma estrutura de decisão, apenas tal laço será suspenso,
mas o algoritmo não necessariamente.
• Se pare for executado em um aninhamento de laços, mesmo havendo aninhamento
de estruturas de decisão, apenas o laço hierarquicamente mais próximo a este comando
será suspenso, mas o algoritmo não necessariamente.

Estudo de Caso – Números Primos: Um número primo é aquele que é divisível apenas
por um e por ele mesmo. Como um número não é divisível pelos que o sucedem é
razoável acreditar que um dado inteiro n, que se quer testar se é primo ou não, deva ser
dividido pelos números no intervalo fechado [2, n-1] sendo primo se todas estas divisões
obtiverem resto não nulo e não primo se pelo menos uma for nula (encontrada uma
divisão com resto nulo o número não é mais primo e as demais divisões, se ainda
restarem, tornam-se desnecessárias). Matematicamente, entretanto, tantas divisões
não são necessárias um intervalo suficiente de testes pode ser reduzido para [2, d] tal
que d2 ≤ n.

Com base no critério anunciado acima foi construído um algoritmo capaz de escrever,
na saída padrão, todos os números primos menores que cinco mil. Segue:

declare
n, d: inteiro
b: lógico
para n ← 2 até 5000 faça
b←V
d←2
enquanto (d*d ≤ n) faça
se (n mod d = 0) então
b←F
pare
d ← d+1
se (b) então
escreva n, ‘ ’

O laço para, neste algoritmo submete em cada iteração o valor de seu contador n a um
teste para verificar se ele é ou não valor primo. O teste possui quatro etapas:

(I) Atribuição à variável b do valor Verdadeiro indicando a primeira hipótese sobre


a natureza do valor em n (ou seja, é primo até que se prove o contrário).

(II) A variável d recebe valor 2 indicando o início do intervalo de valores pelos quais
o valor em n deve ser dividido.

(III) O laço enquanto testa a divisibilidade de n pelos valores no intervalo


[2,3,..,d,..,D], com D2≤n, interrompendo o laço quando o primeiro resto igual a
zero é encontrado. Se esta interrupção acontece o valor em b muda para Falso

p. 30 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

(foi provado o contrário: o número não é primo) e o laço enquanto é suspenso


por um pare (não há mais sentido testar outras divisibilidades).

(IV) O valor em b é verificado para ver se o valor corrente no contador n é primo. Se


for (ver expressão booleana formada apenas por b) ele é impresso na saída
padrão.

Neste último exemplo, utilizando-se limite inferior igual a 3 e passo igual a 2 no laço
para, testam-se apenas valores ímpares (o único primo par é 2) aumentando-se a
velocidade do algoritmo.

1.4 Variáveis Indexadas

Matrizes

Introdução a matrizes e vetores

Uma variável escalar é uma entidade abstrata que se refere a uma célula de memória e
que possui um tipo relacionado, uma faixa restrita de representação e a capacidade de
armazenar um único valor. Há, entretanto, a possibilidade de definir variáveis com
capacidade de guardar mais de um valor ao mesmo tempo. Tais variáveis são
denominadas matrizes.

Naturalmente os valores armazenados por matrizes não compartilham a mesma célula


de memória: de fato mais de uma célula estará presente na definição de matrizes.
Cada uma destas células funciona como uma variável escalar independente o que faz
das matrizes aglomerados de variáveis escalares.

Todas essas variáveis constituintes são do mesmo tipo de forma que podemos ter, por
exemplo, matrizes de inteiros, lógicos ou de reais, mas nunca a mistura deles.
Denomina-se tipo base o tipo de dados comum a todos os aglomerados da matriz.

Uma variável matriz, assim como todas as demais, possui apenas um nome. Então como
manipular cada uma das variáveis escalares (células) que a constitui? O mecanismo para
se referenciar cada uma das células de uma matriz é denominado indexação. Assim, por
exemplo, se M é uma matriz dos primeiros dez ímpares então M[1] = 1, M[2] = 3, M[3]
= 5 e assim por diante: aqui os colchetes retratam hospedeiros dos índices que neste
caso vão de um a dez acessando independentemente cada valor em M. O vetor M ainda
pode ser descrito desta forma: M[k]=2k-1, com o índice k no intervalo {1..10}.

Matrizes podem contar com um ou mais índices. Cada índice de uma matriz está
associado a uma dimensão da matriz. Assim matrizes unidimensionais precisam de um
índice, bidimensionais de dois e assim por diante. As matrizes na matemática se
confundem com as matrizes bidimensionais aqui descritas.

Matrizes unidimensionais são comumente denominadas de vetores. Os vetores


representam a forma de matriz mais comumente empregada em algoritmos.

O total de aglomerados de um vetor representa o comprimento do vetor. O tamanho


de um vetor é a memória total que ele ocupa, ou seja, seu comprimento multiplicado

p. 31 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

pelo tamanho em bytes do tipo base. Assim, por exemplo, se H é um vetor formado de
5 inteiros de 2-bytes, então o comprimento de H é 5, seu tipo base é inteiro, e seu
tamanho vale 10-bytes.

Comprimento = 5

Inteiro – 2 bytes Inteiro – 2 bytes Inteiro – 2 bytes Inteiro – 2 bytes Inteiro – 2 bytes

Matrizes na Memória

Como estão dispostas as matrizes na memória? Se pensarmos em termos de vetores é


coerente imaginar que as células constituintes são dispostas vizinhas umas às outras: de
fato é exatamente isso o que acontece. Quando um vetor precisa ser alocado, então a
memória requisitada deverá ser um bloco uniforme de bytes com o tamanho total do
vetor. Encontrado o bloco ele é então marcado como usado e vinculado a variável vetor
no programa.

Seja, por exemplo, um vetor formado de 50 células de inteiros de 2-bytes vinculado à


variável X. Assim, após alocação, um bloco de 100 bytes estará vinculado a X e as 50
células poderão ser acessadas independentemente por X[1], X[2], X[3],..., X[50]. O único
endereço real disponível é o do início do bloco de memória (chamaremos ). E o de cada
célula? Como funciona uma chamada a X[k], com k inteiro e entre 1 e 50? A resposta é
simples: através de aritmética elementar, ou seja, manipular X[k] significa manipular
diretamente o conteúdo no endereço de memória +(k-1)⋅2.

O acesso a células individuais via vetores é o mais eficaz se comparada a outras formas
de armazenamento linear (como listas encadeadas).

E as matrizes de mais de uma dimensão? Também tem células contiguas em memória?


A resposta é sim. Quando mais de uma dimensão está envolvida a memória total
utilizada será o produto entre o tamanho do tipo base e todos os comprimentos das
dimensões. Por exemplo, seja Q uma matriz bidimensional 3×3 de inteiros como segue:

Se Q é composto por inteiros de 2-bytes então o bloco de memória alocado terá 18


Bytes (3X3 = 9 nove células ---- 9 x 2 bytes = 18bytes em uso).
Declaração Inicialização e uso de Vetores

A sintaxe geral para declaração de vetores é a seguinte:


declare
<variável>[comprimento]: <tipo>
Segue um exemplo:
declare
M[20], i: inteiro
para i  1 até 20 faça
M[i] ¬ i*i

p. 32 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

Neste código duas variáveis são declaradas: um inteiro i e um vetor de inteiros M. A


variável M comporta vinte valores inteiros e é utilizada para armazenar, por ação de um
laço, os quadrados dos números de um a vinte. Vale observar que o contador i do laço
funciona tanto como índice do vetor quanto como componente de expressão. Há duas
aplicações para o par de colchetes. A primeira é declarativa, ou seja, eles abrigam o
comprimento do vetor declarado conforme se verifica na definição da sintaxe geral. A
segunda é evocativa, ou seja, o conteúdo entre os colchetes é um valor de índice entre
1 e seu comprimento (definido na declaração) e possibilita o acesso a uma célula
específica do vetor. Tal acesso permite tanto leitura quanto modificação do que está na
célula indexada.

Consideremos o exemplo seguinte:

declare
M[10], i, imax: inteiro

para i 1 até 10 faça


leia M[i]
imax  1
para i  2 até 10 faça
se (M[i] > M[imax]) então
imax  i
escreva M[imax]

Este algoritmo solicita dez valores do usuário e imprime como saída o maior entre eles.
O primeiro laço é o responsável pela entrada de dados. Em cada iteração o comando
leia modifica uma célula distinta do vetor M de modo a preenchê-lo convenientemente.
O restante do código é um processo de busca. Tal busca começa com a hipótese deque
o maior valor está na primeira posição (assim imax recebe 1). As demais posições são
testadas progressivamente pelo laço para: cada vez que uma célula verificada possui
valor maior que aquele de índice imax, então imax recebe o valor do contador. Quando
o laço encerra imax possui a posição contendo o maior valor e assim M[imax] é impresso.
Não há aninhamento de laços neste exemplo e por essa razão os dois laços estão no
mesmo nível de indentação. Apesar de não estar disponível na maioria das linguagens
de programação introduzimos nessa abordagem uma opção de inicialização de vetores
diretamente do código. A sintaxe geral é a seguinte:

declare
<variável_1>[c1]: <tipo>
//...
<variável_1> ¬ {<valo1_1>, <valo1_2>, <valo1_3>,..., <valo1_c1>}
//...
Um exemplo de aplicação:
declare
M[10], i, imax: inteiro
M ¬ {12, -9, 33, 8, -23, 17, 6, -5, 31, 2}
imax  1
para i ¬2 até 10 faça
se (M[i] > M[imax]) então
imax  i

p. 33 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

escreva M[imax]

Nesta sintaxe de inicialização de vetores, o par de colchetes não é necessário, as chaves


(que envolvem os elementos) são obrigatórias e ainda deve haver vírgulas entre os
elementos. A execução deste algoritmo imprime 33 na saída padrão.

Cadeia de caracteres ou vetor de caracteres

Se um vetor é constituído por caracteres então ele é denominado uma cadeia de


caracteres ou simplesmente string,(strings em CLP na maioria dos fabricantes, são
tratadas como um tipo de variável, porém nada mais são que um vetor de caracteres) .
Cadeias de caracteres são utilizadas para representar mensagens ou mesmo textos
completos. Há duas características importantes das strings que as destacam em relação
aos vetores em geral. A primeira é o conceito de comprimento de cadeia e a segunda
são as formas peculiares que elas possuem de inicialização, atribuição, escrita e leitura.
O comprimento de uma cadeia de caracteres é a quantidade de caracteres medida do
primeiro caractere até o caractere que precede a primeira ocorrência do caractere nulo
(NULL), que é um caractere de controle com valor zero em ASCII, sua denotação em
ASCII é \0 , em CLP geralmente é representado como duas aspas juntas, “”, Esta
estratégia é responsável pela capacidade que strings têm de armazenar mensagens de
tamanho variável, ou pelo menos com tamanho mínimo (zero) e máximo (comprimento
do vetor menos um). Para entender melhor esta questão consideremos um vetor de
comprimento 20 onde se queira armazenar a mensagem ’Hoje vamos viajar’. O aspecto
dos caracteres no vetor segue:

Perceba, que não é necessário utilizar totalmente o tamanho do vetor, porém caso a
mensagem seja maior que o vetor quaisquer caracteres que excedam o tamanho do
vetor, serão desconsiderados, outro detalhe é que o espaço utilizado para separar as
palavras também conta como parte do vetor e ocupam espaços na memória.

Para inicializar uma cadeia de caracteres pode-se utilizar a sintaxe apresentada


anteriormente. Exemplo:
declare
S[10]: caractere
S  {‘a’, ‘ ’, ‘c’, ‘a’, ‘s’, ‘a’, /0}
Neste exemplo cada caractere foi colocado em sua respectiva posição no vetor,
incluindo o nulo. Para guardar a mensagem ‘a casa’, entretanto, são necessários apenas
7 caracteres (incluindo /0).
Outra forma e mais comum de inicializar uma cadeia de caracteres é atribuindo
diretamente a mensagem:

declare
S[10]: caractere
S  ‘a casa’

1.5 Vetores Dinâmicos

Todas as declarações de vetores nas sessões anteriores possuíam vinculação estática de


espaço em memória, ou seja, o tamanho que o vetor possuirá em tempo de execução

p. 34 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

precisa ser definido no código pelo programador. O efeito direto disso é a inflexibilidade,
ou seja, se mais memória for necessária não será possível expandir o vetor durante a
execução. Para resolver esta limitação, introduzimos os comandos alocar e limpar. Eles
interagem diretamente com o gerenciador de memória requisitando e devolvendo
respectivamente quantidades de memória. Cada solicitação de memória com alocar
está associada a uma devolução com limpar. Memória não devolvida mantém o status
de ocupada não podendo ser usada por outros processos. Em máquinas reais, a
ocorrência desse quadro causa queda de desempenho ou mesmo parada do sistema
(crash).

Denominamos vetor dinâmico ao vetor com capacidade de definir seu comprimento


em tempo de execução. A sintaxe geral de um vetor dinâmico é a seguinte:

declare
<vetor>[]: <tipo base>

A diferença para vetores estáticos é a ausência de um comprimento entre os colchetes.

Exemplos:
declare
X[]: inteiro
VET[]: inteiro

Para alocar e limpar memória de um vetor dinâmico utiliza-se respectivamente os


comandos alocar e limpar. A sintaxe básica segue:

alocar <vetor>[<comprimento>]
...
limpar <vetor>

O exemplo a seguir ilustra o uso de vetores dinâmicos:

declare
X[], n, i: inteiro
leia n
alocar X[n]
para i  1 até n faça
X[i]  2*i-1
limpar X

No exemplo acima o vetor dinâmico X tem seu comprimento alocado com um valor de
comprimento, n, fornecido via entrada padrão. Após a alocação o vetor é carregado com
a máxima quantidade de números ímpares que suporta e finalmente desalocado ao final.

Um detalhe para CLPs, é que a os mesmos não permitem alocação dinâmica de memória,
nesse caso não é possível utilizar vetores dinâmicos, porém são uma grande ferramenta
de programação para computadores.

1.6 Modularização

p. 35 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

A realização de uma determinada tarefa muitas vezes é decomposta em sequências de


passos. Lembre-se da tarefa de trocar uma lâmpada: existe uma série de passos que
devem ser seguidos, como:
...
subir na escada
desconectar a lâmpada velha
conectar a lâmpada nova
...
e assim por diante.

Conforme uma tarefa cresce e se torna mais complexa, surge uma série de situações a
serem resolvidas para que este problema possa ser solucionado. Podemos dizer que
passamos a ter dentro deste problema uma série de pequenos problemas.
Muitas vezes, a grande quantidade de pequenos problemas afeta a legibilidade (clareza)
fazendo com que uma consulta ou manutenção futura desta lógica seja uma tarefa difícil
de se realizar. Através da modularização é possível evitar esta "confusão da lógica".

Modularizar é quebrar um problema em pequenas partes, sendo que cada uma dessas
partes será responsável pela realização de uma etapa do problema.

Há dois importantes níveis de abstração em computação: abstração de dados e


abstração de processos. A abstração de dados explora como diferentes tipos de
informações podem ser representados e ainda quais as restrições de operabilidade
entre eles. A abstração de processos trata da simplificação do processo de execução de
uma dada aplicação pela divisão deste em partes menores (sub-processos) que podem
ser testadas separadamente. A modularização está estreitamente ligada à abstração de
processos. Modularizar significa dividir um programa (grande problema) em
subprogramas (pequenos problemas) cujos funcionamentos podem ser testados
separadamente. Os subprogramas são nada mais que abstrações com alguma sintaxe
adicional (em nível de código).

Funções, Procedimentos, Processos e Controle

Modularizar algoritmos significa separar o pseudocódigo em funções. As funções,


módulos, subprogramas ou sub-rotinas, como são conhecidos, podem aparecer em
grande quantidade em um mesmo algoritmo, mas apenas uma destas funções tem papel
de acionador, ou seja, sempre a partir dela se iniciará a execução. É a chamada função
principal. Todas as demais funções são secundárias. Cada função tem um nome e, num
mesmo algoritmo, todas as funções devem ter nomes distintos entre si. Além do nome
uma função pode conter parâmetros. Parâmetros, ou argumentos, são variáveis
especiais que agem como entrada de dados para estas funções. A sintaxe geral de uma
função é a seguinte:

<nome_da_função> (<arg_1>: <tipo_1>, <arg_2>: <tipo_2>, ..., <arg_n>: <tipo_n>)


//declaração de variáveis da função
//instruções da função
Na sintaxe de funções os argumentos são arranjados em uma lista de variáveis com seus
respectivos tipos e ainda separados por vírgula. Apesar de não existir a palavra declarar,
os argumentos de entrada são, por definição, variáveis ali declaradas. A primeira linha
da função (composta por seu nome e seus argumentos entre parênteses) é chamada de
cabeçalho da função. O corpo da função é todo o código abaixo do cabeçalho e cuja

p. 36 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

indentação é pelo menos um nível acima (relação de encapsulamento de código em


funções). O corpo de uma função pode possuir uma sessão declarativa (variáveis da
função) e possui obrigatoriamente (logo abaixo) a sessão de código (bloco de código).

Se um grupo de argumentos de entrada tiver mesmo tipo eles podem ser declarados
com a seguinte sintaxe:

<nome_da_função> (<arg_1>,<arg_2>,<arg_3>,...,<arg_n>: <tipo>)


// corpo da função

Quando uma aplicação inicia sua execução diz-se que a função principal recebe o
controle de fluxo ou simplesmente que recebe o controle. Se a função principal chama
uma função secundária então esta função receberá o controle do fluxo enquanto estiver
executando e o devolverá a função principal quando sua execução se encerrar.

Funções podem retornar valores. O retorno (ou saída) de uma função pode ser, por
exemplo, um número, um caractere ou um booleano. A ação de retorno de uma função
é sumária, ou seja, quando invocada a função automaticamente se encerra devolvendo
o controle à função chamadora. Para provocar o retorno usa-se a palavra-chave retorne
seguida do valor que se deve retornar. Veja o exemplo a seguir:

soma (x, y: inteiro)

declare
s: inteiro
sx+y
retorne s

principal()

declare
a, b, c: inteiro
leia a, b
c  soma(a,b)
escreva c

Neste exemplo há duas funções: a principal (que sempre denotaremos pelo nome
principal) e a função secundária soma(). A função secundária possui dois parâmetros, x
e y e sua chamada é feita na função principal passado como argumentos os valores nas
variáveis a e b. O uso da atribuição, c  soma(a, b), entra em concordância com o
retorne da função soma(), ou seja, só é possível atribuir a c algum valor porque este
valor existe e é o retorno da função em questão. As variáveis x e y são denominados
argumentos formais da função soma() ao passo que a e b são denominadas de
argumentos reais da mesma função.

Procedimentos, tem como diferença para as funções o fato de não retornarem valores
para a função principal.

Para algoritmos, sua sintaxe seria:


procedimento
// Seção de Declarações de Variações Locais Inicio

p. 37 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

// Seção de Comandos
fimprocedimento

Escopo das variáveis

Nós temos 2 escopos das variáveis, que seriam globais e locais

O escopo de uma variável é definido como o lugar no algoritmo onde esta variável pode
ser manipulada.

Variáveis Globais

Tem a sua declaração, antes do cabeçalho da função principal, como o nome diz ela
pode ser acessada por qualquer função

Variáveis locais

São declaradas dentro da seção de declaração de variáveis dentro das funções e são
acessadas somente dentro dessa função específica.

1.7 Recursividade

Recursividade é a técnica que permite a uma função fazer, no corpo de seu código, uma
chamada a si própria. Para ilustrar a recursividade apresentamos a seguir duas versões
de funções para cálculo de fatorial: uma não-recursiva (iterativa) e outra recursiva.

//versão iterativa

fat(n: inteiro)
declare
res: inteiro
enquanto (n>0) faça
res  res * n
nn-1
retorne res

// versão recursiva
fat(n: inteiro)
se (n<2) então
retorne 1
senão
retorne n*fat(n-1)

A versão não recursiva não traz novidades, mas ilustra a potencialidade dos laços para
resolver problemas como o cálculo de fatoriais. Na versão recursiva o laço desaparece,
pelo menos aparentemente. O processamento da versão recursiva da função fatorial é
descrito a seguir. Quando uma chamada explícita a fat() é feita seu argumento formal
recebe o valor do qual se deseja calcular o fatorial. Caso este seja menor que 2 a função
se encerra retornando 1. Caso não seja, ela tenta retornar o produto, n*fat(n-1). Como
a expressão de retorno contém a própria função, então uma nova chamada a fat() é
realizada. Enquanto esta nova chamada não for resolvida a chamada anterior não
poderá retornar. Assim a primeira chamada fica a espera do retorno da segunda

p. 38 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

chamada. Essa por sua vez pode desencadear o mesmo processo e ter-se-á um primeiro
aguardando por um segundo e esse por sua vez por um terceiro. O processo só não se
torna infinito porque existe a decisão bidirecional, se, que desvia para retorno 1 sempre
que valores menores que 2 forem repassados.
Em suma a recursão cria vários níveis de espera que são resolvidos de trás para frente
no momento em que uma delas não recorre mais a recursão. A presença de um
mecanismo de parada como o descrito no exemplo do fatorial (uso de se) impede
naturalmente o problema de laço recursivo infinito.

1.8 Caderno de Exercícios

Recomendações:

• Não analise a resposta dos exercícios logo de cara, tente elaborar o algoritmo.
• Pense no algoritmo como receita de bolo;
• Na dúvida refaça a leitura sobre o tema da apostila;
• Continuou sem entender??? Google!! ... tem várias outras na internet explicando
de forma diferente, talvez ajude;
• Coloque no papel tudo o que entendeu;
• Mesmo assim não conseguiu? Mostre até onde chegou a quem entende e busque
ajuda, explicando com clareza o que está “travando”você;

Todos os algoritmos das respostas serão gerados no VisuAlg, então teste seus algoritmos
lá também.

Terminou todos os exercícios?? Parabéns ... hora de dar um Google e procurar por
mais! – Quanto mais pratica, melhor fica!

Exercícios:

1- Faça um algoritmo que receba 2 números e exiba o resultado da sua soma:


Resposta:

Var
x, y: inteiro
inicio
// Seção de Comandos
escreval("Digite o primeiro número: ")
leia(x)
escreval("Digite o segundo número: ")
leia(y)
escreval("A soma dos números é: ",x+y)

2- Função : Faça um algoritmo que receba dois números e ao final mostre a soma,
subtração, multiplicação e a divisão dos números lidos.
Resposta:

var
x, y: real

p. 39 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

inicio
// Seção de Comandos
escreva("Digite o primeiro número: ")
leia(x)
escreva("Digite o segundo número: ")
leia(y)
escreval("A soma é: ",x+y)
escreval("A subtração é: ",x-y)
escreval("A multiplicação é: ",x*y)
escreval("A divisão é: ",x/y)

fimalgoritmo

3- Função : Escrever um algoritmo que leia o nome de um vendedor, o seu salário fixo
e o total de vendas efetuadas por ele no mês (em dinheiro). Sabendo que este
vendedor ganha 15% de comissão sobre suas vendas efetuadas, informar o seu
nome, o salário fixo e salário no final do mês
Resposta:

var
nome: caractere
salario: real
vendas: real
comissao: real
salarioFinal: real

inicio
// Seção de Comandos
escreval("<><><><><> Sistema de gestão de vendedores <><><><><>")
escreva(">>> Digite o nome do vendedor: ")
leia(nome)
escreva(">>> Digite o salário: ")
leia(salario)
escreva(">>> Informe a quantidade de vendas deste no mês: ")
leia(vendas)
// Cálculo da comissão e salário final
comissao >>>>>>>>> RESUMO <<<<<<<<<<")
escreval("-- Nome: ",nome)
escreval("-- Salário: ",salario)
escreval("-- Salário Final (salário + comissão): ",salarioFinal)
escreval(">>>>>>>>>><><><><><<<<<<<<<<")

4- Elaborar um algoritmo em pseudocódigo que efetue a leitura de um número


inteiro e apresentar uma mensagem informando se o número é par ou ímpar.
Resposta:

algoritmo "Par ou Ímpar"


var
n: inteiro

p. 40 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

inicio
escreval("Insira um número inteiro: ")
leia(n)
se(n mod 2 = 0) entao
escreval("O número: ",n," é par")
senao
escreval("O número: ",n," é impar")
fimse
fimalgoritmo

5- Elaborar um algoritmo em pseudocodigo que efetue a leitura de um valor que


esteja entre a faixa de 1 a 9. Após a leitura do valor fornecido pelo usuário, o
programa deverá indicar uma de duas mensagens: “O valor está na faixa
permitida”, caso o usuário forneça o valor nesta faixa, ou a mensagem “O valor
está fora da faixa permitida”, caso o usuário forneça valores menores que 1 ou
maiores que 9.
Resposta:

algoritmo "Faixa Permitida"


var
n :real
inicio
escreval("Digite um valor: ")
leia(n)
se(n >= 1) e (n <= 9) entao
escreval("O valor está na faixa permitida")
senao
escreval("O valor não está na faixa permitida")
fimse
fimalgoritmo

6- Faça um algoritmo que receba o valor do salário de uma pessoa e o valor de um


financiamento pretendido. Caso o financiamento seja menor ou igual a 5 vezes o
salário da pessoa, o algoritmo deverá escrever “Financiamento Concedido"; senão,
ele deverá escrever "Financiamento Negado". Independente de conceder ou não o
financiamento, o algoritmo escreverá depois a frase "Obrigado por nos consultar."
Resposta:

algoritmo "Financiamento"
var
sala, financ: real
inicio
escreval("Digite o valor do salário: ")
leia(sala)
escreval("Digite o valor do financiamento pretendido: ")
leia(financ)
se(financ<= 5 * sala) entao
escreval("Financiamento concedido, obrigado por nos consultar")
senao
escreval("Financiamento negado, obrigadopor nos consultar")
fimse
fimalgoritmo

p. 41 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

7- Faça um algoritmo que determine o maior entre N números. A condição de parada


é a entrada de um valor 0, ou seja, o algoritmo deve processar o maior até que a
entrada seja igual a 0(ZERO).
Resposta:

algoritmo "Maior número"


var
n, maior: real
inicio
maior<- 0
repita
escreval("Digite um número positivo maior que zero: ")
leia(n)
se(n > maior) entao
maior<- n
fimse
ate n = 0
escreval("O maior número é: ",maior)
fimalgoritmo

8- Faça um algoritmo que conte de 1 a 100 e a cada múltiplo de 10 emita uma


mensagem:“Múltiplo de 10”.
Resposta:

algoritmo "Multiplos de 10"


var
n: vetor[1..100] de inteiro
i: inteiro
inicio
escreval("Os multiplos de 10 de 1 a 100 são:")
para i de 1 ate 100 faca
se(i mod 10 = 0) entao
escreval(i)
fimse
fimpara
fimalgoritmo

9- A conversão de graus Farenheit para graus centígrados é obtida por: C ← (F-


32)*5/9Fazer um algoritmo que calcule e escreva uma tabela em centígrados em
função de grausFarenheit, que variam de 50 a 150 de 2 em 2.
Resposta:
algoritmo "De Farenheit para Centígrados"
var
graus: vetor[50..150] de inteiro
c: real
i: inteiro
inicio
para i de 50 ate 150 passo 2 faca
c <- (i - 32) * 5 / 9

p. 42 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

escreval(i," F é igual a ",c," C")


fimpara
fimalgoritmo

10- criar um algoritmo para uma calculadora, o usuário digita o primeiro número, a
operação que deseja executar e o segundo número. Dependendo do que o usuário
informar como operador, o algoritmo executará um cálculo diferente (soma,
subtração, multiplicação ou divisão
Resposta:

algoritmo "CalculadoraBasicaComSE"
var
numero1 : REAL
numero2 : REAL
operacao : CARACTERE
resultado : REAL
inicio

ESCREVA ("Digite o primeiro número: ")


LEIA (numero1)
ESCREVA ("Digite a operação: ")
LEIA (operacao)
ESCREVA ("Digite o segundo número: ")
LEIA (numero2)

SE operacao = "+" ENTAO


resultado := numero1 + numero2
SENAO
SE operacao = "-" ENTAO
resultado := numero1 - numero2
SENAO
SE operacao = "*" ENTAO
resultado := numero1 * numero2
SENAO
SE operacao = "/" ENTAO
resultado := numero1 / numero2
FIMSE
FIMSE
FIMSE
FIMSE
ESCREVA ("Resultado: ", resultado)
Fimalgoritmo

Outra versão:

algoritmo "CalculadoraBasicaComSE"
var
numero1 : REAL
numero2 : REAL
operacao : CARACTERE
resultado : REAL

p. 43 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

inicio

ESCREVA ("Digite o primeiro número: ")


LEIA (numero1)
ESCREVA ("Digite a operação: ")
LEIA (operacao)
ESCREVA ("Digite o segundo número: ")
LEIA (numero2)

ESCOLHA operacao
CASO "+"
resultado := numero1 + numero2
CASO "-"
resultado := numero1 - numero2
CASO "*"
resultado := numero1 * numero2
CASO "/"
resultado := numero1 / numero2
FIMESCOLHA

ESCREVA ("Resultado: ", resultado)


fimalgoritmo

11- Faça um algoritmo que copie o conteúdo de um vetor em um segundo vetor.


Resposta:

// Seção de Declarações
var

i:inteiro
vetA:vetor[1..5] de inteiro
vetB:vetor[1..5] de inteiro

inicio
// Seção de Comandos

// VETOR A
para i de 1 ate 5 faca
escreval("VETOR A")
escreva("Informe o valor da posicao: ",i,": ")
leia(vetA[i])
fimpara

limpatela

// COPIA VETOR A PARA VETOR B

para i de 1 ate 5 faca


vetB[i]<-vetA[i]
fimpara

p. 44 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

//APRESENTANDO VETOR A

escreval("VETOR A")
escreval("")
para i de 1 ate 5 faca
escreval(vetA[i])
fimpara

//APRESENTANDO VETOR B

escreval("")
escreval("VETOR B")
escreval("")
para i de 1 ate 5 faca
escreval(vetB[i])
fimpara

fimalgoritmo

12- Faça um algoritmo que leia um vetor de 20 posições a apresente o maior e o menor
valor e as posições que eles se encontram.
Resposta:

// Seção de Declarações
var

i,maior,menor,posicaomaior,posicaomenor:inteiro
numeros:vetor[1..20] de inteiro

inicio
// Seção de Comandos

para i de 1 ate 20 faca


escreva("Informe o valor da posicao: ",i,": ")
leia(numeros[i])
se i=1 entao
maior<-numeros[i]
menor<-numeros[i]
fimse

se numeros[i]>maior entao
maior<-numeros[i]
posicaomaior<-i
fimse

se numeros[i]<menor entao
menor<-numeros[i]
posicaomenor<-i
fimse
fimpara

p. 45 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

escreval("")
escreval("")

escreval("O maior numero é o: ",maior," Na posicão: ",posicaomaior)


escreval("O menor numero é o: ",menor," Na posicão: ",posicaomenor)

fimalgoritmo

13- Faça um algoritmo para somar duas matrizes.


Resposta:

// Seção de Declarações
var

l,c:inteiro
matrizA:vetor[1..3,1..3] de inteiro
matrizB:vetor[1..3,1..3] de inteiro
matrizC:vetor[1..3,1..3] de inteiro

inicio
// Seção de Comandos

// MATRIZ A
para l de 1 ate 3 faca
para c de 1 ate 3 faca
escreval("MATRIZ A")
escreva("Informe o valor da posicao: ",l,"-",c,": ")
leia(matrizA[l,c])
limpatela
fimpara
fimpara

limpatela

// MATRIZ B
para l de 1 ate 3 faca
para c de 1 ate 3 faca
escreval("MATRIZ B")
escreva("Informe o valor da posicao: ",l,"-",c,": ")
leia(matrizB[l,c])
limpatela
fimpara
fimpara

limpatela

// MATRIZ C
para l de 1 ate 3 faca
para c de 1 ate 3 faca
matrizC[l,c]<-matrizA[l,c]+matrizB[l,c]

p. 46 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

fimpara
fimpara

escreval("MATRIZ A")

para l de 1 ate 3 faca


escreval("")
para c de 1 ate 3 faca
escreva(matrizA[l,c])
fimpara
fimpara

escreval("")
escreval("")
escreval("MATRIZ B")

para l de 1 ate 3 faca


escreval("")
para c de 1 ate 3 faca
escreva(matrizB[l,c])
fimpara
fimpara

escreval("")
escreval("")
escreval("A SOMA DAS MATRIZES A e B")

para l de 1 ate 3 faca


escreval("")
para c de 1 ate 3 faca
escreva(matrizC[l,c])
fimpara
fimpara

escreval("")
escreval("")

fimalgoritmo

14- Dado uma matriz de 4x5 elementos, escreva um algoritmo para calcular a soma de
cada uma das linhas.
Resposta:

var
l,c,total:inteiro
numeros:vetor[1..4,1..5] de inteiro

inicio
// Seção de Comandos

para l de 1 ate 4 faca

p. 47 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

para c de 1 ate 5 faca


escreva("Informe o valor da posicao: ",l,"-",c,": ")
leia(numeros[l,c])
fimpara
fimpara

limpatela

para l de 1 ate 4 faca


escreval("")
para c de 1 ate 5 faca
escreva(numeros[l,c])
fimpara
fimpara

escreval("")
escreval("")

para l de 1 ate 4 faca


total<-0;
para c de 1 ate 5 faca
total<-total+numeros[l,c]
fimpara
escreval("A soma da linha: ",l," = ",total)
fimpara

fimalgoritmo

15- Escreva um algoritmo para ler dois números e exibir o menor dos dois. A verificação
de qual deles é o menor deve ser realizada por uma função.
Resposta:

algoritmo "Calcula_Quadrado"
// módulo para cálculo do quadrado de um número

funcao quadrado (r : real):real


// declaração de variáveis
Var
x : real
inicio
// calcula o quadrado
x <- r * r
// passa para o algoritmo chamador o valor obtido
retorne x
fimfuncao

// módulo para ler um número


procedimento ler_numero (var val : real)
inicio
//solicita um número ao usuário
escreva ("Entre com um número: ")

p. 48 Paulo Ricardo Siqueira Soares


Desenvolvimento de Software, Treinamentos e Consultoria em Gestão de Projetos

leia (val)
fimprocedimento

// declaração de constantes e variáveis


var
num, x : real
inicio
// lê um número
ler_numero(num)
// calcula o quadrado
x <- quadrado(num)
// escreve o quadrado
escreva ("O quadrado do número é: ", x)
Fimalgoritmo

16- Fazer um algoritmo para o usuário informar uma frase e o número de vezes que o
programa deve repetir essa frase na tela.
Resposta:

Algoritmo “soma”
Var
string:caractere
repetir:inteiro
contador:inteiro
Inicio
escreval(“Digite uma frase:”)
leia(string)
escreval(“Digite a quantidade de vezes para repetir:”)
leia(repetir)
escreval (“resultado:”)
enquanto contador < repetir faca
escreval(string)
contador <- contador+1
fimenquanto

fimalgoritmo

Bibliografia:

https://www.google.com/search?q=algoritmo+cadeia+de+caracteres&rlz=1C1SQJL_pt-
BRUS825US825&oq=algoritmos+cadeia+de+ca&aqs=chrome.1.69i57j0.6303j0j4&sourc
eid=chrome&ie=UTF-8

Ricardo Reis – Algoritmos

https://www.dca.ufrn.br/~affonso/DCA800/pdf/algoritmos_parte1.pdf

http://joinville.ifsc.edu.br/~edsonh/Repositorio/Microcontrolador/Livro%20de%20Pro
grama%C3%A7%C3%A3o/Cap7%20-%20Modularizando%20Algoritmos_v7.pdf

p. 49 Paulo Ricardo Siqueira Soares

Você também pode gostar