Prévia do material em texto
I
PROGRAMAÇÃO BÁSICA
COM VISUALG
TEORIA E PRÁTICA
Mário Leite
Antonio Carlos Nicolodi
II
DEDICATÓRIAS
Dedico este livro às minhas quatro queridas, e inesquecíveis,
professoras do Curso Primário do “Grupo Escolar Emílio Soares”, da
cidade de Tombos (MG), no período de 1956-1959, que me
ensinaram a ler e escrever, para formar a base da minha Educação!
Olga de Oliveira Osken (in memorian)
Consuelo Idalina Ramos (in memorian)
Maria Passos Borba (in memoriam)
Terezinha Rezende Linhares
Mário Leite
Dedico esta obra à minha esposa Márcia e à minha filha Bianca que
me deram seu apoio incondicional.
Antônio Carlos Nicolodi
III
CITAÇÃO
O computador só faz aquilo que você o manda fazer; e não,
necessariamente, aquilo que você quer ele faça!
IV
AGRADECIMENTOS
Agradeço primeiramente a Deus que me deu força e persistência
para escrever mais este livro, depois de um bom tempo de muita
pesquisa, dedicação e muitas revisões.
Agradeço a todos os meus colegas professores e professoras da
Universidade de Uberaba (UNIUBE) pela força e incentivo que
sempre me deram em todas as minhas obras.
Agradeço ao professor Antonio Carlos Nicolodi pelos preciosos
esclarecimentos e atualizações da ferramenta Visualg, além desta
sua preciosa parceria.
Agradeço ao Clube dos Autores, pela oportunidade desta
publicação.
Mário Leite
Agradeço primeiramente aos meus pais por me dar a vida, à
minha esposa Márcia e à minha filha Bianca, por me ajudarem
nos momentos mais difíceis e nos de grandes alegrias; agradeço
também aos meus professores.
Agradeço muito ao meu grande amigo e parceiro Mário Leite por
me dar esta oportunidade de poder participar com ele desta obra,
que deverá ajudar muita gente no futuro. Mas, principalmente,
agradeço à Deus por me dar saúde e o conhecimento que pretendo
compartilhar com todos.
Antonio Carlos Nicolodi
V
SOBRE OS AUTORES
Mário Leite é natural de Tombos (MG); estudou física durante
dois anos no Instituto de Física da UFRJ; foi aluno de Iniciação
Científica do Centro Brasileiro de Pesquisas Físicas (CBPF:
Divisão de Física Nuclear) e do CNPq, no Rio de Janeiro. É
graduado e pós-graduado em engenharia pela Pontifícia
Universidade Católica do Rio de Janeiro (PUC/RJ), onde foi
professor auxiliar de ensino e pesquisa do Departamento de
Ciências dos Materiais e Metalurgia. É especialista em Análise
de Sistemas pelo Centro Universitário de Maringá
(UniCesumar/PR) e mestre em Engenharia de Produção pela
Universidade Federal de Santa Catarina (UFSC).
Trabalhou durante quatro anos na Indústria e Comércio de
Minérios (ICOMI), no estado do Amapá, como engenheiro de
pesquisas, desenvolvendo aplicações para o setor de produção.
Foi chefe do Setor de Informações Gerenciais da Mineração
Caraíba S.A (BA) durante nove anos, ministrando cursos de
técnicas de programação para os engenheiros da empresa, e
desenvolvendo aplicações para os setores de produção e
manutenção. Nesta empresa participou do projeto de mecânica
das rochas para implantação do sistema de escavação da mina
subterrânea, na adaptação do software de elementos finitos para
microcomputadores. É professor de linguagem de programação,
análise de sistemas e tecnologia da informação em cursos de
processamento de dados, sistemas de informação e administração
de empresas. Também é autor de vários livros nas áreas de
linguagens e técnicas de programação e ferramenta de ambiente
numérico. Atualmente é professor da Universidade de Uberaba
(UNIUBE) nas áreas de ferramentas computacionais e linguagens
de programação.
VI
Antonio Carlos Nicolodi é natural de Blumenau (SC); estudou
eletrônica no Centro Educacional Profissionalizante Herman
Hering (CEDUPHH), estudou Mecanografia e processamentos de
dados na ETEVI-Furb de Blumenau e Técnica em Informática
para a Internet no Instituto Federal Santa Catarina (IFSC). É
graduado em Gestão em Tecnologia da Informação e em
Administração de Empresas pela Uniasselvi-Fameblu, com pós-
graduado em Educação à Distância (EaD - Gestão e Tutoria) e
Governança em T.I. Trabalhou como programador na empresa
Apoio Informática (Blumenau), foi gerente de CPD na Escola de
Contabilidade aonde desenvolveu um sistema de integrado de
contabilidade. Foi sócio proprietário da empresa Domínio
Informática e programador chefe, onde desenvolveu vários
sistemas ERP para a comunidade do Vale do Itajaí; foi professor
no Colégio Doutor Blumenau na disciplina de programação
Cobol para os cursos de (Processamento de dados, Administração
de empresas e Contabilidade).
É professor de informática nas prefeituras de Gaspar e Ilhota,
professor de lógica de programação no CEDUPHH (Blumenau);
professor de arquitetura de computadores, lógica de programação
de cursos de informática, jogos de computadores, entre outros, na
Uniasselvi-Fameblu (Blumenau). Criador de vários métodos de
ensino de lógica de programação, entre eles o método conhecido
como portugol (algoritmos escritos em Português nos anos 1980-
83 também conhecido como português estruturado), usado por
vários professores/alunos e escritores (autores em suas obras
literárias técnicas). É um dos desenvolvedores do software
conhecido como Visualg até a versão 2.5 e o criador da versão
3.0 em 2014, que é o interpretador oficial de algoritmos escritos
em portugol. Atualmente é professor, lecionando no horário
noturno, e durante o dia é funcionário público na prefeitura de
Ilhota (SC) na área administrativa.
VII
PREFÁCIO
Eis-me aqui tecendo o prefácio do livro destes ilustres
profissionais - o engenheiro e programador Mário Leite, e o
professor Antônio Carlos Nicolodi, administrador, programador
que há décadas tem se dedicado a área da tecnologia da
informação sendo um dos idealizadores do Visualg.
É com agrado e satisfação que recebi o convite, por três motivos:
primeiro, porque apesar de eu ser administradora, o mundo da
programação sempre me fascinou; em segundo, por saber que
ambos autores estão preocupados em facilitar o aprendizado em
programação, ao apresentarem inúmeros exemplos de programas
que exploram as denominadas Estruturas de Controle, e em
terceiro porque encontraram uma nova forma de ensinar a
programar, o que torna o aprendizado mais leve e eficaz.
Atuo na gestão de cursos que apresentam em algum momento do
currículo a disciplina de programação e tenho observado a
barreira que o próprio aluno coloca quando participa da primeira
aula de programação, por ser uma disciplina vista como “hard”.
Sempre me perguntei o porquê da resistência em aprender
programação.
Eu encontrei a resposta junto a estes dois autores, quando
demonstram que para ensinar programação é preciso deixar para
trás métodos tradicionais ainda muito presentes nas Instituições
de Ensino Superior (IES). É preciso encontrar um novo sentido
de ensinar programação mais dinâmico e interessante apontaram
Mário e Antônio. À vista disso, uma das características mais
notáveis no trabalho desenvolvido por esses autores é a
preocupação de tornar evidente “o COMO FAZER”.
A obra composta trabalha, basicamente, com exemplos,
esquemas e exercícios dentro do ambiente do Visualg, o que
proporciona rápido aprendizado na programação com esta
ferramenta. Além disto, os exercícios propostos (e resolvidos ao
VIII
final do livro) é um fator decisivo para a complementação da
formação do programador, sanando as dúvidas ao longo do curso.
Tenho a convicção de que esta obra proporcionará a você adentrar
no universo da programação com uma visão muito mais clara de
que o COMO FAZER em Visualg pode significar tudo!
Boa leitura!
#Vamos aprender com prazer!
Andreia Mileski Zuliani Santos
Professorae Gestora de cursos EaD – Maringá-PR.
IX
NOTA DOS AUTORES
Este livro tem como objetivo principal ensinar os programadores
a utilizar o Visualg de maneira correta para tirar o melhor
proveito no aprendizado de Lógica de Programação com esta
ferramenta, nos diversos segmentos da Educação . É um guia que
orienta os usuários, tanto nos seus recursos e nas suas
funcionalidades básicas, quanto na própria linguagem da
ferramenta. Mostra uma maneira melhor e mais didática de como
criar, interpretar, editar e testar os algoritmos escritos em
português estruturado, sem a necessidade de utilizar qualquer
linguagem real, ajustando às suas necessidades.
Este livro mostra que este software, além ser prático e objetivo
para testar algoritmos, também possui todas as funcionalidades
de um bom editor de textos no padrão do Windows®, para criar
programas bastante funcionais dentro de um ambiente de
desenvolvimento integrado muito fácil de operar e com recursos
que podem ser equiparados a outros IDEs mais sofisticados.
A obra apresenta o software como sendo uma verdadeira
ferramenta no auxílio aos seus usuários, tanto para iniciantes
quanto para os mais avançados na área de programação,
auxiliando e mostrando várias formas de escrever e testar os seus
algoritmos, nos mais variados tipos de problemas resolvidos por
computador. Mostra a história da ferramenta, os seus novos
recursos, as novas funcionalidades e também os novos comandos
e funções da linguagem, além de muitos esquemas explicativos e
exercícios prontos e propostos para melhorar a eficiência do
aprendizado na criação de programas de computador.
Agosto de 2020
X
ORGANIZAÇÃO DO LIVRO
Capítulo 1 - Lógica de Programação
Neste capítulo o livro focaliza a “lógica de programação”
iniciando com os conceitos básicos sobre instruções, e em seguida
introduz o conceito de “algoritmo” de maneira bem clara e
intuitiva e com exemplos básicos de programas simples. Explica
como o algoritmo define a própria solução do problema; portanto
um assunto fundamental na programação. Mostra a sequência
básica de solução dos problemas através da programação:
algoritmo-pseudocódigo-código. Discute a importância de se
criar a lógica da programação. antes da codificação, frisando que
codificar (criar o código-fonte na linguagem de programação) é
apenas uma questão de saber a sintaxe da linguagem; mas, não é
programar, pois o fundamental é achar a solução mais eficiente e
mais eficaz para o problema; isto é, o fundamental é o “Como
Fazer”. No final do capítulo são propostos onze exercícios para o
usuário exercitar o aprendizado.
Capítulo 2 - O Visualg
Neste capítulo o software Visualg é apresentado com sua história,
seus recursos, seu funcionamento e sua linguagem baseada no
portugol. Mostra como esta ferramenta substitui, com vantagens,
os antigos “Testes de Mesa”, permitindo ao programador a
checagem imediata do algoritmo da solução do problema e o
aperfeiçoamento dessa solução. Explica seus comandos e
funções, além de apresentar a estrutura básica dos algoritmos
escritos no seu editor. Este capítulo mostra os recursos dessa
ferramenta, com esquemas e exemplos bem esclarecedores: como
editar e executar um programa, como verificar e corrigir os
XI
possíveis tipos de erros, No final são sugeridos onze exercícios
para praticar.
Capítulo 3 - Tipos de Dados no Visualg
Neste capítulo são apresentados os tipos de dados suportados pelo
Visualg, e como declarar elementos num programa. Também são
mostrados os operadores e operações permitidos pela ferramenta,
com exemplos bem esclarecedores de utilização dos tipos básicos
de dados na programação. Ao final do capítulo são propostos
doze exercícios para o leitor verificar seu aprendizado.
Capítulo 4 - Estruturas de Controle Visualg
Neste capítulo são apresentadas as estruturas de controle no
Visualg, com as regras e os conceitos aplicados aos operadores
lógicos e relacionais. Este capítulo trata dos chamados
“comandos compostos”, que permitem desviar o fluxo do
programa, como também repetir blocos de instruções. São
apresentadas as estruturas de desvios condicionais, desvio
selecionado e estruturas de repetição (loops). Explica a
importância dessas estruturas, pois, em programas reais a
execução das instruções nem sempre são sequenciais. Também
enfatiza a importância das indentações nos programas para
melhorar a legibilidade e detecção de erros. Doze exercícios são
propostos para verificação do aprendizado.
Capítulo 5 - Trabalhando com Vetores
Este capítulo inicia o estudo dos arrays, apresentando as variáveis
compostas que definem estruturas homogêneas, através de
vetores. Esses elementos são abordados neste capítulo sob uma
ótica bem didática, objetiva e fácil de entender; com esquemas,
figuras e exemplos esclarecedores. O assunto é tratado de maneira
a aumentar o nível de compreensão do leitor e baixar o nível de
dúvidas que muitas vezes aparecem em materiais de
XII
programação. Com um formato bem didático nos programas, o
assunto é explicado nos exemplos de modo bem contundente e
sem sofisticações São estudadas aplicações práticas com vetores,
além de operações, pesquisas e ordenações. Onze exercícios são
propostos para verificar o aprendizado.
Capítulo 6 - Trabalhando com Matrizes
Este capítulo apresenta as variáveis compostas que definem
estruturas homogêneas, através de matrizes. Complementando o
assunto “arrays”, este capítulo trata desses elementos, como uma
generalização dos vetores, de maneira bem fácil de entender:
começando bem tranquilo e aumentando o grau de complexidade
bem devagar. Declaração, inicialização, leitura e impressão dos
elementos de uma matriz são tratados de maneira bem simples, e
enfatizando as características dos arrays. Operações com
matrizes e cálculos de determinantes também são assuntos bem
discutidos e estudados neste capítulo de maneira bem didática e
prática. São propostos onze exercícios para o usuário trabalhar
seu aprendizado.
Capítulo 7 - Trabalhando com Registros
Neste capítulo é apresentado o conceito de registro para dados
heterogêneos, ao contrário dos vetores e matrizes que só
trabalham com dados homogêneos. Este oitavo capítulo
complementa os estudos sobre os tipos de estruturas de dados,
como uma extensão dos arrays. O objetivo é mostrar como criar
uma estrutura heterogênea em contraste com as estruturas
homogêneas representadas pelos arrays. É explicado como criar
estruturas - tal como uma tabela num banco de dados - para conter
dados de tipos diferentes para uma mesma entidade. Para testar o
aprendizado, sete exercícios são propostos ao final do capítulo.
XIII
Capítulo 8 - Modularização
Este capítulo aborda um tema importantíssimo para uma boa
programação: a “modularização de um programa”. O objetivo é
mostrar que esta técnica é fundamental para que o programa tenha
uma melhor legibilidade, além de ter sua manutenção bastante
facilitada. Explica como criar as sub-rotinas (procedimentos e
funções) nos programas, e como a rotina principal as chama e as
executa. Explica com bastante clareza as diferenças entre
procedimento e função, quanto ao modo de chamar, executar e
sobre o resultado. Também discute os tipos de passagem de
parâmetros: “por valor” e “por referência” através de esquemas
práticos. Doze exercícios são propostos ao final deste capítulo
para o usuário praticar.
Anexo - Soluções dos Exercícios Propostos
Neste anexo são apresentadas as soluções de todos os exercícios
propostos ao longo dos nove capítulos estudados.
Bibliografia e Referências Bibliográficas
XIV
SUMÁRIO
Capítulo 1 - Lógica de Programação .............................. 1
1.1 - Introdução ao Capítulo................................................... 1
1.2 - Conceitos básicos de Lógicade Programação .............. 1
1.3 - Algoritmo e Pseudocódigo ............................................ 5
1.3.1 - Algoritmo ......................................................... 5
1.3.2 - Pseudocódigo .................................................... 8
1.4 - Comando e Funções Internos de Pseudocódigo .......... 10
1.5 - Etapas da Solução de um Problema ............................. 11
1.6 - Variáveis e Constantes ................................................. 14
1.6.1 - Identificação de Variáveis .............................. 17
1.6.2 - Escopo de Variáveis ........................................ 20
1.7 - Constantes .................................................................... 21
1.8 - Programação x Codificação ......................................... 22
1.9 - Exercícios Propostos .................................................... 26
Capítulo 2 - O Visualg ................................................... 29
2.1 - Introdução ao Capítulo ................................................ 29
2.2 - Básico sobre Aprendizagem em Programação ............ 29
2.3 - Histórico do Visualg .................................................... 31
2.4 - O Visualg no auxílio à Programação ........................... 34
2.4.1 - A Tela Principal do Visualg ............................. 35
2.4.2 - Características Básicas da Ferramenta .......... 37
2.5 - Pseudocódigo x Visualg ............................................... 39
2.6 - Funcionalidades Práticas do Visualg ........................... 43
2.7 - Itens do Menu Principal .............................................. 44
2.7.1 - Opção “Arquivo” ............................................ 44
2.7.2 - Opção “Editar” ............................................... 48
2.7.3 - Opção “Run” ................................................... 51
2.7.4 - Opção “Exportar” ........................................... 53
2.7.5 - Opção “Manutenção” ...................................... 53
XV
2.7.6 - Opção “Help” ................................................. 59
2.8 - Áreas Funcionais do Visualg ..................................... 64
2.8.1 - Área do Programa ........................................... 65
2.8.2 - Área das Variáveis de Memória ...................... 66
2.8.3 - Área de Visualização dos Resultados ............. 72
2.9 - Funcionalidade dos Botões da Barra de Ícones .......... 73
2.10 - A “Barra de Status” ................................................... 79
2.11 - Palavras Reservadas .................................................. 79
2.12 - Funções, Comandos Internos e Palavras Chaves ....... 81
2.13 - Recursos de Cálculos Numéricos .............................. 84
2.14 - Manipulação de Caracteres ........................................ 85
2.15 - Operações de Entrada e Saída .................................... 88
2.16 - Arredondando Valores de Saída ................................ 93
2.17 - Mensagens de Erros ao Rodar o Programa ............... 95
2.17.1 - Erro de Sintaxe ............................................. 95
2.17.2 - Erro de Computação ................................... 101
2.17.3 - Erro de Lógica (bug) .................................. 103
2.17.4 - Erro de Incompatibilidade de Tipos ........... 105
2.17.5 - Erro de Instrução fora de área .................... 107
2.17.6 - Erro de Falta de Terminadores ................... 112
2.18 - Medindo o Tempo de Processamento .................... 117
2.19 - Depurando Programas ............................................ 118
2.20 - Comentários ............................................................ 120
2.21 - Exercícios Propostos ............................................... 123
Capítulo 3 - Tipos de Dados no Visualg ................... 127
3.1 - Introdução ao Capítulo............................................... 127
3.2 - Tipos Primitivos de Dados ......................................... 127
3.3 - Tipos Complexos ....................................................... 130
3.4 - Os Tipos de Dados Considerados no Visualg ............ 130
3.5 - Declaração de Variáveis no Visualg ........................ 131
3.6 - Operadores e Operações ............................................ 137
3.7 - Exercícios Propostos ................................................. 147
XVI
Capítulo 4 - Estruturas de Controle Visualg ............. 151
4.1 - Introdução ao Capítulo ............................................. 151
4.2 - Estruturas de Controle ............................................. 152
4.2.1 - Estruturas de Decisão .................................. 154
4.2.1.1 - Estrutura de Decisão Simples ......... 154
4.2.1.2 - Estrutura de Decisão Composta ...... 158
4.2.2 - Estrutura de Decisão Selecionada ............... 163
4.2.3 - Estruturas de Repetição (loops) ................... 167
4.2.3.1 - Loop Lógico com Teste no Início ... 168
4.2.3.2 - Loop Lógico com Teste no Final .... 175
4.2.3.3 - Loop Numérico ............................... 179
4.3 - Aninhamento de Decisões usando Se's ...................... 184
4.4 - Indentações ................................................................ 185
4.5 - Exercícios Propostos .................................................. 187
Capítulo 5 - Trabalhando com Vetores ...................... 193
5.1 - Introdução ao Capítulo ............................................. 193
5.2 - Conceitos básicos ...................................................... 193
5.3 - Operações Elementares com Vetores ....................... 196
5.4 - Declaração de Vetores no Visualg ............................. 198
5.5 - Atribuição Direta ..................................................... 199
5.6 - Atribuição por Leituras Individualizadas .................. 200
5.7 - Atribuição por Leituras Através de Loop .................. 202
5.8 - Operações Matemáticas Simples com Vetores ......... 206
5.8.1 - Soma de Vetores ........................................... 206
5.8.2 - Subtração de Vetores .................................... 208
5.9 - Aplicações de Vetores .............................................. 211
5.9.1 - Ordenação .................................................... 211
5.9.2 - Pesquisas ...................................................... 215
5.9.2.1 - Pesquisa Sequencial ...................... 216
5.9.2.2 - Pesquisa Binária ............................ 219
5.9.3 - Verificando Maior e Menor elemento ........ 222
5.9.4 - Soma e Média dos elementos ...................... 224
XVII
5.9.5 - Invertendo a Ordem dos elementos ............ 227
5.9.6 - Verificando Característica de elemento ....... 229
5.9.6.1 - Verificando elemento Múltiplo......229
5.9.6.2 - Verificando elemento Divisor ...... 231
5.9.6.3 - Verificando Paridade e Posição . . 233
5.9.7 - Incluindo/Excluindo/Alterando elemento ..235
5.9.7.1- Incluindo um novo elemento ........ 235
5.9.7.2 - Excluindo um elemento .............. 238
5.9.7.3 - Alterando o valor do elemento ..... 240
5.10 - Erros na utilização de Vetores ................................. 245
5.11 - Exercícios Propostos ................................................ 247
Capítulo 6 - Trabalhando com Matrizes .................... 253
6.1 - Introdução ao Capítulo .............................................. 253
6.2 - Conceitos Básicos .....................................................253
6.3 - Declaração de Matrizes no Visualg .......................... 256
6.4 - Leitura e Escrita de uma Matriz ................................ 258
6.5 - Operações com Matrizes ........................................... 261
6.5.1 - Adição de Matrizes ...................................... 261
6.5.2 - Subtração de Matrizes .................................. 265
6.5.3 - Multiplicação de Matriz por Escalar ............ 268
6.5.4 - Multiplicação de Matriz por Vetor .............. 271
6.5.5 - Multiplicação de Matriz por Matriz ............. 273
6.6 - Determinantes de Matrizes ....................................... 278
6.6.1 - Determinante de Matrizes de Ordem 2 ......... 278
6.6.2 - Determinante de Matrizes de Ordem 3 ........ 280
6.6.3 - Determinante de Matrizes de Ordem > 3 ..... 282
6.7 - Matriz Transposta ..................................................... 286
6.8 - Matriz Identidade ...................................................... 288
6.9 - Elementos das Diagonais de uma Matriz ................... 290
6.10 - Exercícios Propostos ................................................ 298
XVIII
Capítulo 7 - Trabalhando com Registros ................... 303
7.1 - Introdução ao Capítulo .............................................. 303
7.2 - Conceitos Básicos ..................................................... 303
7.3 - Manipulação de Registros ......................................... 305
7.4 - Conjunto de Registros ............................................... 309
7.5 - Leitura de um Conjunto de Registros ........................ 311
7.6 - Pesquisa em Conjunto de Registros .......................... 318
7.7 - Exercícios Propostos ................................................. 326
Capítulo 8 - Modularização ......................................... 327
8.1 - Introdução ao Capítulo .............................................. 327
8.2 - Conceitos Básicos ..................................................... 328
8.3 - Dividir para Unificar ................................................. 329
8.4 - Programação Modular ............................................... 329
8.5 - Sub-rotinas ................................................................ 333
8.5.1 - Procedimentos ............................................... 334
8.5.2 - Funções ......................................................... 336
8.6 - Parâmetros ................................................................ 342
8.6.1 - Passagem de Parâmetros ............................... 344
8.6.1.1 - Passagem Por Valor ........................ 349
8.6.1.2 - Passagem Por referência ................. 350
8.7 - Programas com Sub-rotinas ...................................... 354
8.8 - Acesso a Arquivos .................................................... 369
8.9 - Exercícios Propostos ................................................. 373
Anexo - Solução dos Exercícios Propostos ................. 379
Capítulo 1 ........................................................................... 379
Capítulo 2 ........................................................................... 383
Capítulo 3 ........................................................................... 388
Capítulo 4 ........................................................................... 395
Capítulo 5 ........................................................................... 405
Capítulo 6 ........................................................................... 415
XIX
Capítulo 7 ........................................................................... 424
Capítulo 8 ........................................................................... 428
Bibliografia e Referências Bibliográficas ................... 437
1
Capítulo 1 - Lógica de Programação
1.1 - Introdução ao Capítulo
O processo de criação de um programa passa, necessariamente,
pela análise do problema a ser resolvido, e em seguida sua
solução deve ser criada com uma sistemática que possa resolver
o problema. Essa sistemática é baseada numa lógica que deve
implementar uma solução. E, embora uma linguagem de
programação seja importante para automatizar a solução do
problema, o programa tem que ser elaborado, antes, de modo que
essa solução seja a melhor possível. Ao final, a tradução do
código-fonte numa linguagem de programação deve ser
“introduzida” no computador para dar a informação desejado ao
usuário. A etapa que antecede a criação do código-fonte em
linguagem de programação, é o que implementa a solução; por
isto, é importante frisar que codificar (criar o código-fonte na
linguagem de programação) é apenas uma questão de saber a
sintaxe da linguagem; mas, isto não cria a solução do problema,
pois o fundamental é achar a solução mais eficiente e mais eficaz,
1.2 - Conceitos Básicos de Lógica de Programação
Lógica de Programação pode ser definida como uma “técnica de
desenvolver sequências de ações para atingir um objetivo bem
determinado”. Essas sequências são adaptadas para uma
linguagem de computador a fim de produzir o programa.
Atualmente toda as comunicações dos usuários com os
computadores são feitas através de bytes, que trazem no seu
contexto as ordens para que o computador resolva o problema
2
apresentado pelo usuário, na forma de um programa. Na prática,
o problema é analisado, estudado e manipulado por um outro
personagem no ambiente da computação: o programador. O
programador é quem cria e escreve as ordens que serão dadas ao
computador para que apresente uma solução para o problema. A
figura 1.1 mostra um esquema de como fica a interação: usuário-
programador-computador.
Usuário
Programador
Nível computacional
Figura 1.1 - Trazendo o problema para o nível computacional
O usuário apresenta o problema ao programador, que o refina e
traduz para o computador executar as ordens embutidas nesses
refinamentos. E para que essas ordens sejam executadas
corretamente, elas devem ser escritas como texto, e numa
sequência lógica, tal que a solução apresentada pelo computador
seja correta e satisfaça o usuário. Essas ordens são traduzidas
(codificadas) num texto chamado de código-fonte.
Existem várias definições para “Lógica”, além daquela
mencionada no início deste item, mas, de um modo geral, é
possível resumir essas definições em uma só: “Logica é a forma
ordenada do pensamento”. Do ponto de vista prático, pode-se
dizer que lógica de programação é a forma ordenada de escrever
Problema ???
3
as ações para resolver um problema. Para os programadores, é
muito importante saber distinguir três definições:
• Linguagem de programação é um conjunto de regras que
definem como os comandos e funções devem se
comportar dentro dos programas de computador.
• Programas são as ordens dadas ao computador para que
execute as tarefas exigidas no processamento, a partir de
um conjunto de comandos e funções, seguindo uma
sequência estabelecida.
• Algoritmo é o conjunto de instruções na forma de texto
descritivo, usando um método de montagem conforme a
lógica, para resolver o problema,
Os métodos de ensino de disciplinas de “Lógica de Programação”
têm nomes variados, mas com o mesmo propósito, como:
• Técnicas de Programação.
• Algoritmos.
• Lógica de Programação.
Essas disciplinas apresentam em sua ementa vários métodos de
ensino da lógica; entre os quais podem ser destacados:
1) Método do Algoritmo Descritivo: que literalmente descreve
passo a passo cada etapa de um processo da solução do problema.
2) Métododos Diagramas Gráficos (fluxograma e diagramas de
blocos): onde, por meio de desenhos gráficos é descrito o fluxo
do processo, mostrando como funciona o raciocínio lógico e as
estruturas de controle.
3) Método da Pseudolinguagem (ou Pseudocódigo), que pode
ser apresentado através de uma pseudolinguagem de
programação, como o portugol (português estruturado).
4
O portugol (que é a junção de Português+algol) é uma
pseudolinguagem de programação; ou seja, é um método para
ensinar lógica de programação, muito importante para os
iniciantes no assunto “programação de computadores”. Ele
permite ao aluno entender o que cada comando (ordem) significa,
antes mesmo de saber como será o programa real; por isto é um
método muito poderoso. Um algoritmo não é um programa, mas
ele exprime a lógica do processo para solucionar o problema; o
aluno deve construir um algoritmo antes de codificar em
linguagem de programação real.
Todas as linguagens de programação têm seus códigos-fonte
escritos em Inglês; isto por que esse idioma é o que mais se adapta
ao ambiente computacional, devido ao seu poder de compactação
dos termos. ENTRETANTO, é preciso distinguir BEM o termo
“programação” do termo “codificação”!!!
“Programação é o ato intelectual de escrever a solução do
programa em função do algoritmo (solução descritiva do
problema), e que pode ser aprimorada com uma solução mais
formal (pseudocódigo).”
“Codificação é o ato técnico de converter a solução escrita
pseudocódigo em texto (o chamado código-fonte), baseado na
sintaxe da linguagem escolhida”.
Embora, na prática possa ser dito “programar em Java”, na
verdade, o correto seria: “codificar em Java”, pois a programação
para resolver o problema é feita através da seguinte sequência:
1. Análise do problema;
2. Criação do algoritmo para resolver o problema, em
nível informal;
3. Criação do pseudocódigo para formalizar a solução em
nível mais técnico;
4. Codificação do programa.
5
É esta a sequência - em uma explicação bem simples - que deve
ser executada para resolver um problema num ambiente
computacional.
1.3 - Algoritmo e Pseudocódigo
Embora muitos autores tratem os dois termos como sendo a
mesma coisa, existe uma diferença que pode ser bem marcante
entre algoritmo e pseudocódigo.
1.3.1 - Algoritmo
Existem muitas definições para “algoritmo”; uma delas é dada da
seguinte forma: “Algoritmo é uma sequência de passos factíveis
de execução, com início e fim, que quando executados produzem
a solução de um problema”, Leite (2006, p. 54). Um exemplo
clássico de algoritmo é o famoso problema “Trocar uma
lâmpada”, resumido nos seguintes passos na descrição a seguir...
Início
1 - Pegue uma lâmpada nova.
2 - Teste a lâmpada.
3 - Se lâmpada passar no teste Passo 4; Senão Passo 1
4 - Pegue uma escada.
5 - Posicione a escada no local correto.
6 - Suba os degraus da escada.
7 - Retire a lâmpada queimada.
8 - Coloque a nova lâmpada.
9 - Desça a escada.
11 - Descarte adequadamente a lâmpada queimada.
Fim
6
Embora os termos Início e Fim não sejam obrigatórios, é
importante colocá-los para frisar que um algoritmo sempre deve
ter um início e um fim bem determinados, como citado por Leite
(2006, p. 54). Pelo esquema da solução do problema “Trocar uma
lâmpada”, pode ser observado que as ações dadas a cada passo
sempre devem estar colocadas em verbos no modo Imperativo
Afirmativo: Pegue, Teste, Suba, etc, para dar sentido de ordenar,
exigir! Então, pelo que foi visto, pode-se afirmar que: “Algoritmo
é uma descrição textual e informal da solução do problema”. Em
outras palavras, o algoritmo é a própria solução do problema; se
o algoritmo estiver correto, o problema está resolvido. Simples,
assim!
❖ Exemplo 1.1 - Fazer um algoritmo para verificar se um
número A é divisível por um número B.
Início
1 - Leia o número A.
2 - Leia o número B.
3 - Se B diferente de 0, Então divida A por B e siga em
frente, Senão vá ao Passo 5.
4 - Mostre o resultado.
5 - Pare.
Fim
7
A solução do Exemplo 1.1 já apresenta uma ação que é muito
comum (fundamental) na lógica de programação: Leia. Ela
ordena ao processador a “pegar” o valor digitado pelo usuário e
armazená-lo na memória RAM, definindo o que se chama de
entrada de dados através de leitura. A ação (comando) Se define
uma ordem condicional, analisando uma situação que pode ter um
dos dois valores lógicos possíveis: Verdadeiro ou Falso. Então,
se o número B for um número diferente de 0 (a Matemática não
define divisão por 0), a operação será efetuada e o resultado
mostrado, no passo 4;. Senão (caso contrário), se B for igual a
zero, o passo 4 não será executado e o fluxo do algoritmo será
desviado para o passo 5 (último passo do algoritmo), encerrando
a solução.
Nota: As ações (comandos) Se, Então e Senão são empregados em
“situações” em que haja necessidade de se tomar uma decisão; são
termos que definem comandos condicionais dentro num algoritmo.
Estes serão vistas com mais detalhes no Capítulo 4.
❖ Exemplo 1.2 - Criar um algoritmo para verificar se um
determinado número é par ou ímpar.
8
Início
1 - Leia o número.
2 - Divida o número por 2.
3 - Se o resto da divisão for 0, Então siga em frente,
Senão vá para o Passo 6.
4 - Escreva “O número é par”.
5 - Vá para o passo 7.
6 - Escreva “O número é ímpar”
7 - Pare
Fim
1.3.2 - Pseudocódigo
O pseudocódigo é o algoritmo escrito numa forma mais formal,
mais técnica, utilizando as ordens convertidas em comandos mais
rigorosos. Deste modo, as ações passam a ter um carácter mais
computacional, o que torna a solução do problema menos
descritiva e mais compacta. O esquema abaixo mostra o layout de
um pseudocódigo, que aqui será adotado:
Programa "nome-do-programa"
Declare <lista de variáveis do tipo 1>
Declare <lista de variáveis do tipo 2>
...
Início
Aqui são escritas as instruções do algoritmo
Instrução1
Instrução2
Instrução3
...
FimPrograma
9
Observe como ficam as soluções dos dois exemplos anteriores em
pseudocódigo.
Programa "Divide"
Declare A, B, C: real
Início
Leia(A)
Leia(B)
Se(B<>0) Então
C <- A/b
FimSe
EscrevaLn(C)
FimPrograma
Note que as soluções em pseudocódigo ficaram bem mais
compactas, e com as ordens dadas de maneira mais técnica. Por
exemplo, o comando FimSe para indicar a finalização de uma
decisão, e Escreva para mostrar o resultado.
Programa "VerificaNumero"
Declare A, R: inteiro
Início
Leia(A)
R <- Resto(A/2) //resto da divisão de A por 2
Se(R=0) Então
Escreva("O número é par")
Senão
Escreva("O número é impar")
FimSe
FimPrograma
10
1.4 - Comandos e Funções Internos de Pseudocódigo
Nos programas escritos em pseudocódigo, às vezes, é necessário
empregar comandos e/ou funções para agilizar o processo, como,
por exemplo, “pegar a parte inteira de uma divisão entre dois
números”. Se fosse utilizar uma descrição formal, isto seria muito
complicado e ficaria mais ou menos assim:
...
Leia(N1)
Leia(N2)
Se(N2<>0) Então
X <- Pega parte inteira da divisão de N1 por N2
Escreva(X)
FimSe
...
Observe que a linha de código onde o resultado da divisão é
atribuído à variável X ficou muito estranha; parecendo uma linha
de algoritmo e não de pseudocódigo. A linha de instrução em
pseudocódigo ficaria assim: X <- Int(N1/N2), muito mais
racional. Por isto, existem algumas ordens (comandos e funções)
internas, utilizadas para melhorar a legibilidade do programa. A
tabela 1.1 mostra alguns comandos e funções que são utilizados
nos pseudocódigos.
Ordem Tipo O que Faz
Declare v1, v2, v3 Comando Cria variáveisde memória.
Escreva(x) Comando Exibe o conteúdo da variável x
na tela e fica na mesma linha.
EscrevaLn(x) Comando Exibe o conteúdo da variável x
na tela e salta para nova linha.
EscrevaLn("") Comando Apenas salta uma linha.
11
Leia(x) Comando Lê o conteúdo da variável x para
a memória.
Pare(n) Comando Suspende o processamento por n
milissegundos.
LimpaTela Comando Limpa a tela do monitor de
vídeo.
Abandone Comando Sai do loop incondicionalmente.
Int(A/B) Função Retorna a parte inteira da divisão
de A por B.
Resto(A/ B) Função Retorna o resto inteiro da divisão
de A por B.
RaizQ(x) Função Retorna raiz quadrada de um
número x não negativo.
Abs(x) Função Retorna o valor positivo de um
número x.
Tamanho("s") Função Retorna o número de caracteres
de uma string "s".
Tabela 1.1 - Alguns Comandos e Funções utilizados em pseudocódigos
1.5 - Etapas da solução de um Problema
Nas situações reais a solução de um problema pode ser mais
complexa, exigindo técnicas de análise de sistemas e alguma
complexidade. Mas, de qualquer forma, a sequência básica para
resolver um problema através de um programa de computador,
pode ser resumida no esquema da figura 1.2.
Problema Algoritmo Pseudocódigo Código
Figura 1.2 - Esquema básico da criação de um programa
12
❖ Exemplo 1.3 - Ler dois números, fazer a troca de valores entre
eles, e depois mostrar esses dois números com seus valores
trocados.
Algoritmo:
Início
1 - Leia o primeiro número
2 - Leia o segundo número
3 - Troque os valores entre os dois números
4 - Mostre os dois números com seus novos valores
Fim
Pseudocódigo:
Programa "Trocas"
//Lê dois números, faz a troca entre eles.
//Autor: Mário Leite
//-----------------------------------------------------
Declare A, B, X: inteiro
Início
Escreva("Digite o primeiro número A: ")
Leia(A)
Escreva("Digite o segundo número B: ")
Leia(B)
X A //preserva o valor do primeiro número
A B //faz o primeiro número igual ao segundo
B X //faz o segundo número receber o preservado
EscrevaLn("") //salta linha
EscrevaLn("Valor final de A: ", A)
EscrevaLn("Valor final de B: ", B)
FimPrograma
13
Observe que, embora o algoritmo não mencione esse detalhe, no
pseudocódigo a lógica mandou preservar o valor do primeiro
número para, só no final, colocá-lo no segundo número; caso isto
não fosse feito, os dois ficariam com um mesmo valor e a troca
não seria efetivamente conseguida.
MAS... como saber se os resultados estão corretos, ANTES DA
CODIFICAÇÃO!!??
Para testar a correção de um programa são utilizados os chamados
“Testadores de Algoritmos”, ou “Interpretadores de Algoritmos”.
E um desses, talvez o mais famoso e mais popular é o Visualg
(Visualizador de Algoritmos) que será visto no próximo capítulo.
Essa ferramenta - uma pseudolinguagem de programação - é
muito importante para os iniciantes no assunto, pois permite testar
o programa, antes mesmo de codificá-lo numa linguagem real e
mais potente; pois o que interessa é verificar se o algoritmo está
correto. E, embora o Visualg não seja uma linguagem formal de
programação, ele é muito importante no aprendizado de “Lógica
de Programação”, pois permite ao programador ter uma visão
mais clara da solução já em nível de pseudocódigo. Esta
ferramenta pode ser classificada como “um interpretador de
algoritmos”, que facilita em muito o aprendizado, com um editor
onde é escrito o pseudocódigo do programa, em portugol, e é
distribuída pela Internet, gratuitamente.
Mas, qual é, então, a diferença entre Visualg e o Basic, por
exemplo?! A diferença básica está nos termos empregados para
uma mesma instrução; por exemplo, para exibir o valor da
variável X no monitor de vídeo: em Visualg é Escreva(X) e no
Basic é Print(X); em Visualg utiliza-se o idioma Português
adaptado, e nas outras linguagens é sempre no idioma Inglês.
De tudo que foi visto até agora, pode ser concluído que só depois
de passar pelo estudo do algoritmo/pseudocódigo e um
interpretador de algoritmos é que se deve adotar uma primeira
14
linguagem de programação real, que poderá ser o Pascal, com
qualquer um dos compiladores oferecidos no mercado; entre eles
o Pascal Zim! que é distribuído gratuitamente na Internet.
Portanto, codificar um programa numa linguagem real SEM
ANTES passar pela sua lógica da solução, não é uma boa atitude
de programação.
1.6 - Variáveis e Constantes
Nos exemplos anteriores de programas em pseudocódigo, foram
empregadas muitas linhas de códigos com instruções em que uma
letra (ou conjunto de letras e números) foi colocado à esquerda
do símbolo como por exemplo, no programa “Trocas”,
Aux A
A B
B Aux
Aux, A1 e B são as “VARIÁVEIS” utilizadas para
manipulação/armazenamento dos dados que a lógica do programa
exigiu para resolver o problema proposto.
Mas... o que são variáveis; para que servem?!
A memória RAM de um computador pode ser comparada a um
armário com várias gavetas, onde cada gaveta representa um local
de armazenamento. Cada local desses é um endereço de memória,
com uma identificação própria denominada endereço real e que
só a CPU pode” acessá-lo diretamente. Então, como o
programador não conhece o endereço real, ele tem que acessá-lo
simbolicamente através do conceito de “variável de memória”.
De acordo com Leite (2006) “Variáveis de memória, ou
simplesmente variáveis, são endereços simbólicos da memória
principal definidos pelo programador, onde são armazenados
temporariamente valores para serem processados, ou resultado
de algum processamento”. Quer dizer: variável pode ser
15
considerada uma unidade de armazenamento em nível de
programação; e é importante saber que esses locais” são voláteis;
os valores ali alocados podem ser alterados e/ou descartados
depois de certo tempo, dependendo das circunstâncias. Por isto,
o resultado de um processamento, que originalmente estava em
uma variável, deve ser salvo de forma definitiva em uma mídia:
fita, disco, pen drive etc; senão o valor será perdido
definitivamente.
❖ Exemplo 1.4 - Criar um programa para obter o salário líquido
de um funcionário a partir de seu salário bruto, após descontar a
contribuição para o INSS:
O Algoritmo poderia ser assim:
1 - Entre com o valor do Salário Bruto
2 - Entre com o valor do percentual de desconto
3 - Calcule o Desconto: DC = SB*(PD/100)
4 - Calcule o Salário Líquido: SL = SB - DC
5 - Mostre o resultado armazenado em SL
Note que cinco passos foram usados para calcular o salário
líquido de apenas um empregado. Na verdade, uma empresa -
mesmo sendo uma microempresa - não possui apenas um
empregado; assim o processamento deve ser usado para todos
eles. Deste modo, a cada processamento os valores de SB, PD,
DC e SL se alteram; e se não forem salvos o valor de cada SL em
locais permanentes, ao final do processamento de todos os
funcionários da empresa só restará o valor do salário líquido do
último empregado. Os termos SB e PD são variáveis utilizadas
para armazenar os dados de entrada; DC é uma variável que
armazena o valor calculado para o desconto, e SL uma variável
onde é guardado o resultado do salário líquido de um funcionário;
16
mas todos eles são locais simbólicos da memória principal. A
figura 1.3 apresenta um esquema desta situação.
Nota: SB, PD, DC e SL são os nomes das variáveis empregadas no
problema apresentado no Exemplo 1.4. Entretanto, conforme será
explicado mais adiante, esses nomes deveriam ser mais explícitos para
traduzir melhor o que cada um deles significa no contexto. São como
“caixas” rotuladas para guardar algo que o programador deseja.
variável SL variável PD
3600 104000
400
variável DC variável SB
Figura 1.3 - Armazenamento de valores em variáveis de memória
17
Além do endereço e valor, uma variável também necessita ter um
tipo de dado que qualifique o valor armazenado (tipos de dados
serão vistos no Capítulo 3); em resumo: uma variável deve ser
definida em função das seguintes características:
• Identificador ==> endereço (nome simbólico na
memória).
• Valor ==> quantidade armazenada no
momento.
• Tipo de Dado ==> qualidade do valor armazenado.
• Escopo ==> visibilidade (abrangência) dentro do
programa.
Programa "ControleSalario"
//Controla o salário de um empregado
//Autor: Mário Leite
-----------------------------------------------------
Declare SB, SL, PD, DC: real
Início
Escreva("Digite o valor do salário bruto: ")
Leia(SB)
Escreva("Digite o percentual do desconto: ")
Leia(PD)
DC <- SB*(PD/100)
SL <- SB - DC
EscrevaLn("Salário líquido: ", SL)
FimPrograma
1.6.1 - Identificação de Variáveis
Nas literaturas sobre programação, dependendo até da linguagem,
são sugeridas algumas regras para criar identificadores de uma
variável; entretanto, a regra mais importante é esta: “o
18
identificador de uma variável deve traduzir o significado do que
ela armazena”. Um exemplo seria o de identificar uma variável
que armazenasse o valor da devolução do imposto de renda do
ano de 2020. Neste caso poder-se-ia optar por qualquer um dos
nomes a seguir:
• IR
• DevIR
• DevIR20
• Devolucao_do_Imposto_de_Renda_de_2020
Qual destes identificadores você utilizaria?
O primeiro parece muito curto; o segundo parece mais prático que
o primeiro, pois sugere uma devolução com o emprego do prefixo
Dev. O terceiro é mais explícito, pois indica que a devolução é do
ano de 2020. E o quarto identificador, também poderia ser
utilizado? Sim poderia; mas não deveria, pois apesar de ser o mais
explícito de todos é muito longo! Então, entre as quatro opções
apresentadas o identificador que mais se aproxima do ideal seria
o terceiro: DevIR20, pois além de traduzir bem o que é
armazenado na memória não é muito curto e nem
demasiadamente longo. De qualquer forma, a escolha do nome
(identificador) de uma variável vai depender muito do bom senso
do programador; não existe uma regra rígida para isto, apenas que
ele explique o que vai ser armazenado naquele endereço, porém
sem exageros; mas, existem algumas regras básicas:
1. Deve começar sempre com uma letra (A-Z, a-z) ou com
underline (_).
2. Não pode ser utilizado caractere especial ou pontuação (?
> < @ &*, . # ; -).
3. Não pode haver espaços em branco entre os caracteres.
4. O tamanho deve ser de no máximo 255 caracteres[5].
19
5. Não podem ser utilizadas letras acentuadas (á ó ê ã,) e
nem o cedilha (ç).
6. Não pode utilizar palavras reservadas de linguagens de
programação[6] ou de pseudocódigo.
7. Devem ser evitadas variáveis com identificadores
contendo as letras “I”, e “O” pois, podem ser confundidas
com os dígitos 1 e 0, respecivamente.
Nota: Embora existam linguagens de programação que tratam de modo
sensível os identificadores de variáveis (por exemplo, no C DevIr20 é
diferente de DeveIR20) em pseudocódigo não existe case sensitive em
relação a nome de variáveis. Portanto aqui DevIr20, DEVIR20,
devIR20, Devir20, devir20, DeViR20, etc, são uma mesma variável.
Identificador O que poderia significar
DevIR20 Devolução do Imposto de Renda de 2020.
TotAluFem Total de alunos do sexo feminino.
TotGeral Total geral.
Soma Soma de alguns valores num programa.
Fat Fatorial de um número.
Nota1Alu Primeira nota de um aluno.
Nota1Qui Primeira nota em Química.
NomeCli Nome de cliente.
Num Um número lido.
EndCli Endereço de cliente.
ArqCli Arquivo de clientes.
TotVendas Total de vendas.
TotVendDez Total de vendas em Dezembro.
TotVend20 Total de vendas em 2020.
Tabela 1.2 - Exemplos de identificadores válidos
20
Identificador O que deveria
significar
Por que não é válido
20DevIR Devolução do Imposto
de Renda de 2020.
Começa com dígito
Tot AluFem Total de alunos do sexo
feminino.
Tem espaço entre as letras t e A.
Tot&Geral Total geral. Tem caractere especial (&).
Valor$ Valor monetário. Tem caractere especial ($).
PreçoUnit Preço unitário de um
produto
Possui ç no identificador.
1aNotaAlu Primeira nota. Possui letra sobrescrita.
maçã Nome de fruta. Possui letra acentuada e cedilha.
Next Próximo Comando da linguagem VB.
Read Ler Comando da linguagem Pascal
Resto Resto de uma divisão Função em pseudocódigo.
Var Valor de uma variável Palavra reservada de linguagem.
int Inteiro Tipo de dado da linguagem C.
EndereçoCli Endereço de um cliente. Possui ç no identificador.
Tabela 1.3 - Exemplos de identificadores inválidos
1.6.2 - Escopos de Variáveis
Além do identificador, do tipo de dado e do valor contido as
variáveis possuem também escopo, que quer dizer “visibilidade”
ou “abrangência” dentro de um programa. O escopo define em
que partes do programa uma variável poderá ser acessada ou
referenciada. Existem dois tipos de escopos: local e global.
Variáveis locais só podem ser acessadas dentro da rotina que as
definiram, ao passo que as globais podem ser acessadas em
qualquer parte do programa. Para programas compostos de
módulos, ou subprogramas, cada subprograma desses poderá ter
21
suas próprias variáveis locais que poderão ser acessadas somente
dentro de cada um deles (este assunto será visto no Capítulo 8).
1.7 - Constantes
O valor de PI - razão entre o comprimento de uma circunferência
e seu diâmetro - é, normalmente, usado como 3.14 (com apenas
duas casas decimais). Entretanto, acredite: o PI já foi calculado
com oito quatrilhões de casas decimais! Esta constante é
mostrada abaixo com cinquenta decimais...
3.14159265358979323846264338327950288419716939937511
De qualquer forma, as constantes também representam,
simbolicamente, endereços da memória RAM; entretanto, ao
contrário de uma variável, o valor armazenado em uma constante
não pode ser alterado durante o processamento. Isto quer dizer
que ao declarar uma constante deve-se definir imediatamente seu
valor, o qual permanecerá inalterável durante todo o
processamento do programa. Quanto às outras características
(identificador, tipo de dado e escopo) elas funcionam de forma
semelhante às variáveis. Na prática de programação, embora não
seja uma regra, os identificadores das constantes criadas são,
normalmente, indicados com letras em caixa alta; todas
maiúsculas; eis alguns exemplos:
• PI
• TECLA
• GRAVIDADE
• DESCONTO
• TAXA
• FATOR
Nos programas em que determinado valor permanece constante,
é sempre mais interessante empregar constante, e com escopo
global. Por exemplo, para a constante PI:
Const PI=3.141592653589793 //ANTES das declarações das variáveis
22
Nota: Sempre que possível deve-se empregar variáveis locais nos
programas. As variáveis globais, devido à exposição em todo o
programa, estão sujeitas a interferências e acessos externos indevidos,
o que pode comprometer todo o código. Além disto, em algumas
linguagens de programação, as variáveis globais fragmentam o código
executável, tornando-o maior e além do necessário, fazendo com que
haja perda de performance.
1.8 - Programação x Codificação
Existem dezenas de linguagens de programação nas quais um
mesmo programa pode ser codificado (ou, implementado, como
preferem alguns). Mas, não se deve confundir Programação com
Codificação; rigorosamente falando, o termo “Linguagem de
Programação” deveria ser alterado para “Linguagem de
Codificação”.
Programar é criar uma rotina, seguindo uma lógica, para executar
um trabalho qualquer. Esta definição, certamentelevará o leitor a
pensar que programar é criar uma receita de bolo; e é isto mesmo!
Afinal, escrever um programa nada mais é do que criar uma
receita para resolver um problema qualquer. O trabalho da LP é
apenas a tradução das ações da rotina a serem implementadas, em
códigos na sintaxe exigida pela linguagem; é claro que a
Codificação é importante, mas não é a parte mais fundamental na
criação do programa; pois, na hora da codificação o problema já
deve estar resolvido.
23
❖ Exemplo 1.5 - Ler dois números, inteiros e positivos e criar
um pseudocódigo para calcular e mostrar o MDC (Máximo
Divisor Comum) desses dois números.
Embora seja um assunto bem popular e ensinado no Curso
Fundamental, o MDC (maior número inteiro positivo que divide,
simultaneamente, dois ou mais números) é muito importante em
estudos de Matemática Superior, como, por exemplo, na proteção
de dados através da criptografia de chave assimétrica, em
matrizes, e até na computação quântica (algoritmo de Shor).
Assim, baseando na sua definição formal, existem várias
maneiras de calcular o MDC; vamos descrever duas,
considerando os números 36 e 90.
1 - Através dos divisores dos dois números, na seguinte
sequência:
Passo 1 - Leia o primeiro número (36)
Passo 2 - Leia o segundo número (90)
Passo 3 - Mostre divisores de 36 (1, 2, 3, 4, 6, 9, 12,18 36)
Passo 4 -Mostre divisores de 90(1,2,3,5,6,9,10,15,18,30,45 90)
Passo 5 - Verifique qual o maior divisor comum a 36 e 90 (18)
Passo 6 - Mostre o MDC
2 - Através do “Algoritmo De Euclides” [4]
Passo 1 - Leia o primeiro número
Passo 2 - Leia o segundo número
Passo 3 - Divida o maior número pelo menor
Passo 4 - Se(resto da divisão for 0) Então MDC é o menor;
Vá para o Passo 12, Senão: Siga em frente
Passo 5 - Divida o dividendo pelo resto
Passo 6 - Se(resto da divisão for 0) Então Vá para o Passo 11
Senão: Siga em frente
Passo 7 - Considere o resto como o novo dividendo
Passo 8 - Considere o divisor como o resto anterior
24
Passo 9 - Divida o dividendo pelo divisor do resto anterior
Passo 10 - Volte ao Passo 4
Passo 11 - Considere o penúltimo resto como o MDC
Passo 12 - Mostre o MDC
Então, para o caso de calcular o MDC(90,36) o esquema
abaixo mostra como seria a aplicação do “Algoritmo de
Euclides”
90 36
resto 18
Em seguida o resto 18 é transportado para o lado direito
de 36 e divide-se o 36 por 18, posicionando o novo resto
(0) abaixo do 18:
90 36 18
Resto 18 0
Repete-se este procedimento até encontrar o resto 0
(zero); o penúltimo resto obtido (anterior ao primeiro
resto 0) é o MDC dos dois números dados.
Baseado na segunda forma de calcular o MDC, através no
“Algoritmo de Euclides” descrito acima, a solução do Exemplo
1.5 é dada pelo pseudocódigo a seguir, e a codificação poderia ser
feita em qualquer das inúmeras linguagens e/ou ambientes de
programação, mas, a base SEMPRE é o algoritmo/pseudocódigo
que, realmente, é a solução do problema.
25
Programa "CalculaMDC"
//Calcula o MDC de dois números:“Algoritmo de Euclides”.
//Em Pseudocódigo.
//Autor: Mário Leite.
//----------------------------------------------------
Declare Num1, Num2, N1, N2, Aux, MDC: inteiro
Início
{Inicializações convenientes para entrar no loop de
Num1 -1
Num2 -1
Enquanto ((Num1<=0) ou (Num2<=0)) Faça
Escreva("Entre com o primeiro número: ")
Leia(Num1)
Escreva ("Entre com o segundo número: ")
Leia(Num2)
FimEnquanto //fim do loop de leitura dos números
EscrevaLn("") //salta uma linha
N1 Num1
N2 Num2
{Calcula o MDC com o "Algoritmo de Euclides"}
FimEnquanto (N2<>0) Faça
Aux N1
N1 N2
N2 (Resto(Aux/N2)
FimEnquanto //fim do loop de cálculo do MDC
MDC N1
EscrevaLn("MDC(",Num1,",",Num2,")"," = ", MDC)
FimPrograma
A implementação (codificação) do problema “Calcular o MDC
de dois números” pode ser feita em várias linguagens de
programação: compiladas ou interpretadas, mas seguindo uma
lógica de programação para alcançar esse objetivo, baseada num
único algoritmo/pseudocódigo. E, embora fossem considerados
dois números bem determinados (90 e 36), poderia, também,
26
solicitar as entradas para quaisquer dois números inteiros. Mas, o
importante é frisar que, em princípio, não importa em qual
linguagem de programação o programa será codificado: o MAIS
IMPORTANTE é saber qual algoritmo a ser seguido para obter o
resultado esperado.
1.9 - Exercícios Propostos
1 - Explique, com suas próprias palavras, o que é “Lógica de
Programação”.
2 - Por que não se deve partir direto para a codificação de um
programa sem, antes, criar o algoritmo/pseudocódigo.
3 - Qual é a vantagem de se declarar um endereço de memória
RAM como constante, em vez de variável? Dê um exemplo.
4 - Qual é a vantagem de fazer o pseudocódigo depois do
algoritmo de um programa?.
5 - Explique por que o conceito de variável é fundamental na
programação,
6 - Se você tivesse que nomear uma variável para armazenar o
nome do Campeonato Mundial de Futebol da FIFA para 2024,
qual dos identificadores é o mais apropriado?
A ( ) CampeonatoMundialDeFutebol2024
B ( ) CampeonatoMundialFIFA2024
C ( ) FIFA2024
D ( ) FutebolFIFA2024
E ( ) CampeonatoFIFA2024
7 - Explique, com um exemplo, a diferença entre Algoritmo e
Pseudocódigo.
27
8 - De acordo com as teorias de Mark A. Changizi[7], se os
vulcanianos - planeta natal do Dr. Spock - tiverem três dedos em
cada mão (tal como a criaturinha do filme ET - O Extraterrestre),
então, provavelmente, o sistema de numeração deles seria o da
base hexa (base 6). Considerando essa teoria, marque nas
alternativas abaixo, a que aparece um número (representado na
Base Decimal) que jamais poderia ser escrito na Base Vulcaniana,
considerando que a Matemática vale para todo o Universo.
Explique, o porquê da sua resposta.
A ( ) 31234
B ( ) 4356
C ( ) 234100
D ( ) -1
E ( ) 0
9 - Sabemos que para realizar uma tarefa é necessário executar
alguns passos (poucos ou muitos, dependendo da solução
adotada). Suponha que um cliente deseja que você resolva um
problema para ele, através de um programa; e, considerando o
esquema abaixo, qual dos três caminhos você escolheria para
solucionar esse problema?
A ( ) O caminho de cima.
B ( ) O caminho do meio.
C ( ) O caminho de baixo.
D ( ) Aquele que produzisse uma solução mais eficaz.
E ( ) Qualquer um serviria.
28
10 - Explique porque a instrução X = X + 1 escrita na linguagem
C, por exemplo, não pode ser interpretada como uma equação
matemática.
11 - Crie um algoritmo para verificar se um determinando número
é primo, ou não.
29
Capítulo 2 - O Visualg
2.1 - Introdução ao Capítulo
O Visualg é um ambiente de software onde é possível editar,
interpretar e executar um programa de computador escrito em
pseudocódigo, numa linguagem bem próxima ao Português. Foi
desenvolvida originalmente pelo professor Cláudio Morgado de
Souza[8] até a versão 2.5, e atualmente gerido pelo professor
Antonio Carlos Nicolodi[9] a partir da versão 3.0 com novo layout
e novos recursos. É um dos mais populares interpretadores de
algoritmos, e que não depende de bibliotecas sofisticadas como
DLLs, OCX ou de componentes pré-fabricados. Roda na
plataforma Windows®95 e posteriores, e pode ser baixado
livremente em sites disponíveis na Internet sem quaisquer custos
adicionais. Este capítulo mostra os recursos e a sintaxe da
pseudolinguagemutilizada por esta ferramenta, com esquemas e
exemplos bem esclarecedores.
2.2 - Básico sobre Aprendizagem em Programação
No mundo
informatizado de hoje, com as comunicações feitas através de bits
e bytes, estamos cheios de novas TIC´s (Tecnologia em
Informática e Comunicação), como os notebooks, tablets,
smartphones, e até os bons e velhos desktops. As pessoas vivem
falando que “baixaram” um aplicativo para isto ou para aquilo.
Mas, para criar esses aplicativos é preciso utilizar alguma
linguagem de programação para resolver o problema do usuário,
através do desenvolvimento de códigos-fonte, e depois
http://pt.wikipedia.org/wiki/Software
http://pt.wikipedia.org/wiki/Portugu%C3%AAs_estruturado
30
transformá-los em programas práticos; caso contrário a
comunicação não vai existir, e o problema não será corretamente
resolvido, como desejaria o usuário.
De uma forma geral, a criação do código-fonte de um programa
para resolver um problema, abrange várias fazes (o que não será
mostrado aqui, por fugir ao escopo deste livro); e, dependendo do
ambiente de desenvolvimento, isto pode não ser trivial.
Entretanto, de um modo geral, para criar converter um algoritmo
em código-fonte, o programador precisa conhecer uma linguagem
de programação e, principalmente, ter uma base bem sólida de
lógica de programação. E para conseguir isto, o programador
necessita ter uma boa formação acadêmica, podendo ser
adquirida em cursos de informática voltados para a área de
programação de computadores. Nesses cursos os programadores
aprendem (ou. pelo menos deveriam aprender) lógica de
programação; como definir a sequência lógica do programa e
implementar a solução. Não raramente, os iniciantes encontram
muitas dificuldades em aprender a “lógica de programação”, por
precisar intrinsecamente de uma certa dose de “intuição”,
integrado a um processo cognitivo de aprendizagem. Por isto,
muitos acabam desanimando e desistindo; tanto em cursos de
computação quanto em engenharias nos seus primeiros ciclos; e
um dos motivos é que eles precisam montar os algoritmos com a
lógica, antes de aprenderem como eles funcionam. Muitos
professores, para ajudá-los no início do curso, adotam suas
técnicas de ensino com alguns métodos, tais como: algoritmos
descritivos, diagramas de blocos (que alguns chamam de
fluxogramas) e as pseudolinguagem de programação como o
português estruturado, também conhecido popularmente como
portugol; utilizando essas técnicas, o aprendizagem é bastante
facilitado no início de um curso nas áreas de Ciências Extas e/ou
Engenharias.
31
2.3 - Histórico do Visualg
De 1980 a 1983, os professores Antonio Carlos Nicolodi e
Antônio Manso - este da Universidade de Coimbra (Portugal) -
criaram uma pseudolinguagem baseada no estilo portugol. O
projeto foi formulado e montado para ajudar os alunos de “Lógica
de Programação” pois,eles tinham que usar a linguagem de
programação Pascal como ferramenta básica; mas, assim como
todas as linguagens de programação, o Pascal tem toda a sua
sintaxe escrita em inglês, o que causava alguns transtornos e
muita desistência dos alunos iniciantes nessa disciplina. E, como
titular desta disciplina, em instituição de ensino, no Brasil, o
professor Antonio Carlos Nicolodi sentia o problema de perto; os
alunos estavam com muita dificuldade, nessa tal “Lógica de
Programação”, já que eram usados métodos antigos e ainda muito
americanizados, com linguagens de programação real, em Inglês;
isto era um problema sério para o aprendizado. Então, em meados
de 1985 foi adotado este novo método: o Português Estruturado
(portugol) conforme está compilado na Wikipédia, no link
https://pt.wikipedia.org/wiki/Portugol (em 13/03/2020 - 15:58).
O portugol foi baseado na semântica de numa família de
linguagens de programação de computadores (1960/1970)
chamada Algol (do inglês Algorithmic Language - Linguagem de
Algoritmos), considerada a “mãe de várias outras linguagens”,
pois é baseada em uma estrutura modular que trabalha com blocos
estruturados de comandos. Sua sintaxe foi adotada para os
microcomputadores na linguagem de programação Pascal, e que
era muito difundida em todas as universidades do Brasil naquela
época, por ser bem mais simples que o Cobol. Entretanto, assim
como o Algol, o Cobol era destinado para trabalhar em máquinas
de grande porte chamados de mainframes, e a lógica de
programação daquela época usava como ferramenta principal o
https://pt.wikipedia.org/wiki/Portugol
32
fluxograma (na verdade, diagrama de blocos). Por isto, foi
adotada a estrutura simples do Algol, mas com as características
do Pascal, já adaptada para micros (como o famoso Turbo
Pascal); daí nasceu o portugol, que foi extremamente difundido
no Brasil e nos vários países de língua Portuguesa. Deste modo,
para criar a solução lógica dos problemas, os alunos ainda tinham
que montar os seus algoritmos em portugol, usando os seus
cadernos e testá-los, antes de traduzir para a linguagem Pascal,
compilá-los e, então, testá-los para conferir se estavam corretos.
E esses testes eram feitos através do famoso e trabalhoso “Teste
de Mesa”, onde escreviam no seu próprio caderno, montando uma
tabela com os nomes de todas as variáveis, e a cada passo do
algoritmo alteravam os seus conteúdos, usando como ferramenta
informações “mentais” em situações imaginárias. Isso era muito
tedioso e não muito eficiente; mas tinha que ser usado para
verificar se o algoritmo estava correto e sem erros de lógica. E
depois de tudo isto, quando não já houvesse mais nenhum erro,
então o aluno iniciante deveria transcrever as linhas do algoritmo,
escritos em portugol, para uma linguagem de programação (como
Pascal ou C), usando um editor de textos para, então, codificar o
programa, executar e ver os resultados na tela do computador. E
caso fosse detectado algum erro, deveria refazer tudo de novo,
reiniciando o ciclo torturante da programação. Observe a figura
2.1 que mostra um exemplo de “teste de mesa” criado para
depurar o programa “Trocas”, que lê dois números, A e B, faz a
troca entre eles e os exibe com seus valores trocados. O
pseudocódigo é mostrado a seguir...
33
Programa Trocas
//Faz trocas entre dois números
Declare A, B, X: inteiro
Início
Escreva("Digite o primeiro número A: ")
Leia(A)
Escreva("Digite o segundo número B: ")
Leia(B)
X A
A B
B X
EscrevaLn("") //salta linha
EscrevaLn("Valor final de A: ", A)
EscrevaLn("Valor final de B: ", B)
FimPrograma
Sequência A B X
1 3 4 -
2 3 4 3
3 4 4 3
4 4 3 3
Figura 2.1 - Teste de mesa do programa “Trocas”
34
O teste de mesa para testar/depurar o programa “Trocas” é muito
simples e fácil de criar; entretanto, para programas mais
complexos, esse processo de teste pode ficar inviável e muito
complexo. Assim, era preciso uma ferramenta que agilizasse o
ciclo de criação/teste/depuração do programa, voltado para os
programadores iniciantes.
2.4 - O Visualg no auxílio à Programação
O Visualg (acrônimo de Visual Algoritmo - Visualizador de
algoritmos) é um software que permite criar, depurar e interpretar
os algoritmos; o que o torna uma ferramenta muito poderosa para
os alunos iniciantes (e mesmo profissionais), pois os
programadores podem escrever diretamente nele os seus
algoritmos em portugol, sem precisar utilizar fluxogramas ou
fazer testes de mesa. E com é uma pseudolinguagem de
programação perfeitamente identificada com o portugol, o
programador se sente muito confortável para testar as soluções
algoritmizadas. O programador, iniciante ou não, pode escrever e
testar seus algoritmos com todos os recursos de um bom editor de
textos (sem formatação), mas, com recursos mais avançados,
além de comandos e funçõesbilt in eficientes. Também permite
testar o algoritmo e acompanhar a execução passo a passo;
observando as instruções, os comandos e os conteúdos das
variáveis a cada linha do algoritmo. Isto faz com que o
programador entenda melhor a lógica da solução e consiga
detectar anomalias e/ou possíveis erros na lógica da programação,
podendo corrigi-los de forma rápida, simples e eficiente. A
ferramenta possui várias janelas e caixas de diálogos explicando
suas funcionalidades; e também possui uma autoexplicação de
cada área na “barra de status”, na parte inferior da janela
principal. Além disto, os usuários podem exportar todo o
algoritmo de qualquer tamanho para um arquivo-texto já
transformado na sintaxe da linguagem de programação Pascal,
35
cujo “Nome do arquivo.extensão” já é sugerido através de uma
caixa de diálogo padrão no ambiente Windows®; pronto, rápido e
sem nenhum esforço. O Visualg, em sua versão mais recente,
possui algumas funcionalidades novas, novos comandos, e novas
funções, permitindo a seus usuários escreverem os seus códigos,
tanto em portugol padrão sem acentos e cedilha escritos em
minúsculos, quanto com acentos e cedilha, só que em escritos em
MAIÚSCULAS. Além disto, permite a todos os usuários
personalizar quase totalmente o software e os algoritmos de
maneira mais funcional, especificando informações sobre o nome
da disciplina, nome do professor, nome do curso, nome da
unidade do curso, etc; sempre evoluindo para ser mais intuitivo e
melhor.
2.4.1 - A Tela Principal do Visualg
Ao carregar a ferramenta o que se apresenta é uma tela como a da
figura 2.2a, que mostra o IDE (Integrated Development
Environment - ambiente de desenvolvimento integrado) - tela
principal do Visualg (versão 3.0x); mostrando um template com
alguns termos iniciais indicativos. As futuras versões poderão ter
algumas diferenças em relação a esta, porém muito sutis, pois o
objetivo da ferramenta é se apresentar, de maneira bem intuitiva
e bem interativa com o programador. É nessa tela (janela
principal da ferramenta) onde se define o principal ambiente de
trabalho do programador; é onde o algoritmo deve ser escrito para
que o programa possa ser interpretado e executado, de modo a
solucionar o problema proposto pelo usuário.
Por outro lado, é importante frisar que o algoritmo deve ser tal
que apresente a solução que traga eficiência e mais eficácia
possível, interagindo bem com o usuário, e apresentando uma
solução mais geral, quando for o caso. Por exemplo: se o
problema for “calcular a soma dos dez primeiros números
naturais”, o programador deve tentar fazer com que a solução
36
seja a mais geral; por exemplo, “calcular a soma dos n primeiros
números naturais”, deixando para o usuário escolher quantos
números (valor de n) ele quer que sejam somados, e não apenas
dez. Isto é, deve apresentar uma solução mais geral possível,
reaproveitável e, consequentemente, mais profissional.
Figura 2.2a - Janela principal do Visualg
A figura 2.2b mostra o programa “Trocas” no ambiente do
Visualg, exibindo no editor da ferramenta o seu código-fonte na
janela principal, na sua área de definição personalizada.
37
Figura 2.2b - Exemplo de código-fonte do programa no editor do Visualg
2.4.2 - Características Básicas da Ferramenta
A área total de edição de um programa em Visualg pode ser
subdividida, didaticamente, em três, conforme mostra o esquema
do quadro 2.1.
38
1ª) Área de identificação e documentação do programa
algoritmo "Nome_do_programa"
// Disciplina : [nome do projeto/disciplina]
// Professor(a): [Nome do professor da disciplina, se for o caso]
// Descrição: Descrição do que o programa faz (objetivo)
// Autor(a): Nome do autor (ou aluno se for o caso)
// Data atual: Data do sistema
2ª) Área de declarações globais
Arquivo
Const
Tipo
Var
3ª) Área dos comandos/instruções
Inicio //início do programa principal
Aqui são digitadas as instruções em pseudocódigo.
fimalgoritmo //fim do programa principal
Quadro 2.1 - As áreas de desenvolvimento do Visualg
As configurações básicas dos elementos de um programa seguem
padrões preestabelecidos pela ferramenta.
As palavras-chave (termos reservados) aparecem, originalmente,
na cor azul (sublinhadas); as strings (textos entre aspas) na cor
vermelha, valores numéricos na cor preta, valores lógicos
(verdadeiro e Faso) na cor vermelha, os tipos de dados na cor
marrom e sublinhados e as variáveis na cor preta normal. Isto
facilita muito a edição de um programa, além de ajudar na
depuração de erros. Mas, embora as fontes desses elementos
39
possam ser alteradas no menu Manutenção/Configurações,
sugere-se que sejam mantidas como determina os padrões.
Nota 1: Obviamente, por não ser colorido, aqui neste livro os elementos
“coloridos” aparecerão com a cor meio “acinzentada” para indicar esta
singularidade, em contraste com o texto normal.
Nota 2: Cada linha de código deve ser escrita integralmente numa única
linha do editor; uma linha de instrução não pode ocupar mais de uma
linha de texto.
Nota 3: Na seção de declarações os termos “Arquivo”, “Const” e
“Tipo” (para acessar arquivo, criar constantes e registros,
respectivamente), não aparecem de imediato; devem ser colocadas de
acordo com as necessidades do programa, e NESTA ORDEM.
2.5 - Pseudocódigo x Visualg
O capítulo anterior mostrou que para solucionar um problema
através de um programa de computador, é necessário criar o
algoritmo que implementa a solução, e em seguida formalizar
mais tecnicamente esse algoritmo através do chamado
“pseudocódigo”. As linhas de um programa em pseudocódigo
traduzem os passos do algoritmo de uma forma mais técnica e
mais rigorosa; e para isto são empregados termos que permitem
compactar as ordens descridas informalmente no algoritmo.
Assim, são empregados termos mais próximos de uma linguagem
real; por exemplo, Leia(A) em vez de “Pegue o primeiro
número” como é escrito no algoritmo; esta reescrita faz com que
o futuro código-fonte fique mais fácil de ser implementado.
Embora a escrita em pseudocódigo possa ser em Português livre,
para que possa ser colocado dentro do editor do Visualg é preciso
que ele sofra pequenas adaptações para o portugol dessa
40
ferramenta. Por exemplo, Faça passa a ser Faca (sem a cedilha),
assim como Então que deve ser escrito como Entao (sem o til).
Além destes termos em Português, outros comandos sofreram
algumas alterações aqui neste livro como, por exemplo, a
estrutura Selecione..FimSelecione que no Visualg deve ser
Escolha..FimEscolha. A tabela 2.1 abaixo mostra comparações
entre alguns termos utilizados no pseudocódigo e seu
correspondente em Visualg, o que revela uma semelhança total
entre eles. Isto significa que o pseudocódigo do programa pode
ser, efetivamente, já escrito como o Visualg o reconhece;
entretanto, como o pseudocódigo é uma maneira livre de
formalizar o algoritmo, assim, ele pode ser escrito em livre
Português, como é feito aqui neste livro.
Pseudocódigo Visualg O que faz/Onde utilizar
Então Entao Em estruturas de decisão.
Senão Senao Em estruturas de decisão.
Selecione Escolha No início de uma estrutura de
seleção.
FimSelecione FimEscolha No final de uma estrutura de
seleção.
CasoContrário OutroCaso Alternativa default em estrutura
de seleção.
Faça Faca Em estruturas de repetição
lógica com teste no início.
Até Ate Em estrutura de repetição
numérica.
AtéQue Ate Em estruturas de repetição
lógica com teste no final.
Abandone Interrompa Comando para sair
incondicionalmente de um loop.
Tamanho() Compr() Função que retorna tamanho de
uma strings.
41
CaracNum() CaracpNum() Função que converte caractere
em número.NumCarac() NumpCarac() Função que converte número em
caractere.
Posição() Pos() Função que dá a posição de um
caractere numa string.
Tabela 2.1 - Portugol do Pseudocódigo versus portugol do Visualg
Nota: Embora possa ser escrito exatamente conforme exige a sintaxe
do Visualg, aqui neste livro optamos por escrever o pseudocódigo em
Português livre, além de alterar alguns termos para ficarem melhor
explicados para o leitor, como por exemplo, na estrutura
Selecione..FimSelecione em vez de já escrever Escolha..FimEscolha.
Outra alteração, mesmo sendo bem sutil, é o caso da função que
converte caractere um número: CaracNum (eliminando p) em vez de
diretamente CaracpNum, como exige o Visualg, assim como na
função Tamanho (que dá a quantidade de caracteres de uma string) em
vez de Compr no Visualg. Estas alterações foram feitas apenas para
que o pseudocódigo pudesse expressar melhor, em Português, as linhas
de código do programa.
42
ATENÇÃO: Em temos de escrita do código de um programa no
ambiente de desenvolvimento do Visualg o padrão da ferramenta é
apresentar as palavras-chave em letras minúsculas, tal como se
apresentam na linguagem C. Entretanto, apenas para dar um melhor
significado a todas as palavras reservadas e/ou comandos e funções,
aqui neste livro optamos pelos estilo “camel”, para enfatizar esses
termos. Por exemplo, a palavra-chave que aparece em todos os
programas em Visualg é algoritmo, assim como fimalgoritmo; em
letras minúsculas. Aqui neste livro adotamos um estilo em que TODAS
as palavras-chave devam aparecer SEMPRE com a primeira letra em
maiúscula, e depois com uma combinação de maiúsculas e/ou
minúsculas. Deste modo, ficará Algoritmo e FimAlgortimo para
indicar início do programa e fim do programa, respectivamente. No
caso de FimAlgoritmo para enfatizar a ação “Fim do Algoritmo”,
fazendo com que o comando tenha mais “força” ao ser lido pelo
programador, assim como LimpaTela, FimSe, FimEnquanto, etc.
Embora o Visualg não seja “case sensitive” (o programador pode
escrever os comandos e funções sem se importar com maiúscula ou
minúsculas), aqui neste livro é adotado este estilo que reflete mais as
ações, como por exemplo: FimEscolha em vez de fimescolha pois,
como pode ser notado, a primeira alternativa reflete bem mais a ação
do que a segunda, indicando “Fim da Escolha”! E também para
comandos e funções simples: Div, em vez de div, Mod em vez de mod,
Copia em vez de copia, CaracpNum em vez de caracpnum, Int em
vez de int, Abs em vez de abs, Escreva em vez de escreva, Leia em
vez de leia, etc.
43
2.6 - Funcionalidades Práticas do Visualg
O programador pode escrever e testar seus algoritmos com todos
os recursos de um bom editor de textos no padrão Windows®, mas
com recursos mais avançados, além de novos comandos e funções
melhores. E depois, ainda pode testar e acompanhar passo a passo
a execução do algoritmo, além das instruções e conteúdo das
variáveis a cada linha do programa, para entender melhor e
detectar anomalias e/ou erros; e, se necessário, corrigir e
modificá-los de forma rápida, simples e eficiente. Esta é uma das
vantagens do Visualg, como ferramenta de auxílio ao
aprendizado de programação, dispensando recurso antigos de
depuração do futuro código-fonte, ainda na fase de criação do
programa. A barra de Status (figura 2.3) é um desses recursos
extras na edição/testes dos programas.
Figura 2.3 - Barra de status do Visualg
Depois de editar o programa, e caso queira, o usuário poderá
exportar todo o algoritmo de qualquer tamanho para um arquivo-
texto já transformado na sintaxe da linguagem de programação
Pascal, E, além de uma nova aparência, na versão 3.0 foram
acrescentados novos comandos e novas funções, permitindo aos
seus usuários escreverem seus algoritmos, tanto na versão antiga
(em minúsculo, sem a grafia portuguesa, para manter a
compatibilidade com os algoritmos escritos nas versões antigas)
quanto com todos os acentos e com o "Ç": SÓ QUE, NESTE
CASO, EM MAIÚSCULAS. Observe os exemplos comparativos
a seguir...
44
Versões 2.xx Versão 3x
j <- 1 j <- 1
Para k de 1 Ate 100 Faca Para k De 1 ATÉ 100 FAÇA
j <- k + 1 j <- k + 1
Se(j Mod 2 = 0) Entao Se(j Mod 2 = 0) ENTÃO
Escreval(j) Escreval(j)
FimSe FimSe
FimPara FimPara
Nota: Apenas por uma questão de estilo, adotaremos neste livro a
escrita da versão 2.xx, como mostrado na tabela 2.1. Mas, o leitor pode
utilizar a sintaxe da versão 3.xx, sem problemas; é apenas uma questão
de gosto e estilo pessoal.
2.7 - Itens do Menu Principal
Figura 2.4 - Barra de Menus e Barra de Botões de atalho
2.7.1 - Opção “Arquivo”
Arquivo - Contém itens que permitem manipular os arquivos
com os algoritmos, como: Novo, Abrir, Salvar, Salvar Como,
Imprimir e Sair. A figura 2.5 mostra todos os itens desta opção.
45
Figura 2.5 - Itens da Opção “Arquivo”
Abaixo estão descritas as opções da janela da opção “Arquivo”.
• “Novo” permite ao usuário criar um novo programa,
apagando, “caso não salve”, o conteúdo que estava
anteriormente na área de programas. Também pode-se
usar as teclas de atalho Ctrl+N.
• “Abrir” permite ao usuário abrir um programa que foi
salvo ou criado anteriormente e carregá-lo para a área de
programas. Também pode-se usar as teclas de atalho
Ctrl+A.
• “Salvar” e “Salvar Como” permitem ao usuário salvar
um programa que ainda não foi salvo e chamar a caixa
dele para a área de programas. Também pode-se usar as
teclas de atalho Ctrl+S e Ctrl+Alt+C, respectivamente.
Sugere-se que o nome do programa seja salvo com o
46
mesmo nome do programa, embora isto não seja
obrigatório.
• “Imprimir” permite imprimir o programa em uma
impressora conectada ao microcomputador, e configurada
para o Windows®. Nesta opção também é mostrada uma
lista com os últimos cinco nomes e localização dos
arquivos usados pelo programa.
• “Sair” fecha e encerra a ferramenta, retornando ao
sistema operacional.
Figura 2.6a - Abrir um arquivo já salvo
47
Figura 2.6b - Salvando um arquivo que está no Editor
Quando o usuário for salvar um programa em um arquivo na
mídia, dentro do Windows®, o nome do arquivo já é
automaticamente sugerido como o nome do exercício que está
entre “aspas” no início do programa (depois da palavra-chave
Algoritmo), acrescentando a extensão .alg
48
2.7.2 - Opção “Editar”
Figura 2.7 - Salvando um arquivo que está no Editor
Esta opção da barra do “Menu Principal” permite ao usuário usar
recursos de um editor de texto, próprio da ferramenta; conforme
mostra a figura 2.7.
• “Desfazer” permite ao usuário desfazer o(s) último(s)
comando(s) ou serviço(s) efetuado(s). Pode-se usar as
teclas de atalho Ctrl+Z.
• “Refazer” permite voltar atrás e refazer o que o usuário
já tinha desfeito.
• “Recortar” permite ao usuário recortar uma parte do
programa. A alternativa é pressionar as teclas de atalho
Ctrl+X.
49
• “Copiar” permite ao usuário copiar uma parte do
programa para a memória temporária. As teclas de atalho
Ctrl+C podem ser usadas para o mesmo propósito.
• “Colar” permite ao usuário colar num local do programa,
o que havia sido copiado na memória temporária Podem
ser usadas as teclas de atalho Ctrl+V.
• “Indentação” permite ao usuário forçar a indentação; ou
seja, colocar todo o texto no formato hierárquico
tabulando de três em três caracteres a cada nível,
melhorando a estética do programa. A ação semelhante
pode ser conseguida com as teclas de atalho Ctrl+G.
• Selecionar Tudo, permite ao usuário selecionar todo o
texto do algoritmo. Podem ser usadas as teclas de atalho
Ctrl+T.
• “Localizar...” permiteao usuário procurar e/ou localizar
palavras ou parte de um texto, dentro do programa inteiro.
Alternativamente, podem ser usadas as teclas de atalho
Ctrl+L.
• “Localizar o Próximo” permite ao usuário procurar e/ou
localizar a próxima palavras ou parte de um texto, já
encontrada dentro do programa inteiro. Pode-se usar a
tecla de atalho F3.
• ”Localizar a Anterior” permite ao usuário procurar e/ou
localizar a palavra anterior da parte de um texto, já
encontrada no programa inteiro. A tecla de função F4
produzirá o mesmo efeito de for pressionada.
• “Substituir...” permite ao usuário substituir a(s)
palavra(s) já encontrada(s) por outra(s) dentro do
programa inteiro. Pressionando as teclas de atalho Ctrl+U
o efeito será o mesmo.
50
• “Gravar Bloco...” permite ao usuário gravar parte do
texto dentro de um arquivo temporário do programa.
Pressionando as teclas de atalho Ctrl+W o mesmo efeito
será produzido.
• “Inserir Bloco...” permite ao usuário inserir dentro do
programa um arquivo temporário após a última linha do
algoritmo. Antes de FimAlgoritmo. Pode-se usar as
teclas de atalho Ctrl+R para que isto seja conseguido.
Na figura 2.8 - submenu de “Localizar” - mostra uma caixa de
diálogo onde o usuário pode digitar a palavra a ser pesquisada em
“Procurar por:” e filtrar pelas opções que podem ser marcadas
em pela “Direção” da pesquisa “para Frente” ou ”para Trás”
Figura 2.8 - Pesquisa de texto no programa
Ainda, na figura 2.8, em “Opções”, o usuário poderá fazer a
pesquisa da palavra de várias maneiras quanto à sua grafia.
51
2.7.3 - Opção “Run”
Esta opção da barra do “Menu Principal” permite executar (rodar)
os algoritmos; como mostra a figura 2.9a.
Figura 2.9a - Opção do submenu Run
• “Rodar o Algoritmo” roda diretamente o programa, e
pode-se analisar a lógica do programa. A tecla de função
F9 é a alternativa para essa ação.
• “Rodar Passo a Passo” executa o programa linha por
linha, onde cada linha será executada se o usuário clicar
nesta opção do menu ou apertar tecla de atalho F8.
• “Rodar com Tempo” o usuário define um intervalo de
tempo que o programa esperará para executar a linha; esse
tempo é definido por uma caixa de opções conforme
exibida (vide figura 2.9b), Pode-se usar as teclas de
atalho Shif+F9.
• “Parar” (Stop) permite ao usuário parar a execução do
algoritmo manualmente, antes do seu termino. As teclas
de atalho Ctrl+F2 pode ser usadas como alternativa.
52
• “Liga/Desliga breakpoint” permite ao usuário colocar
pontos de paradas dentro do programa, para fins de testes.
A tecla de função F5 pode ser usada como alternativa.
• “Desmarcar todas” (os breakpoints) permite ao usuário
desmarcar todas as marcas de breakpoints. Pode-se usar
as teclas de atalho Ctrl+F5.
• “Executar em modo DOS” (opção temporariamente
desativada n versão 3x).
• “Linhas (Ativa/Desativa)” permite ao usuário ativar ou
desativar a numeração das linhas que aparecem na lateral
esquerda do programa.
• “Gerar valores Aleatórios” permite ao usuário gerar
números aleatórios quando o programa precisar.
• “Perfil” permite ao usuário criar um perfil dentro do
programa. Pode-se usar a tecla de atalho F7.
• “Pilha de ativação” permite ao usuário criar uma pilha
de ativação dentro do programa. Pode-se usar as teclas de
atalho Ctrl+F3 como alternativa a essa opção.
Figura 2.9b - Intervalo de tempo na opção “Rodar com Tempo”
53
2.7.4 - Opção “Exportar”
Esta opção da barra do” Menu Principal” permite ao usuário
exportar o programa, já convertendo-o em uma linguagem de
programação, Pascal ou C/C++ e Java (ainda em
desenvolvimento) como mostra a figura 2.10.
Figura 2.10 - Exportando o programa em Visualg para uma Linguagem
Na opção para exportar “a Linguagem de programação Pascal”, o
Visualg já transforma as linhas do português estruturado do
algoritmo para os comandos da linguagem evitando assim, que o
usuário tenha que reescrever todo o código-fonte, com exceção
de alguns comandos e algumas funções que existem na
ferramenta, mas não existem na linguagem Pascal.
2.7.5 - Opção “Manutenção”
Nesta opção o usuário encontra os recursos para alterar: cor de
fontes, aparência, dados dos usuários e dos lugares onde são
usados. A figura 2.11a mostra os itens desta opção.
Figura 2.11a
54
• “Configurações” permite ao usuário alterar o ambiente
do Visualg através de três abas como são mostradas na
figura 2.11b.
Figura 2.11b - Opções de configuração da ferramenta
▪ Na aba Editor o usuário pode alterar as configurações
primárias que irão afetar toda a aparência do código, em
tempo de codificação do programa:
✓ Largura da Tabulação: número de colunas que a
indentação irá considerar.
✓ [x] Usar a tabulação inteligente.
✓ Fonte: alterar o tipo do fonte (Courier New é o default)
padrão do Windows®..
✓ Tamanho da fonte “11” é o default.
55
✓ Elementos: este item troca as cores dos elementos do
texto do programa conforme é apresentado em exemplos:
Comentários
Constantes
Fundo do Editor
Palavras-Chave
Palavras especiais
Tipos de dados
Texto em Geral
✓ Atributos: podem ser alterados a cor e o estilo de cada
um dos elementos, em:
Negrito
Itálico
Sublinhado
E como resultado, cada um desses elementos pode ser
visualizado na caixa de comentários chamada “Exemplo” na
janela a direita e abaixo.
▪ A aba Listas mostra algumas listas que podem ser
cadastradas dentro do Visualg para ajudar os usuários,
como é mostrado na figura 2.11c. Nesta aba os usuários
podem criar listas padrões para uso dentro dos algoritmos
e usá-los quando necessário como, por exemplo:
• MESES de um ano (Janeiro, Fevereiro, Março, ...)
• DIAS da semana (Segunda-feira, Terça-feira, ...)
• ESTADOS do Brasil (Minas Gerais, Santa Catarina,
Rio de Janeiro, Bahia Paraná, ...)
• TIMES de futebol (Flamengo, Vasco, São Paulo,...))
• CIDADES de um estado (Tombos, Florianópolis,
Gaspar, Maringá, Campinas, etc)
56
Figura 2.11c - Opções de configuração de Ambiente
✓ O botão [Nova...] permite ao usuário criar uma
nova lista.
✓ O botão [Excluir..] permite ao usuário excluir
(apagar) uma lista já criada.
✓ A aba Personalizar permite ao usuário fazer alterações
nas informações para tornar o Visualg personalizado,
além de poder modificar as caixas de edição, conforme
indica a figura 2.11d. Essas alterações personalizam o
programa que está sendo editado, tais como:
✓ Entidade
57
✓ Disciplina
✓ Professor
✓ Turma Especial
✓ Endereço
Figura 2.11d - Opções de alterações na identificação do programa
As alterações poderão ser feitas pelo usuário em função da
importância do programa que está sendo criado, mas, isto não é
obrigatório; a não ser no caso em que a ferramenta esteja sendo
usada para fins didáticos e/ou em aula expositiva para alunos
iniciantes na ferramenta.
“Calculadora” oferece uma calculadora básica, parecida com
a das versões antigas do Windows®, mas com uma
configuração própria sendo possível copiar os dados para a
área de memória temporária e colar quando voltar ao texto do
algoritmo; veja na figura 2.11e.
58
Figura 2.11e - A Calculador do Visualg
“Calendário” oferece um calendário anual, como mostrado
na figura 2.11f.
Figura 2.11f - O Calendário do Visualg
59
2.7.6 - Opção “Help”
A opção Help (Ajuda) da barra do “Menu Principal” permite ao
usuário, consultar um manual dentro do próprio Visualg, pois em
cada janela há um conjunto de telas para ajudar os usuários. A
figura 2.12a mostra os itens das opções do submenu.
Figura 2.12a - Itens da Opção Help do Visualg
“Tela do Visualg” permite ao usuário abrir um
gerenciador do manual completo no formato HTML ou
arquivos CHM[10]em tela cheia de dentro do próprio
Visualg, contendo todas as informações importantes do
software, como mostra a figura 2.12b.
Figura 2.12b - A Tela de Help do Visualg para um manual da ferramenta
60
E como pode ser notado, o gerenciador HTML de Help possui
uma barra de botões, e seu conteúdo dividido em duas áreas;
sendo que a área da esquerda tem duas abas que contém
tópicos de pesquisas, onde o usuário pode alternar entre os
itens para sanar as dúvidas, como nas figuras 2.12c e 2.12d.
Figura 2.12c - Help em HTML
Ícones permitem ocultar as guias de pesquisas e imprimir o seu
conteúdo em uma impressora, Voltar, Avançar e Opções, e
também modificar o gerenciador de Help.
Figura 2.12d - Abas do Help
Na área das guias do “Help” a aba “Conteúdo” o usuário
pode escolher os tópicos de cada item cujo conteúdo
aparecerá na área da direita da janela.
61
Figura 2.12e - Pesquisa da palavra e mostra o conteúdo
“A Linguagem do Visualg” mostra aos usuários o
arquivo HTML diretamente com os comandos, funções,
operadores e outras informações da linguagem do Visualg
como mostra a figura 2.12f.
Figura 2.12f - O item: A Linguagem do Visualg
62
“Referência da Linguagem do Visualg” oferece ao
usuário uma coleção de todas as palavras-chaves da
Linguagem do Visualg como mostra a figura 2.12g.
Figura 2.12g – Referências, palavras chaves
63
“Sobre os autores do Software” mostra os autores do
Visualg; das versões que deram origem a ele, como indica
a figura 2.12h; em destaque o professor Antonio Carlos
Nicolodi que modificou e que, atualmente, é o gestor da
ferramenta. O botão [Donativos] permite saber mais
informações sobre a ferramenta e como colaborar com seu
desenvolvimento. O botão [Voltar ao programa] permite
voltar á tela principal onde o programa atual editado.
Figura 2.12h - O gestor atual do Visualg
64
2.8 - Áreas Funcionais do Visualg
O IDE do Visualg se divide, funcionalmente, em cinco áreas
como visto na figura 2.13a
1. Área de Identificações gerais do programa.
2. Área de declarações globais.
3. Área de criação do programa.
4. Área das variáveis de memória.
5. Área de visualização dos resultados.
Área das Varáveis de Memória
Área de declarações globais
Área de identificações gerais do Programa
Área de criação do programa (entre Inicio e FimAlgoritmo)
Área de visualização dos resultados
Figura 2.13a - As áreas de desenvolvimento do Visualg
65
Embora sejam cinco as áreas funcionais do IDE do Visualg
(vistas na figura 2.13a), estas podem ser compactadas em apenas
três, básicas, conforme são descritas a seguir...
2.8.1 - Áreas do Programa (edição do código-fonte)
Esta é a área que mais se destaca no IDE do Visualg, pois é nela
onde a “magia” acontece; permite ao usuário criar, editar e
interpretar o algoritmo escrito em uma pseudolinguagem, já
definida como portugol, e utilizada em muitas literaturas sobre
programação; no Brasil e em vários outros países de língua
Portuguesa. Na verdade, é uma aproximação do portugol original,
mas com muito mais recursos, mais comandos e mais funções.
Nessa área o usuário tem algumas informações à sua disposição
para criar e editar os seus códigos. A figura 2.13b mostra a
aparência do formato inicial de um programa com as suas três
sessões e algumas informações extras.
• As linhas numeradas.
• O nome (temporário) do arquivo entre os colchetes sendo
“semnome” quando não tiver nenhum arquivo criado e
salvo com outro nome, ou em branco.
• A sessão do cabeçalho iniciando sempre com palavra
reservada Algoritmo e com nome do arquivo “semnome”
sempre entre aspas.
• Os comentários: opcionais, mas essenciais quando o aluno
é iniciante.
• A sessão onde são declaradas as variáveis de memórias,
com seus tipos.
• A sessão de Inicio do algoritmo: é aqui que as linhas de
instruções são iniciadas para montar o programa principal.
66
• A sessão de final do algoritmo (programa): onde é
colocado a palavra reservada FimAlgoritmo.
A figura 2.13b mostra um modelo de como é, inicialmente, a
“Área do Programa”.
Figura 2.13b - A “Área de Programa” do Visualg
2.8.2 - Área das Variáveis de Memória
É nesta área que o usuário (programador) pode ver, em tempo de
execução - quando o programa estiver rodando - o conteúdo das
variáveis de memória, criadas. Assim, pode-se averiguar se o
programa realmente está correto ou quando algum erro de lógica
acontece. Esta área dispensa o “teste de mesa” para apurar a
corretude do algoritmo, pois o próprio Visualg se encarrega disto
(vide figuras 2.13c e 2.13d)
67
Figura 2.13c - As colunas da “Área das Variáveis de Memória”
Esta área é dividida em quatro colunas, onde são mostrados:
▪ Escopo
▪ Nome
▪ Tipo
▪ Valor
A coluna Escopo mostra informações a respeito de onde se
origina uma variável; se ela é global ou local; se pode ser
visualizada tanto no programa (ou rotina principal) quanto pelas
UDFs (UDF (sigla em Inglês para User Define Function - função
ou procedimento definidos pelo usuário); assim a sua
visualização poderá ser:
• Global - Pode ser vista (enxergada, acessada, manipulada)
por todo o programa e por todas as UDFs existentes no
programa.
68
• Local - Só pode ser vista (enxergada, acessada,
manipulada) no módulo que à criou: como uma UDF (função
ou um procedimento).
A figura 2.13d, mostra um exemplo de acompanhamento dos
valores instantâneos de algumas variáveis.
Figura 2.13d - Acompanhamento do status de variáveis em execução
A coluna Nome contém o nome (identificador) da variável.
A coluna Tipo dá o tipo da variável.
• inteiro
• real
• caractere
• logico
A coluna Valor mostra o conteúdo da variável, naquele instante
do processamento.
69
❖ Exemplo 2.1 - Ler o salário bruto de um funcionário, o
percentual de desconto para a Previdência Social, e no final
mostrar:
• O salário bruto lido.
• O valor do desconto que incidiu sobre o salário bruto.
• O salário líquido recebido.
•
Algoritmo "ControleSalarial"
//Descrição: Controla os dados de salário de funcionário.
//Autor(a) : Antonio Carlos Nicolodi
//Data atual : 04/03/2020
//-------------------------------------------------------
Var SalBruto, SalLiq, PercDesc, Desc: real
Inicio
Escreva("Digite o salário bruto: ")
Leia(SalBruto)
Escreva("Digite o percentual de desconto: ")
Leia(PercDesc)
Desc <- (SalBruto*PercDesc)/100
SalLiq <- SalBruto - Desc
Escreval("")
Escreval("Salário Bruto lido: ",SalBruto)
Escreval("Desconto para INSS: ",Desc)
Escreval("Salário líquido: ",SalLiq)
FimAlgoritmo
Ao pressionar a tecla F9 será executado o algoritmo, e mostrar o
resultado na tela do console, como mostra a figura 2.14a.
70
Figura 2.14a - Saída do programa “ControleSalarial”
Agora que o algoritmo do programa “ControleSalarial” foi
testado e já constatada a sua corretude, deve-se fechar janela do
Console, pressionando a tecla Esc,
Se quiser converter o código em Pascal, basta clicar em
“Exportar Para” no menu principal e selecionar a opção
“Pascal”; isto provocará a abertura de uma janela tal como
mostrada na figura 2.14b.
71
Figura 2.14b - Gerador do código-fonte em Pascal a partir do Visualg
Nota: Dentro da janela da figura 2.10b aparecerá inicialmente a
seguinte informação:
“ATENÇÃO: Esta rotina ainda está em desenvolvimento. O código
gerado pode apresentar incorreções sintáticas”. Isto quer dizer que,
caso seja necessário, o Visualg poderá mostrar apenas comentários, em
vez de de comandos pois, existem muito mais comandos e/ou funções
na pseudolinguagemda ferramenta e que não existem na linguagem de
programação Pascal. O programa mostra como ficou o código escrito
nessa linguagem.
72
Após esta etapa o usuário então poderá salvar esse código, que já
está na linguagem Pascal, para um arquivo-texto com o nome
sugerido pelo Visualg, que é o próprio nome do programa, mas já
com a extensão “.pas”, para isto basta clicar no botão [Salvar] e
salvar novamente.
Nota: Nas versões mais antigas do Visualg era permitido criar
apenas 500 variáveis incluindo os elementos dos vetores e matrizes,
no total. Atualmente esse valor passou para 65535; são 64K bytes
de memória utilizados.
2.8.3 - Área de Visualização dos Resultados
Considerando o programa do Exemplo 2.1, observe o que
acontece, na figura 2.14c.
Figura 2.14c - Visualização variáveis do “ControleSalarial” em execução
73
A figura 2.14c mostra um exemplo de visualização das variáveis
na “Área das variáveis de memória”, do programa
"ControleSalarial", e a figura 2.14d, os resultados na “Área de
Visualização dos resultados”.
Figura 2.14d- Visualização dos resultados de “GeraValoresRelativisticos”
2.9 - Funcionalidades dos Botões da Barra de Ícones
O Visualg oferece ícones para ações na ferramenta, de maneira
rápida, substituindo as ações do Menu Principal.
A figura 2.15 mostra a “Barra de Ícones”, e logo em seguida a
descrição da funcionalidade de cada um deles.
Figura 2.15 - A Barra de Botões/Ícones do Visualg
A tabela 2.2 descreve as funcionalidades de cada elemento da
barra de ícones que fornece as tarefas disponíveis na ferramenta
como atalhos para as principais ações.
74
Ícone Atalho Funcionalidade
[Ctrl+N]
Cria um novo
"modelo" de
programa,
substituindo o
texto atual no
editor.
[Ctrl+A]
Abre um arquivo
de programa que
já salvo, e
substitui o texto
atual no editor. A
setinha mostra
arquivos já
salvos.
[Ctrl+S]
Salva o
programa atual
do editor; se for a
primeira vez a ser
salvo será pedido
o nome e o local
de gravação do
arquivo.
[F9]
Executa o
programa que
está atualmente
no editor de
texto. Roda o
programa
[F8]
Passo a passo -
Executa (roda) o
programa linha
por linha,
acompanhando o
fluxo do
programa, vendo
75
as variáveis, etc.
Permite depurar
o programa.
Timer - Executa
o programa com
tempo
predeterminado,
sem precisar
pressionar
qualquer tecla
para prosseguir.
[CtrF2]
Parar - Encerra
imediatamente a
execução do
programa em
execução. Fica
desabilitado
quando o
programa não
está sendo
executado.
[F5]
Liga/Desliga
Breakpoints -
Cria pontos de
parada em linhas
de instruções do
programa. Esta
ação não
funciona no
modo passo a
passo. Para
continuar deve
ser pressionada a
tecla [F9].
76
[CtrF5]
Marga/Desmarc
a Breakpoints
Marca/desmarca
pontos de parada
já criados.
Restaura a tela
inicial do
ambiente e
retorna à tela
original do
programa.
[Ctrl+X]
Recorta o texto
selecionado e o
move para o
Clipboard.
[Ctrl+C]
Copia o texto
selecionado na
memória no
Clipboard.
[Ctrl+V]
Cola o conteúdo
do Clipboard no
local do cursor.
Grava bloco -
Abre uma janela
para salvar o
bloco
selecionado; cria
uma biblioteca
de funções.
Insere um bloco
de códigos na
posição do
cursor.
[Ctrl+Z]
Desfaz a ação
criada no editor
de texto.
77
[Shift+Ctrl+
Z]
Refaz a ação que
havia sido
anteriormente
criada no editor.
[Ctrl+L]
Localiza uma
string no editor
de digitada numa
janelinha que se
abre.
[F3]
Localiza
próxima
ocorrência.
[F4]
Localiza a
ocorrência
anterior.
[Ctrl+U]
Abre janelinha
para digitar a
string que se
deseja localizar e
substituir no
editor de texto.
[Ctrl+G]
Corrige
automaticamente
a indentação do
programa e
coloca as
instruções dentro
de uma estrutura
de três colunas à
direita da coluna
inicial.
[Ctrl+P]
Imprime o
programa que
está no editor. Se
for preciso
configurar a
78
impressão use a
opção Imprimir.
[F7]
Perfil - Após a
execução de um
programa mostra
quantas vezes
cada linha foi
executada.
Gera alguns
números
aleatórios na
faixa selecionada
e
incrementada.sta
us
[Ctrl+F3]
Mostra a pilha
de ativação dos
procedimentos e
funções.
Mostra uma
calculadora.
Mostra um
calendário.
[F1]
Ativa Ajuda
(on-line)
Encerra o
Visualg e retorna
ao sistema
operacional.
Tabela 2.2 - Descrição das tarefas da “barra de ícones”
79
2.10 - A Barra de Status
A “Barra de Status” do Visualg (figura 2.16) também é uma
ótima fonte para que o usuário possa se informar sobre a situação
do algoritmo que está sendo criado/editado. A tabela 2.3 mostra
como ela se apresenta em situações “normais”, dividida em
quatro partes.
Figura 2.16 - A “Barra de Status” do Visualg
Parte Descrição
0000015:0043 Dá a posição do cursor (linha:coluna) na
edição do programa.
Status Mostra informações do status do programa,
como: modificado ou executando.
Use as setas... Mostra a mensagem FIXA: “Use as setas para
Movimentar-se ou Ctrl+j para ver a lista dos
comandos e funções.
Permite Criar,
Alterar
Esta parte mostra uma mensagem sensitiva.
Onde o ponteiro do mouse estiver, ele mostra
uma mensagem diferente.
Tabela 2.3 – Partes da barra de status do programa
2.11 - Palavras Reservadas
A linguagem de programação utilizada pelo Visualg é parecida
com o Português, estruturada no estilo portugol, e permite que
seja empregada em todas as situações em que haja necessidade de
resolver algum problema de maneira automatizada e baseado na
lógica. Este estilo segue as regras de codificação da linguagem
Pascal, justamente para que a aprendizagem seja a mais produtiva
possível. A codificação do programa é baseada na solução do
80
algoritmo editado, e deve levar em consideração que, mesmo não
sendo uma linguagem real de programação, também possui
“palavras reservadas” (palavras-chave). A figura 2.17 (obtida
pressionado as teclas Ctrl+J) mostra algumas dessas palavras
que não podem ser empregadas como identificadores.
Figura 2.17 - Palavras reservadas do Visualg obtidas com Ctrl+J
81
2.12-Funções, Comandos Internos e Palavras Chaves
Função Tipo O que faz
Abs() Função Retorna o valor absoluto..
Aleatorio Comando Liga/desliga o gerador de números
aleatórios, e pode substituir o
comando Leia().
Asc() Função Exibe o código ASCII de um
caractere.
Carac() Função Exibe o caractere do código
ASCII.
CaracpNum() Função Converte caractere em número, se
isto for possível.
Copia() Função Copia subtexto de um texto
Compr() Função Retorna o tamanho de uma
sequência de caracteres.
Const Comando Declara (cria) uma constante.
Cos() Função Dá o cosseno de ângulo rad.
Cronometro Comando Dá o tempo de processamento
desde on até off.
Exp() Função Potência de um número.
Grauprad() Função Converte graus em radianos
Int() Função Retorna a parte inteira de um
número real, sem arredondar.
Interrompa Abandona um loop de maneira
incondicional.
LimpaTela Comando Limpa a tela de janela DOS.
Log() Função Dá o logaritmo decimal de um
número real positivo.
Logn() Função Dá o logaritmo natural de um
número real positivo
Maiusc() Função Converte em letras maiúsculas.
Minusc() Função Converte em letras minúsculas.
Numpcarac() Função Converte pata em caractere.
Pausa Comando Para até pressiora tecla [F9]
82
Numpcarac() Função Converte pata em caractere.
Pausa Comando Para até pressiora tecla [F9]
Pos() Função Dá a posição inicial de um
caractere num texto.RaizQ() Função Dá a raiz quadrada de um
número real não negativo.
Randi() Função Gera números randômicos na
faixa indicada.
Quad() Função Dá quadrado de um número real.
Sen() Função Dá o seno de um ângulo, em rad.
Tan() Função Dá a tang. de ângulo em rad.
Timer(t) Comando Interrompe o processamento por
t milissegundos.
Pos() Função Dá a posição inicial de um
caractere num texto.
RaizQ() Função Dá a raiz quadrada de um
número real não negativo.
Tabela 2.4 - Algumas funções e comandos oferecidos pelo Visualg
Nota1: A diferença entre função e comando é que a primeira
sempre opera de maneira tal que seu nome vem ANTES dos
parênteses e retorna um resultado que pode ser atribuído a
uma variável de tipo compatível com o seu. Por exemplo, a
instrução x <-Int(3.456) terá x com o valor 3, sendo x do tipo
inteiro. No caso de comandos não existe nenhum retorno.
Por exemplo, Cronometro on apenas liga o relógio, e o
comando Cronometro off desliga o relógio. Depois de
Cronometro off o tempo;o mesmo acontece com o comando
LimpaTela: apenas limpa a tela dos resultados mostrado.
Nota2: Pressionando, simultaneamente, Ctrl+j serão
exibidos todos os comandos e funções do Visualg.
83
Palavras reservadas são termos que a linguagem reserva para si
mesma (além dos comandos e funções) e que não podem ser
utilizadas como identificador de quaisquer elementos de um
programa: nome do programa, nome de variável, nome de
constante, nome de procedimento, nome de função, etc. A tabela
2.5 mostra as principais palavras-chave do Visualg.
Aleatorio Enquanto Funcao Para
Algoritmo Entao Inicio Passo
Arquivo Escolha Int Pausa
Asc Escreva Inteiro Pos
Ate Escreval Interrompa Real
Carac Faca Leia Procedimento
CaracpNum Falso LimpaTela Repita
Caractere FimAlgoritmo Logico Retorne
Caso FimEnquanto Maiusc Se
Compr FimEscolha Minusc Senao
Copia FimFuncao Mod Tan
Cronometro FimPara Nao Var
Debug FimProcedimento Numpcarac Vetor
E FimRepita OU Verdadeiro
Eco FimSe OutroCaso Xou
Tabela 2.5 - Palavras reservadas em Visualg
84
2.13 - Recursos de Cálculos Numéricos
Para manipular cálculos numéricos, o Visualg oferece uma boa
relação de comandos e funções, como foi mostrado na figura
2.16. Os mais utilizados nos programas são os seguintes:
• Int(operação) //função que retorna a parte inteira de uma
operação ou número real.
• Abs(N) //função que retorna o valor positivo (módulo) de
um número N.
• RaizQ(N) //função que retorna a raiz real de um número
N não negativo.
• Exp(N,p) //função que retorna o valor da potência p de um
número N..
• LogN(N) //função que retorna o logaritmo natural de um
número N (N>0).
• Log(N) //função que retorna o logaritmo decimal de um
número N (N>0).
• Randi(faixa) //função que retorna um número randômico
dentro da faixa indicada.
• x Mod y //operador que dá o resto inteiro da divisão de x
por y (inteiros).
• x Div y //operador que dá o quociente inteiro da divisão de
x por y (inteiros).
• : //operador “dois pontos” utilizado para exibir valores
reais arredondados..
Por exemplo: Escreval(Num:5:2) mostra Num com
tamanho total 5 e 2 casas decimais.
85
2.14 - Manipulação de Caracteres
Trabalhar com strings (conjunto de caracteres entre aspas) é
sempre um problema em todas as linguagens de programação; no
C, por exemplo, o programador “sofre” muito para lidar com esse
tipo de dado. No Pascal existem os tipos “char” e “string”,
justamente para programas que precisam manipular esses tipos de
dados. Para manipulação de caracteres (individualmente ou
formando strings) o Visualg também oferece funções/comandos
que facilitam o trabalho do programador. Abaixo, estão alguns
comandos e funções para esse propósito:
• Var Letra: caractere //comando que declara a variável
Letra do tipo caractere.
• Var Frase: caractere //comando que declara a variável
Frase do tipo caractere.
• Var VetLetras: vetor[1..26] de caractere //comando
que declara a variável VetLetras um vetor de no máximo 26
elementos do tipo caractere.
• Var MatLetras: vetor[1..5,1..6] de caractere
//comando que declara a variável MaLetras uma matriz de
no máximo 30 elementos do tipo caractere, com 5 linhas e 6
colunas.
• Asc ("x") //função que retorna um inteiro de código ASCII
do primeiro caractere x.
• Carac (n) //função que retorna o caractere para o código n
da tabela ASCII.
• CaracpNum("x") //função que retorna o caractere x
convertido em valor numérico, quando isto for possível. Por
exemplo, CaracpNum("24"), retornará o inteiro 24.
86
• Compr(string) //função que que retorna o tamanho de uma
string.
• Copia(string,j,k) //função que que retorna k caracteres de
uma string, a partir da posição j dessa string.
• Maiusc(Frase) //função que converte a variável caractere
Frase em caixa alta (maiúscula).
• Minusc(Frase) //função que converte a variável caractere
Frase em caixa baixa (minúscula).
• NumpCarac(n) //função que retorna o número n
convertido em caractere. Por exemplo, NumpCarc(24),
retornará a string "24" .
• Pos("x", string) /função que retorna a posição do caractere
x em uma string. Se esse caractere não estiver na string
retorna 0 (zero).
O programa "ManipulaCaracteres" mostra utilizações práticas
dessas funções.
87
Algoritmo "ManipulaCaracteres"
//Mostra a utilização de várias funções de caracteres.
//Autor: Mário Leite
//-----------------------------------------------------
Var x, y, z, w: caractere
n: inteiro
Inicio
x <- "2" //atribui à variável x o caractere "2"
y <- "4" //atribui à variável y o caractere "4"
Escreval(x+y) //será exibido "24" na tela
Escreval(CaracpNum(x) + CaracpNum(y)) //será
escrito 6 na tela
Escreval(NumpCarac(3+4) + x) //será exibido
"72" na tela
z <- "Brasil, o melhor!"
Escreval(Maiusc(z)) //será exibido "BRASIL,O
MELHOR!" na tela
Escreval(Compr(z)) //será escrito 17 na tela
x <- "Brasil, centro do Universo"
Escreval(Pos("c",x)) //será escrito 9 na tela
Escreval(Pos("x",x)) //será escrito 0 na tela.
Não existe o caractere
"x" na variável x.
Escreval(Asc(x)) //será exibido 66 na tela -
código ASCII de "B".
w <- Carac(65) + Carac(66) + Carac(67)
Escreval(w) //será exibida a string "ABC" na tela
n <- CaracpNum(w)
Escreval(n) //será exibida 0 ("ABC" não é
considerado um caractere ASCII
z <- Copia(x,19,8)
Escreval(z) //será exibida a string "Universo" na
tela.
Escreval(Maiusc(Copia(x,19,8))) //exibirá a
string "UNIVERSO" na tela.
FimAlgoritmo
A figura 2.18 mostra as saídas da execução do programa
“ManipulaCaracteres”.
88
Figura 2.18 - Saída da execução do programa “ManipulaCaracteres”
2.15 - Operações de Entrada e Saída
A figura 2.19 mostra o esquema de qualquer sistema aberto, onde
tem obrigatoriamente, os três elementos básicos: Entradas -
Processamento – Saída
Entradas Processamento Saídas
Figura 2.19 - Esquema básico de um Sistema Aberto
Em Programação ocorre, exatamente, a mesma situação:
89
1) Entradas dos Dados
2) Processamento
3) Saídas
As Entradas são representadas pela leitura dos dados ou,
atribuições diretas; o Processamento utiliza comandos/funções
nas linhas de código; as Saídas são o resultado do processamento,
entregando ao usuário a(s) informação (s) por ele esperada(s).
No Visualg a forma mais prática de entrar com os dados é a
leitura, operacionalizada pelo comando Leia; e a saída é
executada pelos comandos Escreva e Escreval. A diferença entre
esses dois comandos é que enquanto o comando Escreva exibe
um valor e o cursor permanece na mesma linha, o comando
Escreval exibe o valor e o cursor é posicionado na próxima linha.
Observe as duas linhas de intruçõesabaixo, e a figura 2.20a.
Escreva("Hoje tem roda de samba.")
Escreva("O rock brasileiro dos anos 80 era muito bom!")
Figura 2.20a - Saida com os dois comandos Escreva
90
A figura 2.20a mostra o resultado (saída) da execução das duas
linhas de instruções, ambas com o comando Escreva. Neste caso
a segunda frase da segunda instrução saiu imediatamente após a
primeira frase. Isto aconteceu porque na primeira instrução foi
usado o comando Escreva, que escreveu a frase “Hoje tem roda
de samba.”; então, como não houve “salto” de linha, a saída
seguinte saiu colada imediatamente no final da primeira frase.
Para evitar isto, é que existe o comando Escreval (esse “éle” no
final de Escreva indica new line) para mostrar a próxima saída
em em nova linha. Então, alterando a primeira instrução, fica:
Escreval("Hoje tem roda de samba.")
Escreva("O rock brasileiro dos anos 80 era muito bom!")
Figura 2.20b - Saída com o primeiro comando modificado para Escreval
Em TODOS os programas, quando as entradas são solicitadas,
deve-se colocar um comando Escreva, ANTES do comando de
91
entrada. Isto é fundamental para explicar o usuário o que deve ser
a entrada, o que ele deve digitar; caso contrário, sem a mensagem
explicativa, a interatividade com o usuário ficará prejudicada. Por
exemplo, suponha que se deseja calcular a área de uma
circunferência que tem um determinado raio. Observe na figura
2.21a o que ocorre caso não haja uma mensagem explicativa para
essa entrada...
Figura 2.21a - Esperando entrada sem uma mensagem explicativa
Observe na figura 2.21a, que, mesmo tendo um título sobre o que
o programa faz, a entrada não tem mensagem explicativa, e o
usuário não saberá o que o programa está pedindo; o cursor fica
piscando na segunda linha do programa, mas, isto não quer dizer,
absolutamente nada para o usuário; não tem nenhum
esclarecimento sobre o que digitar! Agora, observe, na figura
2.21b, quando uma mensagem explicativa é colocada, ANTES,
da instrução de leitura: fica muito mais interativo com o usuário.
92
Figura 2.21b - Com a mensagem esclarecedora fica mais interativo
Embora esses dois comandos de entrada/saída já tenham sido
utilizados em exemplos anteriores, este item mostrou a real
importância de suas utilizações para que os programas fiquem
mais interativos com o usuário. Também é interessante enfatizar
que a mensagem esclarecedora, ANTES do comando Leia deve
ser com Escreva e não com Escreval, para que o cursor fique
piscando imediatamente após a mensagem. As saídas desejadas
pelos comandos Escreva/Escreval são separadas por vírgulas (,)
dentro dos parênteses, exigido pela sintaxe. Observe o esquema
abaixo, onde deseja-se exibir um texto e um valor numérico:
Escreva("Digite o novo valor:", Valor)
Comando de Saída Vírgula separadora
texto (string entre aspas retas) variável
Leia(Valor)
Comando de Entrada Variável
93
2.16 - Arredondando Valores de Saída
Observe a figura 2.22a; ela retrata uma saída semelhante à saída
da figura 2.22b, reportando a saída do programa
“ControleSalarial” do Exemplo 1, mas na segunda figura os
dois valores finais estão arredondados, para um salário bruto de
2468.24 e desconto de 9.5%. Note que os resultados do desconto
e do salário liquido foram, respectivamente, 234.4828 e
2233.7572 na primeira figura; isto é, ambos os valores com quatro
casas decimais para os centavos, o que é meio estranho em
qualquer moeda. Assim, é melhor apresentar os resultados
monetários com duas decimais, como é de praxe nas operações
financeiras. Para isto o Visualg oferece uma maneira bem simples
de fazer esse arredondamento dentro do comando de saída
Escreva/Escreval, na sintaxe: Valor:tamanho:decimais
▪ Valor é o valor real a ser formatado
▪ Tamanho: tamanho total do valor formatado
▪ Decimais: número de decimais desejado.
Figura 2.22a - Saída do programa "ControleSalarial” sem formatação
94
Alterando as duas linhas de instruções para formatar com duas
decimais, fica assim:
Escreval("Desconto para INSS: ",Desc:8:2)
Escreval("Salário líquido: ",SalLiq:5:2)
O resultado dos valores, agora formatado, com duas decimais é
visto na figura 2.22b.
Figura 2.22b - Saída do programa "ControleSalarial” com formatação
95
2.17 - Mensagens de Erros ao Rodar o Programa
Ao selecionar a opção “Executar” do menu principal, ou,
simplesmente pressionando a tecla de atalho F9 da janela
principal do Visualg, o interpretador da ferramenta inicia a
leitura/interpretação/execução de cada linha do programa-fonte
(pseudocódigo em portugol), a partir da primeira linha do
programa principal, começando em “Inicio”. Caso exista algum
erro o processamento é imediatamente interrompido, e será
exibida uma janela mostrando o ocorrido, através de uma
mensagem ao usuário. E como acontece em todas as linguagens,
existem, basicamente, três tipos de erros que podem ocorrer num
processo de criação/execução de programas em Visualg.
✓ Erro de Sintaxe
✓ Erro de Computação
✓ Erro de lógica (bug)
2.17.1 - Erro de Sintaxe
Este tipo de erro ocorre quanto uma palavra reservada da
linguagem não está escrita corretamente. Neste caso, ao
ler/interpretar a palavra o interpretador não a reconhece; o
processamento é interrompido de imediato, e uma mensagem é
emitida ao usuário alertando para esse fato; e mostrando, também,
o número da linha do programa onde ocorreu tal erro. Por
exemplo, no programa “FuncaoTrigInversa” abaixo, ocorre um
erro na linha de código Ang <- ArcSeno(S)*RD2GR onde o
programa está atribuindo à variável Ang o valor do ângulo (em
graus) cujo seno é digitado pelo usuário. Neste caso, o termo
ArcSeno não existe para o Visualg como uma função interna; a
palavra correta para esta função é ArcSen (sem a letra o no final).
Ocorreu um erro de sintaxe!
96
Algoritmo "FuncaoTrigInversa"
//Calcula e mostra a função inversa do seno de um ângulo.
//Autor: Mário leite
//------------------------------------------------------
Const RD2GR=57.29577951308232 //converte radianos
para graus
Var Ang, S: real
Inicio
Escreva("Digite o seno do ângulo: ")
Leia(S) A cor fica preta normal (estranho)
Ang <- ArcSeno(S)*RD2GR
Escreval("Ângulo cujo seno é",S,": ",Ang," graus.")
Escreval("")
FimAlgoritmo
A figura 2.23a mostra o resultado da tentativa de rodar o
programa.
Figura 2.23a - Erro de sintaxe no programa "FuncaoTrigInversa"
97
A figura 2.23a mostra a resposta do Visualg a esta situação,
emitindo a mensagem “Variável ‘ArcSeno’ não foi
encontrada”, e se “desculpando” por “não haver uma explicação
para tal problema”, além de mostrar o número da linha onde tal
erro ocorreu. Na verdade, ArcSeno não foi colocada no programa
como uma variável; ela foi empregada erradamente pelo
programador como uma função interna para retornar o valor do
ângulo que possui um seno digitado pelo usuário; e mostra que o
erro ocorreu na linha 10 do código-fonte do programa. O usuário
tem a opção de clicar em um dos dois botões oferecidos:
[Continuar] ou [Terminar]: se optar por continuar nada demais
acontece (o sistema apenas dá uma piscada e continua como está);
se clicar em [Terminar]] a execução termina e volta para a tela
de edição, e o poderá fazer as correções necessárias. Corrigindo
para o nome correto da função (ArcSen) o programa roda
normalmente e exibe o resultado esperado. A figura 2.23b mostra
o resultado do processamento após feita a correção.
Algoritmo "FuncaoTrigInversa"
//Calcula e mostra a função inversa do seno de um ângulo.
//Autor: Mário leite
//------------------------------------------------------
Const RD2GR=57.29577951308232 //converte radianospara graus
Var Ang, S: real
Inicio
Escreva("Digite o seno do ângulo: ")
Leia(S) Cor fica azul (palavra-chave correta)
Ang <- ArcSen(S)*RD2GR
Escreval("Ângulo cujo seno é",S,": ",Ang," graus.")
Escreval("")
FimAlgoritmo
98
Figura 2.23b - Saída correta do programa "FuncaoTrigInversa"
Como foi comentado no código acima, quando o programador
digita qualquer palavra-chave (que não seja um tipo de dado) o
Visualg a coloca na cor azul (padrão); caso não fique desta cor o
termo pode ter sido digitado de maneira incorreta; é uma forma
bem rápida de corrigir o código, antes de tentar executar o
programa!
Um outro caso de erro de sintaxe é quando o programador quer
fazer uma coisa, mas ordena outra para o computado; errando
totalmente a sintaxe, não por um simples erro de grafia da
palavra-chave, mas errando grosseiramente ao escrever algo que
não existe na linguagem, mesmo com a boa intenção de fazer a
coisa certa!
Por exemplo, no programa “CalculaRaizQuadrada” abaixo
ocorre um erro na linha de código R <- Sqrt(N), onde
programador deseja atribuir à variável R o valor da raiz quadrada
de um número N lido.
99
Algoritmo "CalculaRaizQuadrada"
//Calcula e mostra a raiz quadrada de um número real.
//Autor: Mário leite
//---------------------------------------------------
Var N, R: real
Inicio
Escreva("Digite um número: ")
Leia(N)
R <- Sqrt(N)
Escreval("Raiz quadrada de",N,":",R)
Escreval("")
FimAlgoritmo
A figura 2.24a mostra a resposta do Visualg a esta situação,
emitindo a mensagem de que “Variável ‘SQRT’ não foi
encontrada”, se “desculpando” por “não haver uma explicação
para tal problema”, e mostrando que o erro ocorreu na linha 9 do
código-fonte. Na verdade, Sqrt não foi colocada no programa
como uma variável; ela foi empregada, erradamente, pelo
programador como uma função interna para extrair a raiz
quadrada de um número digitado pelo usuário, tal como se faz na
maioria das vezes, pois Sqrt é uma função interna de muitas
linguagens de programação, justamente para este fim: extrair a
raiz quadrada de um número real, não negativo; no caso a raiz
quadrada de 142. Este é um vício de programação que pode ser
normal, quando o usuário está acostumado a codificar em outra
linguagem.
100
Figura 2.24a - Erro de interpretação num programa em Visualg
O nome correto da função do Visualg para extrair a raiz quadrada
de um número real não negativo é RaizQ. Observe agora, na
figura 2.22b, quando se troca Sqrt por RaizQ no programa
“CalculaRaizQuadrada”; o programa roda perfeitamente!
Algoritmo "CalculaRaizQuadrada"
//Calcula e mostra a raiz quadrada de um número real.
//Autor: Mário leite
//---------------------------------------------------
Var N, R: real
Inicio
Escreva("Digite um número: ")
Leia(N)
R <- RaizQ(N)
Escreval("Raiz quadrada de",N,":",R)
Escreval("")
FimAlgoritmo
101
Figura 2.24b - Saida do programa sem erro de interpretação em Visualg
2.17.2 - Erro de Computação
Aqui serão considerados os erros de “Falta de declaração de
Variáveis”, e “Erros em cálculos matemáticos”.
Ainda, considerado o programa “CalculaRaizQuadrada”,
observe o código dele abaixo onde foi omitida a declaração da
variável N.
Algoritmo "CalculaRaizQuadrada"
//Calcula e mostra a raiz quadrada de um número real.
//Autor: Mário leite
//---------------------------------------------------
Var R: real
Inicio
Escreva("Digite um número: ")
Leia(N)
R <- RaizQ(N)
Escreval("Raiz quadrada de",N,":",R)
Escreval("")
FimAlgoritmo
102
Ao tentar rodar o programa é exibida a mensagem “Variável N
não foi encontrada”, como mostra a figura 2.25a.
Figura 2.25a - Erro na execução do programa; falta declarar variável
E observe o que acontece quando o usuário digita um valor
negativo (-142). Embora não seja erro de sintaxe, ocorre erro de
operação matemática conhecida no jargão da computação como
“Invalid floating point operation” (erro de cálculo em ponto
flutuante - no caso, tentativa de extrair raiz quadra de um número
negativo). Tal tipo de erro ocorre também em todas as situações
em que a operação matemática resulte num overflow ou
underflow (estouros de memória). A figura 2.25b mostra o erro
cometido.
103
Figura 2.25b - Erro na execução do programa com estouro de memória
2.17.3 - Erro de Lógica (bug)
Nestes casos NÃO É ERRO DO COMPUTADOR, e sim do
programador que não criou o código-fonte corretamente para
obter o resultado esperado. A “culpa” é exclusiva de quem criou
o programa; nenhum sistema é capaz de detectar esse tipo de erro!
Observe o programa abaixo, onde o objetivo é calcular exibir a
soma dos números ímpares de uma série de números digitados
pelo usuário. A entrada dos dados termina quando for digitado o
número 0 (zero) .
104
Algoritmo "SomaImpares"
//Soma apenas os números ímpares de uma lista digitada
//Autor: Mário Leite
//-------------------------------------------------------
--------
Var j, Num, Soma: inteiro
Inicio
Soma <- 0
Num <- 9000
Enquanto (Num<>0) Faca
Escreva("Digite um número inteiro [zero termina]: ")
Leia(Num)
Se(Num Mod 2 = 0) Entao
Soma <- Soma + Num
FimSe
FimEnquanto
Escreval("Soma dos números ímpares digitados: ",
Soma)
FimAlgoritmo
Ao rodar o programa "SomaImpares" o resultado 218 é
nostrado na figura 2.26; mas está INCORRETO! O resultado
CORRETO seria 624 ao fazer a soma do números ímpares
digitados: 3+37+45+19+467+53. O erro foi um bug do programa,
na estrutura de decisão, onde testa se o número lido é ímpar: em
vez de Se(Num Mod 2 <> 0) foi escrito Se(Num Mod 2 = 0),
somando os pares, em vez dos ímpares!
105
Figura 2.26 - Resultado incorreto devido a um bug no programa
2.17.4 - Erro de Incompatibilidade de Tipos
Observe o programa da figura 2.27a.
Figura 2.27a - Erro na declaração de variáveis: incompatibilidade de tipo
106
Ao tentar rodar o programa da figura 2.27a o Visualg responde
com uma mensagem de erro mostrada na figura 2.27b.
Figura 2.27b - Mensagem de erro de incompatibilidade de tipo
Por que ocorreu o erro ao tentar rodar o programa mostrado na
figura 2.27b?!
O processamento de somas algébricas e/ou multiplicação/divisão
que contenta parcelas e/ou fatores do tipo real, sempre vai gerar
107
resultado do tipo real; então a variável que o armazenará tem que
ser do tipo real. Na dúvida sobre o tipo de dado resultante, deve-
se optar sempre por variáveis do tipo real; por isto foi gerada a
mensagem. “Erro na atribuição de valores na variável AREA:
REAL para INTEIRO. Para evitar esse erro, a variável area teria
que ser declarada como real; a variável raio poderia continuar
como inteiro.
2.17.5 - Erro de Instrução fora de área
Na área de “Declarações” (de arquivos, de constantes, de
variáveis e de registros - nesta ordem) ANTES de Inicio, não
pode haver instruções. As instruções só podem ser digitadas entre
Inicio e FimAlgoritmo”. Se alguma instrução for digitada na
área de “Declarações”, o interpretador do Visualg emitirá uma
mensagem de erro. Observe a figura 2.28a, que mostra o
programa “AreaCirculo” no editor do Visualg, em local proibido
(dentro da “Seção de Declarações”).
Figura 2.28a - Programa “AreaCirculo” com instruções em local proibido
108
Ao tentar rodar o programa, dá um erro, como mostrado na figura
2.28b.
Figura 2.28b - Alerta de erro na execução do programa “AreaCirculo”
Observe na figura 2.28b, que já na primeira linha de instrução
detectada fora do local permitido, dá erro na interpretação. E,
caso fosse removida essa primeira linha, o erropersistiria na
segunda, até que todas as linhas de instruções fossem removidas
dessa área proibida para instruções.
Agora, vamos remover essas linhas da “Seção de Declarações” e
colocá-las no local correto: a partir do comando Inicio, como na
figura 2.28c.
109
Figura 2.28c - Programa “AreaCirculo” com instruções em local correto
Agora, o programa roda normalmente, e apresenta o resultado
correto. (vide a saída na figura 2.28d)
Figura 2.28d - Saída correta do programa “AreaCirculo”
110
Note que, agora, com as quatro linhas de instruções digitadas,
corretamente, na “Seção de Comandos”, o programa rodou sem
problemas, e mostrou o resultado desejado: a área do círculo de
raio 4. Entretanto, devemos lembrar que o valor da área de um
círculo, dado seu raio, pode ter valores diferentes um do outro.
Isto acontece devido à constante universal PI, que pode ser
empregada com um número de casas decimais bastante variável
(até o final de 2019 PI havia sido calculado com mais de 31
trilhões de decimais). O identificador PI representa, exatamente,
essa constante, cujo valor utilizado é 3.14159265358979 (com
quatorze decimais). Deste modo, para utilizar o valor de
3.141592653589793 (com quinze decimais), o programa usou
PII como identificador da constante, em vez de PI, pois PI é uma
palavra reservada do Visualg. Outro detalhe a ser notado nas
figuras 2.28a e 2.28c é que o nome do programa aparece como
“semnome”; isto acontece porque o programa ainda não fora
salvo num arquivo em disco. E embora o arquivo possa ser salvo
com qualquer nome válido, uma boa prática é salvar o arquivo
com o mesmo nome do programa. Assim, vamos salvar o
programa no arquivo “AreaCirculo.alg” no seguinte local:
D:/Livros/Livro9/Codigos, como mostra a figura 2.29a.
111
Figura 2.29a - Salvando o programa “AreaCirculo” no local desejado
Figura 2.29b - Arquivo do programa “AreaCirculo” salvo em arquivo
112
2.17.6 - Erro de Falta de Terminadores
“Estruturas de Controle” - que serão vistas no Capítulo 4 - são
comandos compostos que permitem tomar decisões, e repetir um
bloco de linhas de instruções. Em Visualg todas as estruturas de
controle têm uma instrução de início e outra para indicar o seu
término; assim, é muito comum acontecer do programador se
esquecer, ou mesmo duplicar o terminador de uma dessas
estruturas, causando erro na hora de executar o programa. Por
exemplo, as estruturas de decisão começa com apalavra-chave Se
e exige o terminador FimSe para indicar seu término; então, pode
ocorrer que o programador se esqueça desse terminador.. Observe
o programa “VerificaValor” na figura 2.30a, e o resultado na
tentativa de executar o programa, na figura 2.30b, mostrando a
mensagem: “Esperava encontrar FimSe”, indicando que faltou
esse terminador na estrutura .
Figura 2.30a - Código-fonte do programa “VerifValor” no editor
113
Figura 2.30b - Erro na execução do programa “VerifValor”
Observa na figura 2.30b que, mesmo lendo corretamente o valor
digitado, ocorreu um erro ao tentar “fechar” a estrutura, devido à
falta do terminador FimSe.
Agora, vamos introduzir um “pequeno” erro de digitação no
programa: apenas deslocar o dois pontos (:) para depois das
aspas, na instrução de leitura (primeira linha de código do
programa): Escreva("Digite um valor" : ). veja como fica na
figura 2.31a. O resultado da tentativa de execução do programa
pode ser visto figura 2.31b.
114
Figura 2.31a - Código-fonte do programa “VerifValor” no editor
Figura 2.31b - Erro na execução do programa “VerifValor”
115
Note que a mensagem de erro emitida pelo Visualg, na figura
2.31b, não esclarece bem a respeito do que provocou o erro “Não
há explicação disponível para este problema”. Além disso,
observe que nada apareceu na janela DOS; nenhum saída! Neste
caso, o erro ocorreu devido à sintaxe errada de uma instrução de
saída. Mensagens de erro assim (sem um esclarecimento real),
pode acontecer; vai depender do programa e do contexto do
código. Por isto, o usuário deve ter cuidado na digitação do
código do programa. Observe o programa
“MostraParesNaFaixa”, no editor do Visualg, mostrado na
figura 2.32a.
Figura 2.32a -Código-fonte do programa “MostraParesNaFaixa”
116
Na figura 2.32b o Visualg emitiu a mensagem “Esperava
encontrar FimPara”, ao tentar rodar o programa
“MostraParesNaFaixa”, indicando que esse terminador faltou
na estrutura de repetição Para..FimPara (que será estudada no
Capítulo 4). Entretanto, apareceu a instrução de fim de programa
“FimAlgoritmo”, deixando dúvidas se essa instrução também tem
erro além de mostrar outra mensagem “Não há explicação para
este problema”! Na verdade, a explicação foi dada ao dizer que
“não encontrou FimPara”. Portanto, o usuário deve ficar bem
atendo na hora de digitar o código do programa no editor do
Visualg, para evitar que ocorra erros que podem ser fáceis de
evitar, mas, às vezes, difíceis de entender a mensagem.
Figura 2.32b-Erro na execução do programa “VerifMostraParesnaFaixa”
117
2.18 - Medindo o Tempo de Processamento
Um dos recursos bem interessante e bastante prático oferecido
pelo Visualg é a medição do tempo de processamento de um
bloco ou do programa todo. Este recurso é dado pelas instruções
Cronometro on e Cronometro off. A primeira dispara o
cronômetro (marca o início da medição) e a segunda desliga o
cronômetro (marca o fim da medição).
...
Cronometro on //aqui o cronômetro é ligado e o tempo
começa a ser contado
...
...
Cronometro off //aqui o cronômetro desliga e o tempo de
processamento é exibido
A figura 2.33 mostra o resultado da execução de um programa
que gera alguns números randômicos pares. O tempo gasto para
gerar esses números foi de 22s e 797ms; o resultado é exibido na
“Área de visualização dos resultados”.
Figura 2.33 - Resultado da medição do tempo de processamento
118
2.19 - Depurando Programas
A depuração (debunggin) é muito importante quando estiver
ocorrendo resultados estranhos ao rodar um programa. É um
processo de encontrar e reduzir defeitos num programa; nesses
defeitos estão incluídos aqueles tipos que previnem
o programa de ser executado e aqueles que produzem um
resultado inesperado.
A depuração de um programa no Visualg é feita, pressionando a
tecla F8 (para executar passo a passo as linhas de instruções) em
vez da tecla F9, que executa todo o código sem paradas. E,
embora exista o comando debug(expressão) para depurar uma
linha de código, o uso de F8, em conjunto com breakpoint, é mais
prático. Para ver isso na prática, vamos considerar o programa
abaixo, denominado “CalculaMedia”, que lê quatro notas
parciais de um aluno e calcula a média aritmética dessas notas,
exibindo-a com apenas uma casa decimal. Para fazer o debugging
de um programa em Visualg, basta criar um breakpoint na linha
de código que pode estar ocorrendo o bug e pressionar F8 para ir
executando o programa passo a passo. Por exemplo, no programa
mencionado o resultado da média das notas 7.6, 8.5, 7.4 e 7.1 está
apresentando um resultado estranho: 25.3, em vez de 7.5;
conforme mostra a figura 2.34.
119
Figura 2.34 - Resultado incorreto do programa ”Calculamedia”
Então, o programador deve desconfiar dos valores entrados, ou
do cálculo da média. Desse modo, coloca-se um breakpoint na
linha de instrução do cálculo da média, pressiona F8 para ir
observando o fluxo do programa passo a passo (vide figura 2.35).
Figura 2.35 - Executando o programa ”Calculamedia” passo a passo
120
Assim, o bug do programa pode ser encontrado, e a instrução
reescrita corretamente, envolvendo a soma das nota com
parênteses:
media <- (nota1+nota2+nota3+nota4)/4Fazendo essa alteração, o resultado da média das quatro notas
sairá correto, como mostra a figura 2.36.
Figura 2.36 - Executando o programa ”Calculamedia” passo a passo
2.20 - Comentários
Os comentários são fundamentais para documentar o código de
uma rotina ou um bloco de instruções. Dependendo da linguagem
de programação os símbolos para indicar um “comentário”
podem variar; mas, no Visualg pode ser empregado um par de
121
barras paralelas inclinadas (//) para comentar uma linha, como
também chaves { } para comentar um bloco de linhas. Os
comentários são utilizados para explicar linhas de instruções de
modo a esclarecer melhor a funcionalidade dentro do programa;
como por exemplo, nas instruções abaixo.
Soma (Nota1+Nota2+Nota3+Nota4) //Soma as notas
Media Soma/4 //Calcula a média aritmética das notas
Tudo que for digitado depois das duas barras (//) é ignorado pelo
processador; mas é muito importante para esclarecer melhor o
que está sendo feito. É claro que não se deve comentar o óbvio;
no exemplo acima foi apenas para exemplificar o uso deste
recurso em programação. Veja a expressão matemática abaixo.
M = C(1+i)t
Se não houver nenhum comentário para explicar melhor o que
significa cada termo desta instrução, ficaria difícil entender o que
se deseja com esta equação depois de passado algum tempo da
criação do programa. As figura 2.37a e 2.37b mostram um
programa de cálculo financeiro com as variáveis comentadas de
duas maneiras diferentes.
122
Figura 2.37a - Variáveis comentadas em linhas separadas
Os comentários são muito importantes para documentar os
trechos mais complexos dos programas, e sempre devem aparecer
nas aplicações. Isto é importante, pois esses trechos ficam mais
explícitos para que nas manutenções futuras o programador possa
entender melhor a lógica do programa. Para comentar um bloco
de linhas basta colocá-lo entre chaves { }; por exemplo, comentar
as variáveis do programa “Financeiro” mostrado acima.
123
Figura 2.37b - Variáveis comentadas em um bloco de linhas
2.21 - Exercícios Propostos
1 - Qual é a vantagem de se usar a “Barra de Ícones” do Visualg
para executar uma ação na criação de um programa, sabendo que
essas mesmas ações podem ser obtidas na “Barra do Menu
Principal”?
2 - Qual é a diferença entre comandos e funções (internos) no
Visualg? Dê exemplos.
3 - Se o Visualg não é uma linguagem real, qual é a sua
importância no aprendizado de Linguagem de Programação?
4 - Existem erros no programa “AreaCirculo” escrito em
Visualg. Mostre quais são esses erros.
124
Algoritmo "AreaCirculo"
//Calcula a área de um círculos,dado o seu raio.
//-----------------------------------------------------
Var raio, area: inteiro
Const: PI=3.14159265
Inicio
Escreva("Digite o valor do raio do círculo: ")
Leia(raio)
area <- PI*raio^2
Escreva("Área do círculo: ", area)
FimAlgoritmo
5 - Observe o programa abaixo, em Visualg: ele vai rodar?!.
Explique!
Algoritmo "AreaTriangulo"
//Calcula a área de um triângulo dada sua base e altura.
//-----------------------------------------------------
Inicio
Var B, h, Area: real
Escreva("Digite o valor da base: ")
Leia(b)
b <- Abs(b)
Escreva("Digite o valor da altura: ")
Leia(h)
h <- Abs(h)
Area <- b*h
Escreval("")
Escreval("Área do triângulo:", Area)
Escreval("")
FimAlgoritmo
6 - Marque com V os identificadores válidos para variáveis e com
F para os não válidos.
A ( ) DevIR20
125
B ( ) AmanhaDeManhaVouPedirOCafePraNosDois
C ( ) MédiaGeral
D ( ) QteMaçãs
E ( ) 2aNota
F ( ) Nota2
G ( ) Cata_Vento
H ( ) DevoluçãoIR20
I ( ) R$Ganho
J ( ) Const
7 - Marque com V as alternativas que contenham instruções
válidas (com resultados normais) e com F as que contenham
instruções inválidas nos programas em Visualg, sabendo que as
variáveis A, B e C são numéricas do tipo inteiro, e D do tipo
logico.
A ( ) Declare A, B, C: real
B ( ) Var A, B, C, D: inteiro
C ( ) A <- B =C
D ( ) D <- A>C
E ( ) C <- C > ( A+B)
F ( ) A <- RaizQ(B/C)
G ( ) A <- (A Mod A)
H ( ) B <- (B Div C)
I ( ) D <- nao(A>(B+C))
8 - Se você pode codificar um programa diretamente numa
linguagem real, por exemplo, Python, qual seria a vantagem de
usar o Visualg, antes dessa codificação?
9 - Marque a única expressão INVÁLIDA no Visualg, com A=3,
B=4 e C=Verdadeiro.
A ( ) C <- (B > (RaizQ(B)/A*B))
B ( ) (A>B) e C ou (nao(A<=B) )
C ( ) (B<=A) ou C e (não.(A<=5))
126
D ( ) (C>=B) e A<B
E ( ) C <- (B<C) e (nao((nao(nao(nao((A+B)<C)))))))
10 - Observe o trecho de programa abaixo para calcular as duas
raízes reais de uma equação do 2º grau do tipo ax2 + bx + c = 0,
supondo que todas as variáveis tenham sido declaradas
corretamente. As duas raízes, x1 e x2 SEMPRE serão mostradas
num programa em Visualg? Explique sua resposta!
...
Escreva("Digite o valor da constante a: ")
Leia(a)
Escreva("Digite o valor da constante b: ")
Leia(b)
Escreva("Digite o valor da constante c: ")
Leia(c)
x1<- (-b + RaizQ(b^2-4*a*c))/(2*a)
x2<- (-b - RaizQ(b^2-4*a*c))/(2*a)
Escreval("Primeira raiz:: ",x1)
Escreval("Segunda raiz:: ",x2)
...
11 - Escreva os valores resultantes das expressões abaixo,
sabendo que A=3, B=4 e C=5 (inteiros).
A ( ) A + B/A
B ( ) A + (B/A)
C ( ) A > B
D ( ) A <= B
E ( ) A + RaizQ(B)/A*B )
F ( ) nao(A>B) e B<=C)
G ( ) (B<=A) e (C>=B) ou (nao(A<=5))
H ( ) (C>=B) e (A<=B)
I ( ) nao((nao(A>B) e (C=B)) ou (A<B))
J ( ) A <- (B<C) e (nao((nao(nao(nao(A+C))))))
127
Capítulo 3 - Tipos de Dados no Visualg
3.1 - Introdução ao Capítulo
Neste capítulo serão estudados os tipos de dados suportados pelo
Visual; por exemplo, no programa "AreaTriangulo", dos
“Execícios Propostos” do capítulo anterior, vimos a seguinte
instrução, antes do Inicio do programa: Var b, h, Area: real
Esta instrução declara (define) três variáveis do tipo real (b, b,
Area), todas do tipo real, para armazenar valores numéricos com
ou sem casas decimais. Em outras palavras, o comando Var
define o tipo de dado que será armazenado naquele endereço de
memória; isto é, o TIPO de dado das três variáveis. Do ponto de
vista formal pode-se dizer que “um tipo de dado define uma área
de memória com certas características e um conjunto de
operações que sobre ela pode ser aplicado”. Um tipo de dado
define uma faixa de valores permitida para operações.
3.2 - Tipos Primitivos de Dados
De um modo geral os tipos primitivos podem ser agrupados em
três grandes grupos:
• Numérico
• Caractere
• Lógico
O tipo Numérico abrange quaisquer valores que se traduzem em
números, e se subdividem em duas categorias: inteiro e real. Por
exemplo, para armazenar o número de filhos de um casal deve ser
utilizado o tipo inteiro, uma vez que não existe por exemplo, 2.5
filhos: ou são 2 filhos ou são 3 filhos. Já o tipo real define uma
128
faixa de números que pode conter casas decimais e usados em
quaisquer operações matemáticas, mas que não é o ideal, neste
exemplo, para armazenar o número de filhos de um casal.
O tipo Caractere, também conhecido como string (alfanumérico,
texto, literal ou cadeia), define uma ampla faixa de valores com
os quais só é possível efetuar uma única operação: a
concatenação; junção de cadeias: “Ana “ + “Lúcia” = “Ana
Lúcia”. Este tipo de dado não pode ser empregado em operações
matemáticas.
O tipo Lógico armazena apenas um dos dois possíveis valores
lógicos: Verdadeiro ou Falso, e só empregado em expressõeslógicas.
Dependendo da linguagem de programação, o tipo numérico pode
ser subdivididos em outros para atender as necessidades da
aplicação. Por exemplo, um valor numérico que não tem casa
decimal é considerado um inteiro, mas, armazenar o número de
filhos de um casal é um pouco diferente do que armazenar o
número de habitantes da cidade de São Paulo. O tipo numérico é
dividido em inteiros e reais; e mesmo assim estes ainda podem
ser subdivididos em outros tipos para melhor atender as
especificidades da aplicação, com a linguagem utilizada. O
esquema da figura 3.1 mostra como os tipos de dados se
apresentam, em termos gerais, independentemente de qualquer
classificação secundária em uma linguagem formal de
programação. Num programa qualquer, em pseudocódigo, essa
figura fornece a base do uso desses dados nas operações.
129
Figura 3.1 - Tipos básicos de dados
No caso do tipo inteiro (normal) suas características são as
seguintes:
• Faixa: -2147483648 a +2147483647
• Operações: suporta as quatro operações elementares e
mais algumas permitidas pela Matemática; por exemplo,
potenciação.
O tipo real abrange o tipo inteiro e quaisquer valores que
possuam casas decimais; isto é, o tipo real tem uma faixa de
valores bem maior que a dos inteiros.
• Faixa: -3.4x10-4932 a +3.4x104932
• Operações: suporta as quatro operações elementares e
mais outras permitidas pela Matemática; por exemplo,
raiz quadrada de apenas números não negativos dando
como resultado um número real.
130
O tipo caractere, comumente chamado de string, define os dados
que podem conter qualquer tipo de caractere. Entretanto, para
indicar este tipo os valores têm que ser escritos entre aspas retas
(" ") , e a única operação permitida é a concatenação.
O tipo lógico (booleano) é aquele que armazena apenas um dos
dois valores lógicos permitidos pela lógica formal: Verdadeiro ou
Falso; e as operações têm que ser do tipo relacional, sempre
dando como resultado um valor lógico.
3.3 - Tipos Complexos[12]
Os tipos complexos são, na verdade, derivados dos tipos básicos
primitivos; assim, por exemplo, pode existir uma matriz de
números inteiros ou de caracteres, ou ainda uma estrutura
(registro) com elementos de vários tipos básicos. Na linguagem
C e nas suas correlatas, existe, adicionaçlmente, o tipo void, que
não foi relacionado no esquema da figura 3.1; este é um tipo
meio “esquisito”, pois representa um tipo “sem tipo sem valor”.
Na verdade ele foi criado para justificar o “retorno” de uma rotina
que não retorna nada; isto é, foi criado para que a linguagem C
não precisasse trabalhar com rotinas chamadas procedimentos;
bastante comuns em outras linguagens, e que não têm retorno. De
qualquer forma, qualquer outro tipo de dado sempre será uma
composição dos três tipos primitivos básicos: numérico,
caractere, lógico.
3.4 - Os Tipos de Dados Considerados no Visualg
No Visualg os tipos de dados utilizados são os tipos primitivos:
• Numérico (inteiro e real)
• Caractere (texto)
• Lógico
Variáveis do tipo inteiro possuem valores na faixa de -
2147483647 a +2147483647, o que nas outras linguagens é
131
chamado de “inteiro longo”. Por razões de controle interno, o
limite inferior dessa faixa, no Visualg, é uma unidade maior que
a considerada nas linguagens de programação formais, que é -
2147483648.
Variáveis do tipo real seguem o mesmo padrão de faixa do tipo
real da linguagem Pascal.
Variáveis do tipo lógico só podem assumir dois valores:
Verdadeiro ou Falso.
O uso de qualquer um tipo de dado para uma variável vai
depender, exclusivamente, da característica do seu conteúdo a ser
manipulado dentro da lógica do programa.
3.5 - Declaração de Variáveis no Visualg
Embora já tenha sido apresentados alguns exemplos de
programas com declarações de variáveis, vamos formalizar este
procedimento aqui neste item, e com detalhes adicionais.
Como já foi mencionado, as variáveis representam endereços da
memória RAM, e são utilizadas para armazenar dados e
resultados de processamentos. E, como armazenam dados, é
preciso que os tipos de dados de cada uma delas seja,
previamente, declarado (definido) para que o interpretador do
Visualg possa indicar à CPU a melhor maneira de fazer a alocação
do endereço de memória. Assim, se uma determinada variável for
declarada como sendo do tipo inteiro, então o valor 4.3578 não
poderá ser armazenado corretamente nessa variável; certamente
será truncado e considerado apenas 4, pois, as decimais serão
ignoradas. Deste modo, é preciso prestar bem atenção nos tipos
de dados das variáveis que serão usadas no programa. Todas as
variáveis utilizadas num programa em Visualg TÊM que ser
declaradas antes de serem inicializadas, ou lidas. O comando para
declarar variáveis é a palavra-chave Var, obedecendo a sintaxe:
132
Var x1,x2,x3,..,xn: tipo
A sintaxe acima declara as n-variáveis x como sendo de um
determinado tipo de dado; isto é, TODAS de um mesmo tipo. Se
fossem variáveis de tipos diferentes, teriam que ser declaradas em
linhas separadas, para cada tipo.
Var x1,x2,x3: inteiro
X4, x5: real
X6, x7, x8: caractere
X9: logico
Observe que na sintaxe de declaração usa-se apenas um Var para
declarar TODAS as variáveis, mesmo que sejam de tipos
deferentes, em linhas distintas. A figura 3.2a mostra como fica
dentro do editor do Visualg as declarações dessas nove variáveis.
Figura 3.2a - Declarando variáveis de um programa em Visualg
É claro que, se executarmos o programa acima nada vai aparecer
como resultado, pois na “Seção de Comandos” nada foi digitado,
133
como pode ser conferido na figura 3.2b; tanto na janela DOS
(tela preta) quanto na janela da “Area de Visualização dos
Resultados”.
Figura 3.2b - Saída do programa: nada exibido
Às vezes, o programador pode cometer erro ao declarar uma
mesma variável mais de uma vez; e quanto isto acontece é emitida
uma mensagem de aviso, como no caso abaixo, se a variável x7
fosse declarada mais de uma vez numa mesma linha (mesmo tipo
de dado), ou em linha distinta com outro tipo de dado. Veja a
figura 3.3.
134
Figura 3.3 - Erro na interpretação: variável declarada mais de uma vez
Quando ocorre algum erro na interpretação (tentativa do Visualg
em ler o comando) o programa trava, e é necessário clicar no
botão [Terminar] para reparar o erro e reeditar a instrução
corretamente. Clicar no botão [Continuar] não adianta nada,
esses casos!
135
❖ Exemplo 3.1 - Criar um programa que calcule e mostre a raiz
cúbica de 12.
A figura 3.4a e a figura 3.4b mostram, respectivamente, o
programa “CalculaReizCubica12” no editor, em duas versões
diferentes e com seus respectivos resultados na execução, em
função das declarações das duas variáveis: num e raizCub.
Figura 3.4a - Programa com problema de declaração de tipo errada
136
Neste caso, houve erro na tentativa de atribuir um resultado do
tipo real [12^(1/3)] na extração da raiz cúbica de 12 a uma
variável do tipo inteiro.
Agora, declarando corretamente a variável raizCub numa linha
separada, para o tipo real, não haverá erro na interpretação e o
resultado será exibido normalmente, como pode ser confirmado
na figura 3.4b.
Figura 3.4b - Programa com saída norma
137
3.6 - Operadores e Operações
Os operadores são símbolos utilizados para realizar cálculos, bem
como instrumentos complementares usados para permitir ao
usuário modificar, avaliar, comparar e checar o conteúdo das
variáveis, auxiliando na montagem de fórmulas nas expressões
numéricas e de cadeias de caracteres dentro de um algoritmo.
Também são muito utilizados dentro de comandos simples e
compostos. Embora possa existir vários tipos de operadores nas
linguagens formais, eles podemser divididos em apenas três
grandes categorias básicas: Aritméticos, Relacionais e Lógicos:
Operador Símbolo Tipo O que faz
Unário
– Unário Inverte o sinal de valor numérico.
Potenciação ^ Binário Eleva um número a uma potência.
Divisão real
/ Binário
Divide dois números reais, dando um
resultado real, se o divisor não for 0.
Multiplicação * Binário
Multiplica dois valores reais, dando
como resultado um valor real.
Divisão
inteira
Div Binário
Divide dois números inteiros, dando
um resultado inteiro, se o divisor não
for 0. Por exemplo, 7 Div 2 = 3,
Resto da
divisão
Mod
Binário
Dá o resto inteiro da divisão inteira
entre dois números inteiros. Por
exemplo: 7 Mod 2 = 1.
Adição + Binário
Soma dois valores reais, resultando
em um valor real.
Subtração – Binário
Subtrai um valor real de outro,
dando como resultado um valor real.
Tabela 3.1 - Operadores Aritméticos na hierarquia das operações
138
Operador Símbolo O que faz
Igual a
= Verifica se duas expressões, ou conteúdo de
duas variáveis, possuem o mesmo valor.
Diferente
de
<> Verifica se duas expressões, ou conteúdo de
duas variáveis, possuem valores diferentes.
Menor
que
< Verifica se uma expressão, ou conteúdo de uma
variável, é menor que o conteúdo de outra.
Maior que
> Verifica se uma expressão, ou conteúdo de uma
variável, é maior que o conteúdo de outra.
Menor ou
igual
<= Verifica se uma expressão, ou conteúdo de uma
variável, é menor ou igual ao conteúdo de outra.
Maior ou
igual
>= Verifica se uma expressão, ou conteúdo de uma
variável, é maior ou igual ao conteúdo de outra.
Tabela 3.2 - Operadores Relacionais
139
Operador Símbolo Tipo O que faz
Negação
nao Unário Inverte o valor lógico de uma expressão
lógica, de modo que se for Verdadeiro
passa a ser Falso, e se for Falso passa a ser
Verdadeiro.
Conjunção
e Binário Liga dois valores lógicos, de modo que o
resultado só será Verdadeiro se ambos
forem Verdadeiro, caso contrário, se pelo
menos, um dos valores for Falso resultará
Falso.
Disjunção
ou Binário Liga dois valores lógicos, de modo que o
resultado será Verdadeiro se pelo menos,
um destes valores for Verdadeiro, e será
Falso se ambos forem Falso.
Disjunção
Exclusiva
xou Binário Liga dois valores lógicos, de modo que o
resultado será Verdadeiro se um dos dois
valores for Falso e o outro Verdadeiro; e
será Falso se ambos os valores forem
Verdadeiro ou ambos Falso.
Tabela 3.3 - Operadores Lógicos na hierarquia das operações
Nota: Embora exista uma hierarquia para os operadores, os parênteses
sempre são os mais prioritários, podendo alterar a ordem de operação
numa expressão. O que estiver dentro dos parênteses mais internos será
primeiramente executado, obedecendo o sentido lógico operativo na
expressão: “da esquerda para a direita”.
Conclusão: Tentar, por exemplo, colocar um valor do tipo real
num local preparado para receber um tipo inteiro é como se
quisesse colocar o conteúdo de um copo cheio d’água numa
140
xícara de cafezinho; vai derramar! Mas, embora o contrário seja
possível - colocar o conteúdo de uma xícara num copo - seria um
desperdício de espaço! Portanto, escolher o tipo de dado mais
compatível com o conteúdo a ser armazenado (alocação estática,
adotada pelo Visualg) é bom, e pode economizar espaço na RAM.
Os operadores aritméticos são empregados em instruções que
envolvem cálculos matemáticos entre duas expressões numéricas,
produzindo um resultado numérico.
Os operadores relacionais são empregados em comparações de
duas expressões, e o resultado só pode ser num valor lógico:
Verdadeiro ou Falso.
Os operadores lógicos[13] são empregados para unir duas
expressões de tal modo que o resultado é um valor lógico,
modificado de acordo com os valores lógicos de cada expressão,
e dando como resultado um dos dois valores possíveis:
Verdadeiro ou Falso; tal como nas chamadas proposições.
Considere a seguinte frase: “O leite é preto”; apesar de ser
estranha para nós é uma proposição, já que seu valor é Falso
assim como a frase “o leite é branco”, cujo valor lógico é
Verdadeiro. Já a frase exclamativa “Olha que coisa mais linda,
mais cheia de graça!” não é uma proposição, pois não permite
um valor lógico como resultado. Portanto, somente são
consideradas proposições as frases que podem ter como resultado
um valor lógico. A hierarquia das operações ou das expressões
aritméticas segue as regras da matemática; e assim como tal,
deve-se sempre observar a única regra básica para toda e qualquer
formula:
1. Primeira Regra : sempre da esquerda para a direita;
2. Segunda Regra : precedência (ou prioridade):
1a Parênteses (...): tudo que estiver entre os parênteses será
executado primeiro.
2a Exponenciação: dentro de uma formula será executada
prioritariamente.
141
3a Multiplicação e Divisão: será executado o operador que
aparecer primeiro.
4a Soma e Subtração: será executado o operador que
aparecer primeiro.
Observe a instrução: X <- 100*2/5 (com x do tipo real)
O valor armazenado na variável X após executar a instrução
100*2/5, será 40; pois o processamento será feito assim:
1º) 100 será multiplicado por 2 ==> 200
2º) 200 será dividido por 5 ==> 40
3º) o valor 40 será atribuído à variável X.
Os operadores relacionais são utilizados sempre dentro de
expressões de comparações; e os valores a serem comparados
devem ser sempre dos tipos: Numéricos (inteiros ou reais) ou do
tipo caractere. E o resultado dessa comparação sempre retornará
um valor do tipo lógico (Verdadeiro ou Falso).
Um dos operadores, talvez o mais importante para a
programação, e que não foi mostrado nas tabelas anteriores, é o
operador de atribuição, cujo símbolo em Visualg é representado
por <- (sinal de “menor que” seguido do sinal de subtração,
Atribuir à variável Soma o valor de 0 (inicializar essa variável):
Soma <- 0
• Incrementar a variável Soma de 1: Soma <- Soma + 1
• Atribuir à variável Raiz a raiz quadrada de um número N:
Raiz <- RaizQ(N)
• Atribuir à variável x1 o resultado de expressão: x1 <- (-
b+RaizQ(Delta))/(2*a)
Nota: Observe nos exemplos de atribuições acima, que o termo Raiz
pode ser utilizado como identificador de variável. Mas, RaizQ (apenas
com a inclusão do Q) não pode ser identificador de variável, pois é uma
palavra reservada do Visualg (função interna) que retorna a raiz
quadrada de um número real não negativo.
142
Os operadores relacionais e lógicos são sempre utilizados em
operações que envolvem comparações, e onde os resultados
dessas comparações sempre retornam valores lógicos. Estes tipos
de operadores são geralmente empregados dentro de comandos
de desvios condicionais (que serão vistos com mais detalhes no
próximo capítulo).
Resumo: Como as variáveis podem ser consideradas “caixas”
que contém “algo” para ser guardado na memória RAM do
computador, o Tipo de Dado seria o “tipo de material” dessa
“caixa”; portanto, cada material deve ser guardado em caixas do
tipo adequado. Então, fazendo uma analogia com a sua natureza:
se o material (valor) é líquido a caixa tem que ser de um material
(tipo) que suporte líquido. Em termos de tamanho: se o material
for muito pequeno, seria um desperdício utilizar uma caixa muito
grande; caso contrário, se o material for algo muito grande a caixa
também deve ser de tamanho compatível, se não o material não
caberá nela!
• Exemplo 3.2 - Criar um programa em Visualg para realizar as
principais operações matemáticas.
No programa “OperacoesMatematicas” são lidos dois números:
num1 e num2; ambos inteiros e maiores que zero.
143
Algoritmo "OperacoesMatematicas"
//Faz operações matemáticasem função de um menu de
//opções.
//Autor: Mário Leite
//------------------------------------------------------
Var Num1, Num2: real
Soma, Subt, Mult, Divide, Pote, Raiz: real
Inicio
Escreva("Entre com o primeiro número: ")
Leia(Num1)
Escreva("Entre com o segundo número [diferente
de zero]: ")
Leia(Num2)
Escreval("")
Escreval("Adição: ")
Soma <- (Num1+Num2)
Escreval(Num1," +",Num2," = ",Soma)
Escreval("")
Escreval("Subtração: ")
Subt <- (Num1-Num2)
Escreval(Num1,"-",Num2," = ", Subt)
Escreval("")
Escreval("Multiplçicação: ")
Mult <- (Num1*Num2)
Escreval(Num1,"-",Num2," = ", Mult)
Escreval("")
Escreval("Divisão: ")
Divide <- (Num1/Num2)
Escreval(Num1, " /", Num2, " = ", Divide)
Escreval("")
Escreval("Potenciação: ")
Escreva("Entre com a base: ")
Leia(Num1)
Escreva("Entre com o expoente [diferente de zero]:")
Leia(Num2)
Pote <- (Num1^Num2)
144
Escreval(Num1, " ^", Num2, " = ", Pote)
Escreval("")
Escreval("Radiciação: ")
Escreva("Entre com o número: ")
Leia(Num1)
Escreva("Entre com índice da raiz [número positivo]:")
Leia(Num2)
Raiz <- (Num1^(1/Num2))
Escreval("Raiz índice",Num2,"de",Num1,"=", Raiz)
Escreval("")
FimAlgoritmo //fim do programa "OperacoesMatematicas"
A figura 3.5 mostra a saída do programa
“OperaçoesMatematicas”; entrando com os dados solicitados
nas respectivas operações
Figura 3.5 - Saída do programa “OperacoesMatematicas”
145
❖ Exemplo 3.3 - Dadas quatro notas parciais de um aluno,
calcular a média escolar com um número de casas desejado pelo
usuário.
O programa “MediaEscolar” , cujo código é mostrado na figura
3.6, é uma opção de solução em Visualg.
Figura 3.6 - Código-fonte do programa “MediaEscolar” no editor
A figura 3.7a mostra a saída do programa no na “janela DOS”, e
a figura 3.7b nas “Areas de Visualizações”.
146
Figura 3.7a - Saída do programa “MediaEscolar” (janela DOS)
147
Figura 3.7b - Saída de “MediaEscolar” (janelas de visualizações)
3.7 - Exercícios Propostos
1 - Para que servem os tipos de dados nos programas?
2 - Além dos três tipos básicos de dados, por que existem outros?
3 - É possível fazer cálculos com o tipo Lógico? Explique!
4 - Qual tipo de dado deve ser utilizado para armazenar um
número de telefone? Explique!
5 - O programa abaixo, em Visualg, não vai rodar. Explique o
porquê.
148
Algoritmo "DivideNumero"
//Mostra o resultado da divisão de um número por outro.
//-----------------------------------------------------
Var num, den, div: inteiro
Início
Escreva("Digite o numerador: ")
Leia(num)
Escreva("Digite o denominador: ")
Leia(den)
div <- num/den
EscrevaLn("Área do triângulo:", Area)
FimAlgoritmo
6 - Observe o trecho de programa abaixo para calcular as duas
raízes reais de uma equação do segundo grau do tipo ax2 + bx +
c = 0, e suponha que as três constantes e as raízes x1 e x2 tenham
sido declaras corretamente. As duas raízes, x1 e x2, SEMPRE
serão mostradas com seus valores corretos? Explique sua
resposta!
...
Escreva("Digite o valor da constante a: ")
Leia(a)
Escreva("Digite o valor da constante b: ")
Leia(b)
Escreva("Digite o valor da constante c: ")
Leia(c)
x1 <- (-b + RaizQ(b^2-4*a*c))/2*a
x2 <- (-b - RaizQ(b^2-4*a*c))/2*a
Escreval("Primeira raiz:: ",x1)
Escreval("Segunda raiz:: ",x2)
...
7 - Quais serão as respectivas saídas do programa
“MostraResultados”, quando for executado?
149
Algoritmo "MostraResultados"
Var A, B, C: real
Início
A <- 3
B <- 4
C <- 5
Escreval(A + B/A)
Escreval(A +(B/A))
Escreval(A > B)
Escreval(A <= B)
Escreval(A + RaizQ(B)/A*B)
Escreval(nao(A>B) e (B<=C))
Escreval(((B<=A) e (C>=B)) ou ((nao(A<=5))))
Escreval((C>=B) e (A<=B))
Escreval(nao((nao(A>B) e (C=B)) ou (A<B)))
Escreval((A<=(B<C)) e
(nao((nao(nao(nao(C<(A+C))))))))
FimPrograma
8 - Marque a única expressão INVÁLIDA em Visualg, sabendo
que A=3, B=A e C=Falso.
A ( ) C <- B > (RaizQ(B)/A*B)
B ( ) (Falso) e (B >A)
C ( ) C <- (B=A) ou (C (e (nao(A<=5)))
D ( ) C <- (A+B) - B
E ( ) C <- (B<C) e (nao((nao(nao(nao((A+B)<C)))))))
9 - Declare variáveis para armazenar: devolução do imposto de
renda de 2020, nome de um cliente, total de vendas no mês de
dezembro, resposta do usuário se confirma ou não a exclusão de
um cliente do arquivo e o total de alunos do sexo feminino de um
colégio.
150
10 - Crie um programa em Visualg que leia o nome de um aluno,
suas quatro notas parciais e mostre a média ponderada dessas
notas, sabendo que: peso da primeira nota é 2, da segunda nota é
3, da terceira nota é quatro e da quarta nota é seis.
11 - Observe o programa abaixo, em Visualg. Seu objetivo é
mostrar a velocidade final de um corpo abandonado a uma
distância H da superfície, considerando o valor da aceleração da
gravidade uma constante de valor 9,80665 m/s². Entretanto,
mesmo estando correta a expressão da queda livre, o programa
não vai rodar. Explique porque!
Algoritmo "QuedaLivre"
Var V, H, T: real
Const G=9.80665
Inicio
T <- 32,5
V = (1/2)*G*T^2
Escreval("Velocidade do corpo em 32,5 segundos: ",V)
FimAlgoritmo
12 - Marque com C os valores do tipo caractere, com I os valores
do tipo inteiro, com R as variáveis do tipo real e com L os do tipo
lógico.
A ( ) 4.66667
B ( ) “4.66667”
C ( ) -43
D ( ) Falso
E ( ) “56”
F ( ) “Boa noite”
G ( ) Verdadeiro
H ( ) 3.14128265
151
Capítulo 4 - Estruturas de Controle Visualg
4.1 - Introdução ao Capítulo
Observando a maioria dos programas mostrados até agora,
podemos notar que as instruções são executas sequencialmente,
sem desvios. É como se não houvesse nenhuma necessidade de
orientar o fluxo do programa para determinado local do
programa, tal como acontece no programa “Armazenamentos”,
que vai atribundo valores a variáveis e mostrando mostrando os
resultados de maneira sequencial.
Algoritmo "Armazenamentos"
//Exemplo simples de atribuições/armazenamentos e
//escritas.
//-----------------------------------------------------
Var A, B, C, D: inteiro
Inicio
D 0
Escreval("Valor de D: ",D)
A 2
Escreval("Valor de A: ", A)
B 3
Escreval("Valor de B: ", B)
C 5
Escreval("Valor de C: ", C)
C C + 1
Escreval("Valor de C: ",C)
D A + C
Escreval("Valor de D: ",D)
FimAlgoritmo
152
A execução do programa começa na palavra Algoritmo e vai
interpretando/executando linha por linha até o final em
FimAlgoritmo. Não há qualquer desvio do fluxo, pois não há
nenhuma decisão a ser tomada, e nem mesmo repetição de
comandos; é um programa inteiro com instruções sequenciais.
Mas, na prática, isto não acontece, pois, em situações reais
sempre aparece condições a serem analisadas e que, dependendo
da resposta, o fluxo do programa pode seguir caminhos
diferentes. Uma outra situação é quando é necessário escrever
uma instrução repetidas vezes como, por exemplo, exibir cinco
vezes a frase “Hoje vai chover”. Uma solução simples, seria:
Escreval("Hoje vai chover: ")
Escreval("Hoje vai chover: ")
Escreval("Hoje vai chover: ")
Escreval("Hoje vai chover: ")
Escreval("Hoje vai chover: ")
Embora as cinco instruções acima resolva o problema, esta não é
uma boa solução; é bem ineficiente, caso fosse repetir não cinco,
mas cinquenta, ou cinco mil vezes a mesma frase. Para resolver
problemas mais complexos do que repetir simples instruçõessequenciais, ou tomar decisões impostas pelo lógica do programa,
é que existem as chamadas “Estruturas de Controle”.
4.2 - Estruturas de Controle
Com os tipos de dados e operadores apresentados no capítulo
anterior, podemos definir um conjunto de estruturas, baseado na
lógica, que permite ao programador criar soluções bem elegantes,
utilizando instruções e comandos para solucionar o problema
apresentado. Essas estruturas definem controles que se
convencionou chamar de “comandos compostos”, e podem ser
classificados em três tipos fundamentais:
153
• Estruturas de Decisão (desvios condicionais)
• Estrutura de Seleção (estrutura Case)
• Estruturas de Repetição (loops)
Nota: A expressão “comando” aqui neste livro se refere à uma ordem
ou ação específica escrita no código para que o processador possa
executá-la. A expressão “instrução”, embora muitos autores a
empreguem no sentido de “comando”, será utilizada num sentido mais
amplo para indicar o que o processador deve fazer numa linha de código
do programa, que pode envolver vários comandos e expressões. Por
exemplo, X <- RaizQ(Num) + FunFatorial(n) + Soma/j.
✓ RaizQ é uma função interna para extrair a raiz quadrada de um
número não negativo.
✓ FunFatorial é um comando (função definida pelo usuário),
para calcular o fatorial.
✓ Soma/j é uma operação de divisão que compõe uma instrução.
A linha de código X<-RaizQ(Num) + FunFatorial(n) + Soma/j pode
ser chamada de instrução, ou comando (sem consequências graves),
mas, correto seria considerar LINHA DE CÓDIGO. Mas, existem
casos em que uma coisa se confunde, rigorosamente, com a outra: por
exemplo, a instrução LimpaTela (que também é chamada de
COMANDO, sem retorno), é por si só, uma linha de código.
Operador de Atribuição
Variável Linha de código Instruções
X <- RaizQ(Num) + FunFatorial(n) + Soma/j
Função interna Função criada pelo programador Expressão matemática
154
Muitos autores chamam uma Instrução de “Comando”; outros
chamam de “Comando” os procedimentos internos de uma
linguagem (uma função interna que não tem retorno). Por
exemplo, para límpar a tela do monitor de vídeo: ClrScr (em
Pascal), Cls (em VB), clc (em SciLab) LimpaTela (em Visualg),
etc. Todas estas palavras-chave, nas suas respectivas linguagens,
podem ser chamadas de COMANDO. Também, as palavras-
chave de leitura, tais como: Read (em Fortran), Read (em VB),
readline (em PHP), Read e ReadLn (em Pascal), input( em
Python e em SciLab), Leia (em Visualg). Para a escrita temos:
Print (Em Basic), Write e WriteLn (em Pascal), printf (em
SciLab), print (em PHP e em Python), println (em Julia),
Console.WriteLine (em VB.net) e Escreva (em Visualg).
Resumindo: TODAS as palavras-chave que indicam uma ordem
expressa e sem retorno, podem ser consideradas COMANDOS.
4.2.1 - Estruturas de Decisão
Estes tipos de estruturas de controle também são conhecidos
como “Desvios Condicionais”, provocam um desvio no fluxo
natural do programa, ao ser detectada alguma condição a ser
analisada. E podem ser divididos em três tipos:
▪ Estrutura de Decisão Simples (Desvio Condicional
Simples)
▪ Estrutura de Decisão Composto (Desvio Condicional
Composto)
▪ Estrutura de Decisão Encadeado (Desvio Condicional
Encadeado)
4.2.1.1 - Estrutura de Decisão Simples
Os comandos de desvios condicionais simples formam estruturas
de controle em que a decisão sobre a direção do fluxo do
155
programa é condicionada a apenas uma alternativa, de acordo
com o valor lógico resultante da condição analisada.
Se(condição) Entao
Linha1
Linha2
Linha3 linhas de código executadas se condição Verdadeiro
...
LinhaN
FimSe
A “Estrutura de Decisão Simples” funciona da seguinte maneira:
Quando o fluxo do programa depara com um
Se(condição)..FimSe a expressão lógica de condição é executada;
se o resultado for Verdadeiro todas as instruções entre Se e o
terminador FimSe serão executas. Caso contrário, nenhuma
dessas instruções serão executadas e o fluxo do programa seguirá
normalmente DEPOIS do terminador FimSe.
O programa “VerifPar1” a seguir, ilustra o mecanismo de
execução desse tipo de desvio condicional.
Palavras-chave que indicam início da estrutura de decisão.
Palavra-chave que indica fim da estrutura de decisão.
156
Algoritmo "VerifPar1"
Var num, rest: inteiro
Inicio
LimpaTela
Escreva("Digite um número inteiro e positivo: ")
Leia(num)
Num <- Abs(Int(num))//garante que Num seja inteiro
e não negativo
rest <- (Num Mod 2)
Se(Rest=0) Entao
Escreval("O número", Num, " é par.")
FimSe
Escreval("")
FimAlgoritmo
Num e num, Rest e rest para o Visualg é a mesma coisa, pois a
ferramenta não é case sensitive como algumas linguagens de
Programação (C, Python, SciLab, Java). O programa
“Verif”Par1” roda normalmente; e um exemplo de saída pode
ser visto na figura 4.1a.
157
Figura 4.1a -Um exemplo de saída do programa “VerifPar1”
Observe que o programa “VerifPar1” atende ao que foi proposto:
verificar se um dado número digitado é par. Então, se o número
digitado for par uma mensagem será exibida ao usuário
esclarecendo; ENTRETANTO, embora atenda ao proposto, ele
não atende BEM, pois, se o número não for par nada será
informado ao usuário. Isto deixa meio “capenga” a lógica da
programação, como pode ser comprovado na figura 4.1b.
158
Figura 4.1b - Outro exemplo de saída do programa “VerifPar1”
4.2.1.2 - Estrutura de Decisão Composta
No item anterior, o programa “VerifPar1”, embora esteja
perfeitamente correto (mostra a mensagem quando o número
digitado é par), não é completamente eficaz, pois caso o número
digitado não seja par (como no caso da figura 4.1b), nenhuma
mensagem é mostrada, e o usuário não fica inteiramente satisfeito
com o seu desempenho. Assim, para tornar uma estrutura de
decisão mais eficiente e eficaz, complementando a informação
em outras situações, é que existe a “Estrutura de Decisão
Composta”, que oferece a alternativa de código para quando a
condição testada resultar num valor falso. Neste caso temos duas
alternativas, sendo uma delas obrigatória.
159
A sintaxe deste tipo de estrutura é mostrada no esquema a seguir...
condição Verdadeiro ?
Se(condição) Entao
Linha11
Linha12 sim
Linha13 executa estas instruções
...
Linha1N
Senao
Linha21
Linha22 não
Linha23 executa estas instruções
...
LinhaN
FimSe
Então, agora, reutilizando o programa “VerifPar1”, introduzindo
a estrutura de “Desvio Condicional Composto”, e renomeando-o
para “VerifPar2”, ficando do seguinte modo:
160
Algoritmo "VerifPar2"
Var num, rest: inteiro
Inicio
LimpaTela
Escreva("Digite um número inteiro e positivo:")
Leia(num)
Num <- Abs(Int(num
rest <- (Num Mod 2)
Se(Rest=0) Entao
Escreval("O número", Num, " é par.")
Senao
Escreval("O número", Num, " não é par.")
FimSe
Escreval("")
FimAlgoritmo
Agora, com a alternativa de instruções para condição Falso, o
programa ficou muito mais interativo com o usuário, oferendo
duas possíveis respostas para a análise do número digitado.
Nota: Algumas linguagens de programação oferecem um terceiro tipo
de Estrutura de Decisão, que muitas vezes é chamado de “Estrutura de
Decisão Encadeada”, do tipo:
Se(condição) Então
Senão Se(condição1) Então
...
Senão Se(condição2) Então
...
FimSe
O Visualg ainda não oferece esse tipo de estrutura, mas ele pode ser
simulado com a utilização de vários Se(condição)... aninhados.
161
Observe, agora, na figura 4.2, com o emprego da “Estrutura de
Decisão Composta”, como fica a saída do programa, alterado, e
compare com a saída da figura 4.1b.
Figura 4.2 - Exemplo de saída do programa “VerifPar2”
Observe o código do Exemplo 4.1 abaixo, que calcula a média
final de um aluno, em que a “Estrutura de Decisão Encadeada”
foi simulada no Visualg.
❖ Exemplo 4.1 - Calcular a média de um aluno em função de
quatro notas parciais, e do exame (se for necessário).
O programa “CalculaMediaFinal” é uma solução para o que se
pede no Exemplo 4.1, observando, nesta solução, que temos uma
“Estrutura de Decisão Composta”, aninhada (dentro) de uma
outra mais externa. Esse tipo de situação é bastante comum,
quando se tem condições a serem testadas dentro de outra
condição mais externa. Note que embora não possua,
explicitamente, comandos compostos para estruturas de decisão
162
encadeada, os comandos Se(condição)..Entao..Senao podem ser
agrupados para fazer uma simulação perfeita nessas situações.
Algoritmo "CalculaMediaFinal"
//Calcula a média de quatro notas, com “Estruturas de
//de Decisões” aninhadas.
//Encadeada”.
//Autor: Mário Leite
//-----------------------------------------------------
Var Nota1,Nota2,Nota3,Nota4: real
Soma, Media, Exame: real
Inicio
Escreva("Digite a primeira nota: ")
Leia(Nota1)
Escreva("Digite a segunda nota: ")
Leia(Nota2)
Escreva("Digite a terceira nota: ")
Leia(Nota3)
Escreva("Digite a quarta nota: ")
Leia(Nota4)
Soma Nota1 + Nota2 + Nota3 + Nota4
Media Soma/4
Escreval("Média: ", Media)
Escreval("") //salta linha
Se(Media>=7.0) Entao
Escreval("Aprovado")
Senao
Escreva("Digite a nota do exame: ")
Leia(Exame)
Media (Media*4 + Exame*6)/10
Escreval("Média final: ", Media)
Se(Media>=6.0) Entao
Escreval("Aprovado")
Senao
Escreval("Reprovado")
FimSe
FimSe
FimAlgoritmo
163
4.2.2 - Estrutura de Decisão Selecionada
Esta estrutura, também conhecido simplesmente como “Estrutura
de Seleção”, “Desvio Selecionado” ou ainda “Estrutura Case”, é
utilizada para desviar o fluxo de um programa no qual são
oferecidos várias condições representadas por casos, comparados
a um valor previamente conhecido, onde para cada Caso existe
um bloco de instruções a ser executado, dependendo da
comparação ser Verdadeiro. A sintaxe textual para esse tipo de
estrutura é mostrada no esquema abaixo.
Escolha(variável/expressão)
Caso1
Linha11
Linha12
...
Linha1N
Caso2
Linha21
Linha22
...
Instrução2N
---
---
CasoN
LinhaN1
LinhaN2
LinhaN3
...
LinhaNM
OutroCaso
LinhaA
LinhaB
...
LinhaZ
FimEscolha
164
Escolha(variável/expressão): marco de início da estrutura.
Caso´s: valores que serão comparados com (variável/expressão).
OutroCaso: início do bloco de instruções a sere executado se
nenhum Caso anterior for Verdadeiro.
FimEscolha: marco de término da estrutura.
(variável/expressão) é um valor qualquer, previamente
conhecido, que será comparado com valores estabelecidos em
cada “Caso”.
O processamento começa lendo (variável/expressão); em seguida
compara o seu conteúdo com cada valor definido nos “casos”. No
primeiro caso que for verdadeiro seu bloco de instruções será
executado, e em seguida o fluxo continuará após o marco
FimEscolha. Se nenhum dos casos for verdadeiro então serão
executadas as instruções entre OutroCaso e FimEscolha; por
isto, neste tipo de estrutura este último bloco alternativo pode se
tornar vital para a lógica do programa. Esta estrutura deve ser
empregada em situações em que o usuário precisa escolher uma
alternativa de execução quando são oferecidas várias alternativas
como, por exemplo, em um menu de opções de ações, como no
caso do famoso e tradicional CRUD: : “1-Incluir”, “2-Alterar”,
“3-Excluir”, “4-Pesquisar”, “5-Finalizar”.
❖ Exemplo 4.2 - Definir o status de um aluno em função de n
notas parciais obtidas.
165
Algoritmo "StatusAluno1"
//Define a situação acadêmica de um aluno, em função da
//média final obtida.
//Autor: Mário Leite
//-----------------------------------------------------
Var j, n: inteiro
Nota, Soma, Media, Exame: real
Inicio
Repita
Escreva("Número de notas[min 2-max 10]" :")
Leia(n)
Ate((n>=2) e (n<=10))
Escreval("")
Soma <- 0.00 //inicializa o somatório das notas
Para j De 1 Ate n Faca //loop numérico para ler
Repita //valida cada nota digitada
Escreva("Digite a nota #",j,": ")
Leia(Nota)
Ate((Nota>=0)e(Nota<=10)) //fim das validações
Soma <- Soma + Nota //acumula soma das notas
FimPara //fim do loop de leitura das notas
Media <- Soma/n //calcula a média
Escolha Media
Caso 3.0 Ate 5.0
Escreval("Conselho de Classe")
Caso 5.1 Ate 6.9
Escreval("Em Exame")
Caso 7.0 Ate 10.0
Escreval("Aprovado")
OutroCaso
Escreval("Reprovado")
FimEscolha
FimAlgoritmo //fim do programa "StatusAluno1"
166
O trecho do programa a seguir, mostra como funciona a
“Estrutura De Seleção”.
Leia(Letra) //tipo caractere
Escolha Letra
Caso "A"
Escreval("Esta é a opção da letra A")
Caso "B"
Escreval("Esta é a opção da letra B")
Caso "C"
Escreval("Esta é a opção da letra C")
Caso "D"
Escreval("Esta é a opção da letra D")
Caso "E"
Escreval("Esta é a opção da letra E")
OutroCaso
Escreval("Esta é a opção de nenhuma vogal")
FimEscolha
Também é possível variações em caso de múltiplas escolhas, em
situações de Casos com mais de um valor dentro da opção: Caso
V1 Ate V2, como é mostrado no trecho de programa a seguir...
167
...
Escreva("Digite uma nota do aluno de 1 à 10: ")
Leia(x) //tipo real
Escolha x
Caso 3.0 Ate 5.0
Escreval("Nota está Ruim.")
Caso 5.1 Ate 6.5
Escreval("Nota Satisfatório.")
Caso 6.6 Ate 8.5
Escreval("Nota Boa.")
Caso 8.6 a 10.0
Escreval("Nota Ótima.")
OutroCaso
Escreval("Nota fora da faixa ou valor inválido! ")
FimEscolha
Escreva("Digite uma letra correspondente a vogal: ")
Leia(Letra) //tipo caractere
Escolha Letra
Caso "A","B"
Escreval("Esta é a opção da letra A ou B.")
Caso "C","D"
Escreval("Esta é a opção da letra C ou D.")
Caso "E"
Escreval("Esta é a opção da letra E.")
OutroCaso
Escreval("Esta é a opção de nenhuma vogal")
FimEscolha
...
4.2.3 - Estruturas de Repetição (loops)
Estas estruturas oferecem comando para controlar os laços
(loops) de repetições de blocos de instruções. Neste caso, o bloco
168
de instruções será continuamente executado até que (ou
enquanto) uma condição seja atendida. Elas podem ser
classificadas em dois grupos, dependendo do tipo de condição a
ser testada:
▪ Loops Lógicos
▪ Loop Numérico
4.2.3.1 - Loop Lógico Com Teste no Início
Este é o tipo de loop lógico mais empregado nos programas, por
ser bem intuitivo. O esquema abaixo mostra a sua sintaxe.
{Inicializações}
Palavra-chave que indica início da estrutura
Enquanto (condição) Faca
Linha1
Linha2
Linha3
...
...
LinhaN
FimEnquanto Palavra-chave que indica fim da estrutura
Instruções a serem executadas enquanto condição
for Verdadeira
169
Nota: {Inicializações}, embora não faça parte da sintaxe da estrutura,
é um bloco de linhas de código que deve anteceder a entrada do fluxo
do programa na estrutura de repetição. E nesse bloco TEM que existir
alguma linha de código que envolva a condição, de modo que a torne
Verdadeiro, para que oprograma possa “entrar” no loop. Se, por caso,
condição já for Falso no bloco de instruções o programa desviará e não
executará as linhas de código do loop. Então, é NECESSÁRIO que
condição seja Verdadeiro, previamente, para que o loop seja executado,
pelo menos uma vez. Outro detalhe FUNDAMENTAL, é que deve
existir alguma linha de código dentro das executadas no loop que o
incremente, para que em algum momento condição se torne Falso;
nesse instante o laço é rompido e o fluxo do programa volta ao seu
percurso normal, na primeira linha de código APÓS o terminador
FimEnquanto. Portanto, esse tipo de loop lógico depende diretamente
de duas premissas: uma linha de código para inicializar condição
com valor Verdadeiro e uma outra para realimentar o loop, de modo
que condição se torne Falso em algum momento. Se a primeira
premissa não for atendida o loop não será executado; se a segunda
premissa não existir, as linhas de código dentro da estrutura serão
executadas indefinidamente, produzindo um loop “infinito” (eterno).
Ao ler o comando Enquanto(condição) o programa executará
todas as linhas de código dentro da estrutura, enquanto condição
for Verdadeiro. No momento em que condição de tornar Falso
o fluxo seguirá normalmente após o terminador FimEnquanto.
Os dois casos a seguir ilustram três situações de uso da estrutura
Enquanto(condição)..Faca..FimEnquanto;. a primeira sem a
170
devida inicialização de condição, a segunda sem a realimentação
do loop e a terceira com a sintaxe correta.
❖ Exemplo 4.3 - Somar os números digitados pelo teclado,
enquanto não digitar 0.
Algoritmo "SomaNumerosDigitados"
//Soma os números digitados pelo teclado, enquanto não
digitar 0 (zero).
//Autor: Mário Leite
//-----------------------------------------------------
Var Num, Soma: real
Cont: inteiro
Inicio
LimpaTela
Cont <- 0
Soma <- 0
Enquanto (Num<>0) Faca
Escreva("Digite um número [zero encerra]: ")
Leia(Num)
Soma <- Soma + Num
Cont <- Cont + 1
Escreva("Soma parcial: ", Soma)
Escreval("")
FimEnquanto
Escreval("")
Escreval("")
Escreval("Soma total dos",(Cont-1)," números
válidos digitados:", Soma)
FimAlgoritmo
Primeira versão da solução: Sem a devida inicialização da condição
Aqui a variável Num deveria ser inicializada
com um valor diferente de zero.
171
A figura 4.3a mostra a saída do programa
“SomaNumerosDigitados" considerando-o sem a linha de
código de inicialização Verdadeira para a condição (Num<>0).
Note que, por isto, o loop não foi executado, e o resultado saiu
errado!
Figura 4.3a - Saída da primeira versão do programa: SEM a inicialização
da condição
172
Algoritmo "SomaNumerosDigitados"
//Soma os números digitados pelo teclado, enquanto
não digitar N (zero).
//Autor: Mário Leite
//-----------------------------------------------
---------------------------
Var Num, Soma: real
Cont: inteiro
Inicio
LimpaTela
Cont <- 0
Soma <- 0
Num <- 999 //inicializa convenientemente a
variável de controle do loop
Enquanto (Num<>0) Faca
Soma <- Soma + Num
Cont <- Cont + 1
Escreva("Soma parcial: ", Soma)
Escreval("")
FimEnquanto
Escreval("")
Escreval("")
Escreval("Soma total dos", (Cont-1)," números
válidos digitados:", Soma)
FimAlgoritmo
Segunda versão da solução: SEM realimentação do loop
Nesta segunda versão NÃO FOI considerada a realimentação do
loop; e neste caso o programa fica rodando sem parar (em loop
eterno), não produzindo uma saída definitiva pois, as linhas de
código dentro do loop ficam sendo executadas continuamente,
sem parar. A figura 4.3b mostra que o valor da variável Soma
ficará eternamente sendo calculado...
Aqui deveria uma linha de código
para realimentar o loop.
173
Figura 4.3b - Saída da Segunda versão do programa: SEM a
realimentação do loop
174
Algoritmo "SomaNumerosDigitados"
//Soma os números digitados pelo teclado, enquanto não
digitar 0 (zero).
//Autor: Mário Leite
//-----------------------------------------------------
Var Num, Soma: real
Cont: inteiro
Inicio
LimpaTela
Cont <- 0
Soma <- 0
Num <- 999
Enquanto (Num<>0) Faca
Escreva("Digite um número [zero encerra]: ")
Leia(Num)
Soma <- Soma + Num
Cont <- Cont + 1 //realimentação do loop
Escreva("Soma parcial: ", Soma)
Escreval(“”)
FimEnquanto
Escreval("")
Escreval("")
Escreval("Soma total dos",(Cont-1)," números válidos
digitados: ",Soma)
FimAlgoritmo
Terceira versão: correta; COM a inicialização da condição e COM a
realimentação do loop
A figura 4.3c mostra a saída correta do programa
"SomaNumerosDigitados".
175
Figura 4.3c - Saída da versão Correta do programa: COM inicialização e
COM realimentação
4.2.3.2 - Loop Lógico com Teste no Final
Este é o segundo exemplo de loop lógico; isto é, uma estrutura de
repetição em que uma instrução lógica (condição) deve ser
testada para que o loop se desenvolva. Mas, ao contrário do loop
“Enquanto..Faça..FimEnquanto” que pode não ser executado
nenhuma vez, este é executado sempre pelo menos uma vez. Isto
acontece porque o teste da condição fica no final do loop, e não
no início, como naquele. Este tipo é muito utilizado quando se
quer validar alguma entrada de dados; por exemplo, impedir que
o usuário entre com um número negativo para calcular seu
fatorial. O loop se repete ATÉ que a entrada seja um número
176
maior ou igual a zero. Sua sintaxe esquemática é mostrada
abaixo:
Indica início da estrutura
Repita
Linha1
Linha1
Linha3
...
...
LinhaN
Ate(condição)
❖ Exemplo 4.4 - Calcular a soma dos N primeiros números
naturais.
Terminador da estrutura.
Condição a ser testada. estrutura.
Linhas de código que serão executadas até que condição
seja Verdadeiro.
177
Algoritmo "CalculaSomaNaturais1"
//Calcula a fatorial de um número, fazendo validação.
//Autor: Mário Leite
//-----------------------------------------------------
Var j, N, Soma: inteiro
Inicio
Escreva("Quantos números naturais serão
somados?: ")
Leia(N)
Repita
Escreva("Quantos números naturais serão
somados?: ")
Leia(N)
Escreval("")
Ate(N>1)
Soma <- 0
j <- 1
Enquanto (j<=N) Faca
Soma <- Soma + j
j <- j + 1
FimEnquanto
Escreval("")
Escreval("Soma dos", N, " primeiros números
naturais: ",Soma)
FimAlgoritmo
A figura 4.4 mostra uma ´possível saída do programa
"CalculaSomaNaturais1"
178
Figura 4.4 - Saída do programa "CalculaSomaNaturais1"
Nota: É importante frisar que os testes da expressão que analisa a
condição nos dois tipos de loop lógico são expressões que se
equivalem logicamente em termos de teste da condição.
Enquanto(x<=y) <==> Ate(x>y)
O programa "CalculaSomaNaturais2" tem o mesmo propósito
que o anterior: calcular e mostrar a soma dos N primeiros
números naturais. Entretanto, neste caso, foi utilizada a estrutura
de repetição Enquanto..Faca..FimEnquanto para fazer a
validação da entrada.
179
Algoritmo "CalculaSomaNaturais2"
//Calcula a fatorial de um número, fazendo validação.
//Autor: Mário Leite
//-----------------------------------------------------
Var j, N, Soma: inteiro
Inicio
N <- -999 //inicialização conveniente para entrar no loop
Enquanto (N<=1) Faca
Escreva("Quantos números naturaisserão
somados?: ")
Leia(N)
Escreval("")
FimEnquanto
Soma <- 0
j <- 1
Enquanto (j<=N) Faca
Soma <- Soma + j
j <- j + 1
FimEnquanto
Escreval("")
Escreval("Soma dos", n, " primeiros números
naturais: ",Soma)
FimAlgoritmo
4.2.3.3 - Loop Numérico
Este loop é de um tipo não lógico; e muitas vezes, também é
chamado de “Loop Automático” pois, ele inicializa e incrementa
a variável do tipo inteiro que o controla, automaticamente. Este é
o tipo de loop mais indicado quando se deseja repetir um bloco
de linhas de código, sabendo a priori, quantas vezes a repetição
será executada; isto é, se for conhecido o valor inicial e o valor
final da variável de controle. Neste caso as repetições acontecerão
até atingir o número de vezes previamente definido na própria
estrutura; a sintaxe textual é mostrada no esquema a seguir...
180
{Inicializações}
Para VarCont De Início Ate Fim [Passo <p>] Faca
Linha1
Linha2
Linha3
...
LinhaN
FimPara
VarCont É a variável de controle do loop, que por tradição
são utilizadas as letras minúsculas i, j, k, l, m, n.
Início Valor inicial inteiro assumido por VarCont.
p Valor inteiro do incremento da variável de
controle. Se p não for definido é assumido o
padrão 1; mas neste caso a palavra-chave Passo
não pode aparecer.
Fim Valor máximo inteiro que a variável de controle
pode assumir.
A respeito deste tipo de loop, é MUITO IMPORTANTE observar
o seguinte:
✓ NÃO EXISTE instrução de realimentação; a
realimentação é 1 ou dada por Passo p. Também NÃO
EXISTE uma instrução específica para inicializar a
variável de controle no bloco de {Inicializações} como
havia nas duas estruturas anteriores. A inicialização da
variável de controle do loop é estabelecida na própria
estrutura, e é sempre um valor numérico inteiro.
Bloco de instruções a ser
repetido.
181
✓ NÃO PODE ser atribuído nenhum valor à variável de
controle (VarCont) dentro do loop, pois seu valor só deve
ser alterado pela própria estrutura.
✓ É permitido criar um loop dentro de outro; este caso define
os chamados loops aninhados, e todas as instruções do
laço mais interno são integralmente executadas
prioritariamente para cada valor da variável de controle do
laço mais externo.
❖ Exemplo 4.5 - Contar de 1 até 100, de 2 em 2.
Para Cont De 1 Ate 100 Passo 2 Faca //contará valores
de 1 à 100 de 2 em 2
Escreval(Cont) //mostra conteúdo de Cont em cada linha
FimPara
❖ Exemplo 4.6 - Contar o número de tipos de caracteres que
existe em uma frase.
Algoritmo "ContaCaracteresNaFrase"
//Conta os caracteres de uma frase: letras (maiúsculas
//minúsculas), espaços,números e caracteres especiais.
//-----------------------------------------------------
Var j,n,ContMai,ContMin,ContEspa: inteiro
ContNum,ContEspe,CodCar: inteiro
Frase, Car: caractere
Cond1, Cond2, Cond3, Cond4: logico
Inicio
Escreva("Digite a frase: ")
Leia(Frase)
n <- Compr(frase)
ContMai <- 0
ContMin <- 0
ContEspa <- 0
ContNum <- 0
182
ContEspe <- 0
Para j De 1 Ate n Faca
Car <- Copia(Frase,j,1) //pega um caractere
CodCar <- Asc(Car)
Cond1 <- ((CodCar>=65) e (CodCar<=90))
Cond2 <- ((CodCar>=97) e (CodCar<=122))
Cond3 <- (CodCar=32) //espaço em branco
Cond4 <- ((CodCar>=48) e (CodCar<=57))
Se(Cond1) Entao
ContMai <- ContMai + 1
Senao
Se(Cond2) Entao
ContMin <- ContMin + 1
Senao
Se(Cond3) Entao
ContEspa <- ContEspa + 1
Senao
Se(Cond4) Entao
ContNum <- ContNum + 1
Senao
ContEspe <- ContEspe + 1
FimSe
FimSe
FimSe
FimSe
FimPara
Escreval("Resumo dos caracteres encontrados:")
Escreval("----------------------------------")
Escreval("Número de letras maiúsculas: ", ContMai)
Escreval("Número de letras minúsculas: ", ContMin)
Escreval("Número de espaços encontrados: ", ContEspa)
Escreval("Número de dígitos numéricos: ", ContNum)
Escreval("Número de caracteres especiais: ", ContEspe)
Escreval("Número total de caracteres da frase: ", n)
Escreval("")
FimAlgoritmo//fim do programa "ContaCaracteresNaFrase"
183
Nota: Observe no programa “ContaCaracteresNaFrase”, que se não
fossem aplicadas as devidas indentações no bloco de “{Verificação do
tipo de caractere da frase}”, seria muito difícil entender a lógica da
programação para fazer o que se pede.
Portanto, em TODOS os locais onde existem estruturas de controle
(seja ela do tipo que for) as INDENTAÇÕES devem ser colocadas, e
o espaço em cada uma delas deve ser 3 ou 4; nem menos e nem mais,
para não ficar pequena e nem grande demais!.
A figura 4.5 mostra um exemplo de saída do programa
"ContaCaracteresNaFrase".
Figura 4.5 - Saída da execução do programa "ContaCaracteresNaFrase"
184
4.3 - Aninhamento de Decisões Usando Se's
Esta é uma das técnicas de programação muito adotada pela
maioria dos usuários nos algoritmos, e recomendada pelos
professores, pois os alunos ficam mais “afiados” na lógica. E,
embora o emprego intenso de vários comandos Se..Entao usando
o desvio SIMPLES junto com o desvio COMPOSTO, possa
exigir um esforço computacional adicional, esta técnica ajuda
muito na compreensão da lógica dentro de programas mais
complexos. Observe o exemplo abaixo, onde existem vário
desvios condicionais dentro de um mais externo, para escrever a
situação acadêmica final de um aluno, em função da média de n
notas parciais ou, se precisar da nota de um exame final.
❖ Exemplo 4.7 - Mostrar a situação acadêmica final de um
aluno, em função de notas parciais e/ou do Exame final.
O programa "StatusAluno2" é uma solução para o problema do
Exemplo 4.7, mostrando o status acadêmico de um aluno, após
calcular sua média de quatro notas parcial e verificar se ele vai
necessitar de fazer o Exame Final para ser aprovado.
Algoritmo "StatusAluno2"
//Dá o status de um aluno em função da média/exame.
//-----------------------------------------------
Var Nota, Soma, Media, Exame: real
j: inteiro
Inicio
Soma <- 0.0
Para j De 1 Ate 4 Faca
Repita
Escreva("Entre com a nota ", j, ": ")
Leia(Nota)
Ate(Nota>=0) e (Nota<=10))
Soma <- Soma + Nota
185
FimPara
Escreval("") //salta linha
Media <- Soma/4
Se(Media>=7.0) Entao //aprovado direto
Escreval("Aprovado direto: ", Media)
Senao //tem que fazer exame
Repita
Escreva("Entre com a nota do Exame: ")
Leia(Exame)
Ate((Exame>=0) e (Exame<=10))
FimSe
Media <- (Media+Exame)/2
Se(Media>=5) Entao
Escreval("Aprovado por exame: ", Media)
Senao
Escreval("Reprovado: ", Media)
FimSe
Escreval("")
FimAlgoritmo
4.4 - Indentações
Um programa de computador, seja ele codificado em qualquer
linguagem, é um texto puro; porém, não deve ser escrito tal como
um poema, ou um artigo sobre um assunto científico, ou mesmo
como uma carta comercial ou pessoal. O texto do código-fonte é
composto de ordens dadas ao tradutor para que ele as converta em
linguagem de máquina. E embora ao tradutor não interesse como
ele está escrito, pois o que interessa é a sintaxe correta, o
programador deve se preocupar em manter o texto elegante e bem
legível.
Indentações são espaços - de dois a quatro - que o programador
deve colocar para evidenciar as instruções sujeitas a uma
estrutura; seja ela de decisão, seleção ou repetição. No caso de
“Estruturade Decisão”, observe o trecho de programa abaixo.
186
Leia(a)
Leia(b)
Se(b<>0) Entao
c a/b
Escreval(a,"dividido por ",b,"=", c)
Senao
Escreval("Operaçãoimpossível!")
FimSe
Indentações
Observe o código-fonte do programa “MostraMedia” a seguir;
ele está correto mas sem indentações, além de faltar mensagens
esclarecedoras nas entradas; isto o torna meio confuso, com
legibilidade muito ruim e sem a devida interação com o usuário.
Algoritmo "MostraMedia"
Var Nota1,Nota2,Nota3,Nota4,Soma,Media: real
Inicio
Leia(Nota1)
Leia(Nota2)
Leia(Nota3)
Leia(Nota4)
Soma <- (Nota1 + Nota2 + Nota3 + Nota4)
Media <- Soma/4
Escreval("Média das notas: ", Media)
Se(Media<7) Entao
EscrevaLn("Reprovado")
Senao
Escreval("Aprovado")
FimSe
FimAlgoritmo
187
O programa “Loops” abaixo está correto, mas sua legibilidade é
simplesmente terrível!
Algoritmo "Loops"
//Programa sem indentação
//-------------------------------------
Var i,j,k,l,x,y: inteiro
Inicio
Escreva("Digite um valor para y: ")
Leia(y)
Para i De 1 Ate 10 Faca
x <- y
Para j De 1 Ate 20 Faca
Para k De 1 Ate 30 Faca
Para l De 1 Ate 40 Faca
x <- x + 1
FimPara
FimPara
FimPara
FimPara
FimAlgoritmo
Pergunta: Quantas vezes a instrução x x+1 será executada? A
análise é bem difícil sem as indentações necessárias.
4.5 - Exercícios Propostos
1 - Para que servem os loops?
2 - Qual é a diferença fundamental entre um loop com teste no
início e um loop com teste no final?
3 - Mostre uma vantagem e uma desvantagem de um loop lógico
quando comparado com um loop numérico.
4 - Mostre um laço com um erro de lógica, e a consequência desse
erro.
188
5 - Crie um programa que calcule as raízes quadradas de dez
números digitados pelo usuário.
6 - Repetir o que foi pedido no exercício anterior, agora, porém,
deixando o usuário digitar a quantidade de números desejada.
7 - Crie um programa para verificar se um caractere digitado é
uma letra.
8 - Deseja-se criar um programa em que seja exigido declarar:
variáveis, constantes e registros. Mostre como seriam colocadas
essas declarações num programa em Visualg.
9 - Qual valor de Soma será mostrado no programa abaixo?
Explique a resposta.
Algoritmo "CalculaSoma"
Var j, Soma: inteiro
Inicio
Soma <- 0
j <- 1
Enquanto (j>1) Faca
Soma <- Soma + j
Escreval(Soma)
j <- j + 1
FimEnquanto
Escreval("")
Escreval("Valor da soma: ",Soma)
FimAlgoritmo
10 - Quantas vezes a variável k será exibida ao executar o
programa "MostraVezes"?
189
Algoritmo "MostraVezes"
Var k, Soma: inteiro
Inicio
Soma <- 0
k <- 0
Enquanto (Soma < 0) Faca
Escreval(k)
Soma <- Soma + 2
FimEnquanto
Escreval("")
FimAlgoritmo
A ( ) 0
B ( ) 1
C ( ) 2
D ( ) 3
E ( ) 4
11 - O programa “CalculaIMC”, abaixo, tem um erro. Qual?
Algoritmo "CalculaIMC"
//Calcula o IMC (Indice de Massa Corpórea) de um adulto
//Autor: Mário Leite
//-------------------------------------------------------
Const IMC=10
Var Peso, Altura: real
Inicio
Escreva("Digite o peso: ")
Leia(Peso)
Enquanto (Peso<=36) Faca //arbitra um peso mínimo
para uma pessoa adulta
Escreva("Digite o peso [mínimo 36]: ")
Leia(Peso)
Escreval("")
FimEnquanto
Escreva("Digite a altura: ")
190
Leia(Altura)
Enquanto ((Altura<1.30) e (Altura>2.60)) Faca
Escreva("Digite a altura: ")
Leia(Altura)
Escreval("")
FimEnquanto
IMC <- Peso/(Altura^2)
Se(IMC<=16) Entao
Escreval("Magreza grave")
FimSe
Se((IMC>16) e (IMC<=17)) Entao
Escreval("Magreza moderada")
FimSe
Se((IMC>17) e (IMC<=18.5)) Entao
Escreval("Magreza leve")
FimSe
Se((IMC>18.5) e (IMC<=25)) Entao
Escreval("Saudável")
FimSe
Se((IMC>25) e (IMC<=30)) Entao
Escreval("Sobrepeso")
FimSe
Se((IMC>30) e (IMC<=35)) Entao
Escreval("Obesidade leve")
FimSe
Se((IMC>35) e (IMC<=40)) Entao
Escreval("Obesidade severa")
FimSe
Se(IMC>40) Entao
Escreval ("Obesidade mórbida")
FimSe
Escreval("")
FimAlgoritmo //fim do programa "CalculaIMC"
12 - Pelo Teorema de Euler[11] sobre os poliedros convexos com
V vértices, A arestas e F faces, vale a seguinte relação: V-A+F=2.
O programa “VerifPoliedro” verifica qual poliedro em questão
191
e quantas faces ele possui. Mas falta linhas de código no
programa para que ele fique mais correto. Quais linhas de código
você adicionaria?
Algoritmo "VerifPoliedro"
//Verifica qual poliedro está sendo considerado e mostra
sua quantidade de //faces.
//Autor: Mário Leite
//-----------------------------------------------------
Var V, A, F: real
Resp: logico
Inicio
Escreva("Digite o número de vértices do poliedro
[4-6-8-12-20]: ")
Leia(V)
Escreval("") //salta linha
Escreva("Digite o número de arestas do poliedro
[6-12-30]: ")
Leia(A)
Escreval("")
Resp Falso
F 2 + A - V
Se((V=4) e (A=6)) Entao
Escreval("Tetraedro:", F, " faces")
Escreval("Forma face: Triângulo")
Resp Verdadeiro
Senao
Se((V=8) e (A=12)) Entao
Escreval("Hexaedro:", F, " faces")
Escreval("Forma face: Quadrado")
Resp Verdadeiro
FimSe
Se((V=6) e (A=12)) Entao
Escreval("Octaedro:", F, " faces")
Escreval("Forma face: Triângulo")
Resp Verdadeiro
FimSe
Se((V=20) e (A=30)) Entao
Escreval("Dodecaedro:", F, " faces")
Escreval("Forma face: Pentágono")
192
Resp Verdadeiro
FimSe
Se((V=12) e (A=30)) Entao
Escreval("Icosaedro:", F, " faces")
Escreval("Forma face: Triângulo")
Resp Verdadeiro
FimSe
FimSe
FimAlgoritmo //fim do programa "VerifPoliedro"
193
Capítulo 5 -Trabalhando com Vetores
5.1 - Introdução ao Capítulo
Os vetores são muito importantes no ensino de Programação, uma
vez que podem servir, até, como uma introdução a assuntos mais
complexos de Estrutura de Dados. Além disto, é um assunto que
sempre ajuda o programador a resolver problemas que envolvem
dados indexados, permitindo criar soluções mais eficientes e mais
eficazes, estendendo o conceito de variáveis. Neste capítulo os
vetores são apresentados de maneira bem simples e com bastante
exemplos de aplicações práticas em programas com o Visualg.
5.2 - Conceitos Básicos
Nos capítulos anteriores os armazenamentos, manipulações e
acesso aos endereços de memória foram todos baseados,
exclusivamente, com variáveis simples. Isto é, variáveis que só
podem armazenar um único valor em cada momento específico;
pois esse tipo de variável não pode armazenar mais de um valor
ao mesmo tempo.
Neste capítulo será estudada uma classe de variáveis que podem
manipular muitos valores ao mesmo tempo, com a definição dos
chamados Vetores[14] que, na prática ,pode ser considerado uma
“lista de valores ordenados e de um mesmo tipo de dado”.
Os vetores representam uma classe especial de variáveis que,
tendo apenas uma referência nn memória, podem armazenar e
manipular muitos valores de um mesmo tipo de dado. Esta classe,
de um modo mais geral, é chamada de array e também conhecida
como matriz, variável composta, variável subscrita ou indexada,
e define uma estrutura homogênea; isto é, os valores manipulados
194
por esse tipo de variável devem ser TODOS de um mesmo tipo
de dado. A utilização de vetores em programação faz-se
necessário quando é preciso manipular muitos valores de mesma
origem, evitandotrabalhar com muitas variáveis. Por exemplo,
numa situação típica de controle escolar, em que se deva verificar
a situação acadêmica de um aluno em função de quatro notas que
ele obteve ao longo de quatro meses. Caso fosse utilizar apenas
variáveis simples, seria necessário criar quatro variáveis
diferentes para que cada uma delas armazenasse uma nota
diferente. Além disto, poderia ser necessário criar mais duas
variáveis extras: uma para armazenar a soma das quatro notas e
uma outra para armazenar a média das notas. Com a utilização de
vetores, para armazenar e manipular as quatro notas parciais seria
necessário criar apenas uma variável. E, embora na prática da
programação, seja usual ainda, criar uma variável para guardar a
soma dessas notas e uma outra para a média. seria possível usar o
próprio vetor para armazenar, também, essas outras duas
variáveis extras. O que significa que com apenas UMA variável
seria possível controlar as notas, a soma e a média dessas notas!
Portanto, todas as vezes que se deseja manipular valores de uma
mesma origem (espécie) o uso de vetores torna a programação
bem mais eficiente. A figura 5.1a mostra um esquema ilustrativo
de um vetor que controla oito notas em Física de um aluno.
Figura 5.1a - Vetor de notas de um aluno
Fisica
Nota1 Nota2 Nota3 Nota4 Nota5 Nota6 Nota7 Nota8
Física[1] Física[2] Física[3] Física[4] Física[5] Física[6] Física[7] Física[8]
195
O esquema da figura 5.1b mostra, mais detalhadamente, o que
significa cada nota do aluno em termos vetoriais, supondo Fisica
o nome do vetor, e como ficariam as oito notas obtidas com os
seguintes valores: 7.2, 7.4, 7.0, 6.9, 7.1, 6.8, 7.3 e 7.5,
respectivamente.
Figura 5.1b - Elementos do vetor Fisica[ ]
Suponha que o aluno peça vista da prova, e na correção o
professor descobre que cometeu um erro de 0.1 ao somar os
pontos obtidos nas questões: a quarta nota seja 7.0 em vez de 6.9
como havia publicado. Assim, o novo valor (7.0) deverá ser
atribuído à quarta nota do aluno. A figura 5.2 mostra o esquema
de como isto seria feito, indicando os itens que compõem o vetor
Fisica[ ] no ambiente do Visualg.
196
elemento: lê-se assim “Fisica de 4”
Fisica[4] 7.0 atribuição do novo valor ao elemento
nome do vetor: Fisica
índice do elemento: 4
Figura 5.2 - Itens de um elemento de vetor
Fisica = [ 7.2, 7.4, 7.0, 7.0, 7.1, 6.8, 7.3, 7.5 ]
vetor elementos do vetor alterado
Nota: Em algumas literaturas os vetores são apresentados
esquematicamente na vertical como na figura 5.1b. Entretanto, esta
representação é apenas uma maneira de visualizar melhor,
“fisicamente”, esses elementos matemáticos. Teoricamente, um vetor
“vertical” é uma matriz que possui várias linhas e apenas uma coluna;
e um vetor horizontal é uma matriz de apenas uma linha e várias
colunas.
5.3 - Operações Elementares com Vetores
As operações com vetores seguem as regras da Matemática e da
Lógica, obedecendo a hierarquia em uma operação; por exemplo,
tomando como exemplo o vetor Fisica[ ].
✓ Somar: Fisica[6] + Fisica [3] = 6.8 + 7.0 ==> 13.8
✓ Subtrair: Fisica [6] - Fisica [3] = 6.8 - 7.0 ==> -0.2
✓ Dividir: Fisica [6] / Fisica [3] = 0.9714285
✓ Multiplicar: Fisica [6] * Fisica [3] = 47.6
197
✓ Elevar a uma potência: Fisica [3]^2 = 49.0
✓ Extrair a raiz: RaizQ(Fisica [6]) = 2.6076809
✓ Comparações: Fisica [3] > Fisica [6] ==> Verdadeiro
✓ Comparações: nao(Fisica [3] > Fisica [6]) ==> Falso
Resumindo: as operações matemáticas e lógicas podem ser
aplicadas aos elementos de um vetor, observando o tipo de dado.
Entretanto, é importante frisar que a manipulação de vetores tem
que ser elemento a elemento; não é possível, manipular um vetor
de uma vez só, e nem fazer atribuições de vetor para vetor. Por
exemplo, considere que as oito notas em Química, do mesmo
alunos, fossem reunidas num vetor chamado Quimica[ ].
Quimica = { 7.2, 7.4, 7.0, 7.0, 7.1, 6.8, 7.3, 7.5 }
Com os mesmos valores das notas em Física (com a quarta nota
corrigida), e que fosse comparar o desempenho nas duas
disciplinas, com a instrução abaixo:
Quimica = Fisica !!???
ISTO NÃO PODE ser feito. Para fazer essa comparação tem que
comparar elemento a elemento com estrutura de decisão dentro
de um loop, como no fragmento a seguir...
198
...
EhIgual <- Verdadeiro
Para j De 1 Ate 8 Faca
Se(Quimica[j] <> Fisica[j]) Entao
EhIgual <- Falso
Interrompa
FimSe
FimPara
Se(EhIgual) Entao
Escreval("Respectivas notas de Física
correspondem às de Química")
Senao
Escreval("Respectivas notas de Física não
correspondem às de Química")
FimSe
5.4 - Declaração de Vetores no Visualg
Embora não sendo uma variável simples, os vetores também
devem ser declarados ANTES de serem manipulados; esta é uma
exigência das linguagens de programação tradicionais, e de
algumas mais atuais. Por exemplo, declarar o vetor VetNum[ ]
para armazenar nove valores inteiros. A declaração é feita no
Visualg, dentro da “Seção de Declarações das variáveis” da
seguinte maneira:
Var VetNum: vetor[1..9] de inteiro
Nome do vetor Declara vetor Tipo de dado do vetor
Comando de declaração Faixa dos índices
Na “faixa dos dados” 1 indica “índice do primeiro elemento” e 9
o “índice do último elemento” do vetor. Assim, o número de
elementos (tamanho) do vetor é 9.
199
Nota: Em algumas linguagens de programação o índice inicial
dos elementos de um vetor é 0 (zero), mas, no Visualg começa
com 1, como na lógica humana de ordenação.
5.5 - Atribuição Direta
Considerando o vetor VetNum[ ] mencionado anteriormente,
com nove elementos inteiros, esta operação pode ser vista no
programa "AtribuicaoDireta" onde são atribuídos nove valores
inteiros, predeterminados: um a cada elemento desse vetor, como
é mostrado no programa abaixo.
Algoritmo "AtribuicaoDireta"
//Armazena nove número inteiros por atribuição direta.
//Autor: Mário Leite
//---------------------------------------------------
Var VetNum: vetor[1..9] de inteiro
Inicio
VetNum[1] <- 2
VetNum[2] <- 15
VetNum[3] <- 11
VetNum[4] <- 0
VetNum[5] <- -7
VetNum[6] <- 16
VetNum[7] <- 8
VetNum[8] <- 9
VetNum[9] <- -1
FimAlgoritmo
200
5.6 - Atribuição por Leituras Individualizadas
Neste caso as atribuições serão feitas com nove leituras; uma para
cada elemento do vetor, como no programa abaixo, denominado
“AtribuicaoPorLeitura1”.
Algoritmo "AtribuicaoPorLeitura1"
//Armazena nove número inteiros por leituras
// individualizadas.
//Autor: Mário Leite
//-------------------------------------------------------
Var VetNum: vetor[1..9] de inteiro
Inicio
Escreva("Digite o valor do primeiro elemento: ")
Leia(VetNum[1])
Escreva("Digite o valor do segundo elemento: ")
Leia(VetNum[2])
Escreva("Digite o valor do terceiro elemento: ")
Leia(VetNum[3])
Escreva("Digite o valor do quarto elemento: ")
Leia(VetNum[4])
Escreva("Digite o valor do quinto elemento: ")
Leia(VetNum[5])
Escreva("Digite o valor do sexto elemento: ")
Leia(VetNum[6])
Escreva("Digite o valor do sétimo elemento: ")
Leia(VetNum[7])
Escreva("Digite o valor do oitavo elemento: ")
Leia(VetNum[8])
Escreva("Digite o valor do nono elemento: ")
Leia(VetNum[9])
FimAlgoritmo
Esses dois métodos de atribuição não são eficientes e nem
eficazes na prática, pois, “agridem” a lógica de programação, com
soluções muito pobres e sem recursos.
201
No primeiro tipo de atribuição com o programa"AtribuiçãoDireta” fica evidente a falta de flexibilidade, uma
vez que os valores atribuídos serão SEMPRE os mesmos, o que
torna o programa sem um sentido prático. No programa
"AtribuicaoPorLeitura1" a solução também é muito ineficiente
pois, obriga o programador a digitar dezoito linhas de código
(nove para mensagens e nove para ler os valores); imagine se, em
vez de nove, fosse noventa valores!?. A figura 5.3a mostra como
ficam as leituras dos elementos do vetor VetNum[ ] no programa
"AtribuicaoPorLeitura1"
Figura 5.3a - Leitura dos elementos do vetor por leituras diretas
individualizadas
202
Então, a solução mais eficiente, e eficaz, é trabalhar com loop
para manipular elementos de vetores, como será mostrado nos
itens seguintes
5.7 - Atribuição por Leituras Através de Loop
Neste caso a técnica é bem mais eficiente, uma vez que o número
de linhas de código será, basicamente, quatro:
1) Início da estrutura do loop.
2) Mensagem explicativa para o usuário.
3) Leitura do elemento do vetor.
4) Término da estrutura do loop.
Observe como funciona essa técnica no programa
"AtribuicaoPorLeitura2", e compare os tamanhos dos códigos
nas duas versões!
Algoritmo "AtribuicaoPorLeitura2"
//Armazena nove números inteiros por leituras em loop.
//Autor: Mário Leite
//----------------------------------------------------
Var VetNum: vetor[1..9] de inteiro
j: inteiro
Inicio
Para j De 1 Ate 9 Faca
Escreva("Digite o valor do elemento",j,": ")
Leia(VetNum[j])
FimPara
FimAlgoritmo
A figura 5.3b mostra a saída do programa
"AtribuicaoPorLeitura2".
203
Figura 5.3b - Leitura dos elemento do vetor através de um loop
Além de reduzir drasticamente o número de linhas de código, a
versão 2 do programa é bem mais rápida, quando se tem uma
quantidade muito grande de leituras. Mas, ele pode se tornar mais
geral ainda, em vez de se considerar um número fixo de
elementos (no caso foi 9) ser solicitado, previamente, o tamanho
do vetor (quantidade de elementos). Digamos que seja n; então,
uma terceira versão do mesmo programa pode ser vista em
“AtribuicaoPorLeitura3”, bem mais geral e completa para esses
casos.
204
Algoritmo "AtribuicaoPorLeitura3"
//Armazena nove número inteiros por leituras com quantidade
//desejada.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXELE=100 //define máximo de elementos do vetor
Var VetNum: vetor[1..MAXELE] de inteiro
j, n: inteiro
Inicio
Repita
Escreva("Digite o número de elementos do vetor
[min 2 - max",MAXELE,":")
Leia(n)
n <- Int(n) //garante n inteiro
Ate((n>=2) e (n<=MAXELE))
Escreval("")
Para j De 1 Ate n Faca
Escreva("Digite o valor do elemento",j,": ")
Leia(VetNum[j])
FimPara
FimAlgoritmo
A figura 5.3c mostra a saída do programa
"AtribuicaoPorLeitura3".
205
Figura 5.3c - Leitura do vetor com loop (solução mais geral)
Observe que nesta versão mais geral do programa,
“AtribuicaoPorLeitura3”, foram introduzidas mais algumas
linhas extras de código ANTES do loop de leitura dos elementos.
1. Const MAXELE=100 para definir um valor máximo do
tamanho do vetor, podendo ser alterado, se for necessário.
2. Estrutura de repetição para validar o número de elementos do
vetor, inclusive garantindo um valo inteiro para n, com a
instrução Int(n).
Todas as vezes em que houver entrada de um valor X que deva
ser, necessariamente, inteiro, a instrução X <- Int(X) deve ser
considerada.
206
5.8 - Operações Matemáticas Simples com Vetores
Conforme foi introduzido no item 5.3, as operações elementares
podem ser feitas com vetores, desde que seja considerado o
sistema de elemento a elemento, do mesmo tipo. E além das
operações matemáticas elementares (soma, subtração,
multiplicação e divisão), e outras.
5.8.1 - Soma de Vetores
Considere dois vetores U e V, ambos com n elementos inteiros,
que devem ser somados. O programa “SomaDoisVetores”
mostra como seus elementos podem ser somados, cujo resultado
dessa soma é, também, um vetor S de tamanho n.
Algoritmo "SomaDoisVetores"
//Soma dois vetores, elemento a elemento.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXELE=100 //define o tamanho máximo dos
vetores.
Var U, V, S: vetor[1..MAXELE] de inteiro
j, n: inteiro
Inicio
Repita
Escreva("Digite o número de elementos {min 2 –
max",MAXELE,"]:")
Leia(n)
n <- Abs(Int(n)) //garante n inteiro e não negativo
Ate((n>=2) e (n<=MAXELE))
Escreval("")
Escreval("")
{Leitura do vetor U}
Para j De 1 Ate n Faca
Escreva("Digite o elemento",j,"do primeiro vetor: ")
207
Leia(U[j])
FimPara
Escreval("")
{Leitura do vetor V}
Para j De 1 Ate n Faca
Escreva("Digite o elemento",j,"do segundo vetor: ")
Leia(V[j])
FimPara
Escreval("")
{Soma o vetor U com o vetor V para obter o vetor S}
Escreval("Vetor soma: S = U + V")
Para j De 1 Ate n Faca
S[j] <- U[j] + V[j]
Escreva(S[j], " ")
FimPara
Escreval("")
FimAlgoritmo //fim do programa "SomaDoisVetores"
A figura 5.4 mostra a saída do programa "SomaDoisVetores"
com as leituras dos elementos dos dois vetores (U e V) e o
resultado da soma no vetor S.
208
Figura 5.4 - Soma de dois vetores: uma saída do programa
"SomaDoisVetores"
5.8.2 - Subtração de Vetores
A operação de subtração entre dois vetores funciona quase que
exatamente como na operação de soma. A única diferença é o
operador aplicado na operação; em vez de + (adição) será -
(subtração); apenas isto! E ainda considerando os vetores U e V
do item anterior, o resultado da subtração do vetor V do vetor U
é mostrado na figura 5.5. O resultado é o vetor-diferença D, de
mesmo tamanho n.
209
Figura 5.5 - Subtração entre dois vetores uma saída do programa
"SubtraiVetores "
210
Algoritmo "SubtraiVetores"
//Subtrai um vetor de outro, elemento a elemento.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXELE=100 //define tamanho máximo dos vetores
Var U, V, D: vetor[1..MAXELE] de inteiro
j, n: inteiro
Inicio
Repita
Escreva("Digite o número de elementos {min 2
- max",MAXELE,"]:")
Leia(n)
n <- Abs(Int(n)) //garante n inteiro e não negativo
Ate((n>=2) e (n<=MAXELE))
Escreval("")
Escreval("")
{Leitura do vetor U}
Para j De 1 Ate n Faca
Escreva("Digite elemento",j,"do primeiro vetor: ")
Leia(U[j])
FimPara
Escreval("")
{Leitura do vetor V}
Para j De 1 Ate n Faca
Escreva("Digite elemento",j," do segundo vetor: ")
Leia(V[j])
FimPara
Escreval("")
{Subtrai o vetor V do vetor U para obter o vetor D}
Escreval("Vetor diferença: D = U - V")
Para j De 1 Ate n Faca
D[j] <- U[j] - V[j]
Escreva(D[j], " ")
FimPara
Escreval("")
FimAlgoritmo
211
5.9 - Aplicações de Vetores
5.9.1 - Ordenação
Uma lista de valores de tipos numéricos e/ou caracteres pode ser
classificada em ordem crescente ou decrescente, com a utilização
de vetores. Cada um desses valores são representados por
elementos de um vetor, definido como do tipo correspondente.
Para isto existem várias técnicas, ou métodos, de classificação.
Segundo Azeredo (1996), existem diversos métodos de
classificação (ordenação) de elementos, formando as chamadas
“famílias de classificações”;aqui neste livro, para não fugir ao
escopo didático a que se propõe, trataremos apenas da técnica
mais utilizada pelos programadores: o “Método da Bolha”. Este
método, conhecido academicamente como “Bubble Sort”, é o
mais popular entre os programadores iniciantes, devido à sua
simplicidade e facilidade de aprender, embora não seja o mais
eficiente. Em resumo, consiste em percorrer a estrutura de um
vetor, trocando um elemento de posição quando este estiver fora
de sua posição de acordo com o modo de classificação desejado.
Então, se o que se deseja é uma ordenação crescente - do menor
valor para o maior valor - a troca será feita quando um elemento
de posição j tiver menor valor que um elemento da posição j-1.
Caso contrário, se a classificação for na ordem decrescente - do
maior para o menor - a troca ocorrerá quando um elemento de
posição j for maior que o elemento da posição j-1. Então, é
necessário utilizar uma estrutura de repetição com dois loops
aninhados, de modo que o mais externo controle as posições dos
elementos antecessores e o segundo (mais interno) os elementos
sucessores, fazendo comparações ente eles. No caso da ordenação
crescente, se o antecessor for maior que seu sucessor então faz-se
a troca de posições entre eles; caso contrário suas posições
212
permanecem como estão. O quadro 5.1 mostra o esquema do
“Método da Bolha” para ordenar os elementos 17, 15, 94, 30 e 12
de um vetor de inteiros.
17 15 94 30 12
15 17 94 30 99
1/2: Troca
1/3: Não Troca
15 17 94 30 12
1/4: Não Troca
15 17 94 30 121/5: Troca
12 17 94 30 152/3: Não Troca
12 17 94 30 152/4: Não Troca
12 17 94 30 152/5: Troca
12 15 94 30 173/4: Troca
12 15 30 94 173/5: Troca
12 15 17 94 304/5: Troca
12 15 17 30 94Vetor Ordenado
Quadro 5.1 - Esquema de ordenação pelo Método da Bolha
213
O programa “OrdenaBolha”, a seguir, mostra como fazer a
ordenação crescente com uma lista de n elementos digitados pelo
usuário.
Algoritmo "OrdenaBolha"
//Ordena um vetor lido, de n elementos pelo "Método Bolha".
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXELE=100 //define o máximo de elementos
Var VetNum: vetor[1.. MAXELE] de inteiro
i, j, n, Aux: inteiro
Num: real
Inicio
Repita
Escreva("Digite o número de elementos min 2 –
max",MAXELE,"]: ")
Leia(n)
n <- Int(n) //garante número inteiro
Ate((n>=2) e (n<=MAXELE))
Escreval("")
{Loop para a leitura dos elementos do vetor}
Para j De 1 Ate n Faca
Escreva("Digite um número inteiro: ")
Leia(Num)
VetNum[j] <- Int(Num)
FimPara //fim da leitura dos elementos do vetor
LimpaTela
{Loop para exibir os elementos do vetor na ordem lida}
Escreval("Elementos do vetor na ordem lida:")
Para j De 1 Ate n Faca
Escreva(VetNum[j], " ")
FimPara
Escreval("")
Escreval("")
{Loops aninhados para ordenar pelo "Método da Bolha"}
Para i De 1 Ate (n-1) Faca
214
Para j De (i+1) Ate n Faca
{Faz as trocas, se for necessário}
Se(VetNum[i] > VetNum[j]) Entao //crescente
Aux <- VetNum[i]
VetNum[i] <- VetNum[j]
VetNum[j] <- Aux
FimSe
FimPara
FimPara
{Exibe os elementos do vetor ordenados crescentemente}
Escreval("Elementos do vetor depois de ordenados:")
Para j De 1 Ate n Faca
Escreva(VetNum[j], " ")
FimPara
FimAlgoritmo //fim do programa "OrdenaBolha"
Nota: O código do programa "OrdenaBolha" faz a classificação de
um vetor de inteiros em ordem crescente. Para fazer a classificação
em ordem decrescente basta, apenas, inverter o operador na
expressão que faz a comparação de > para <
A figura 5.7 mostra uma saída do programa “OrdenaBolha”,
para um vetor de onze elementos lidos.
215
Figura 5.7 - Ordenação do vetor pelo “Método da Bolha”
5.9.2 - Pesquisas
Existem vários métodos e técnicas de fazer pesquisas em vetores;
mas, de um modo geral, a base para se pesquisar (procurar) um
determinado elemento num vetor é o que se chama de chave, que
requer duas informações básicas: campo e valor.
campo
chave
valor
A informação do campo é referenciada num vetor por seu índice,
e valor é o conteúdo do campo (valor do elemento) que é o
objetivo da pesquisa.
Aqui serão mostrados apenas dois métodos de pesquisa:
Sequencial e Binário.
216
5.9.2.1 - Pesquisa Sequencial
Este método de pesquisa, também conhecido como “busca
linear”, apesar de ser o mais lento entre todos os outros, é o mais
simples de entender, uma vez que o processo é tal como nós
raciocinamos: começar a procurar o valor, fazendo comparações
com os elementos do vetor, do primeiro para o último elemento.
A pesquisa terá sucesso se o valor procurado coincidir com o
valor de algum elemento (campo) do vetor; é simples, porém
muito demorada. Deste modo, se o vetor possuir muitos
elementos e o valor procurado estiver contido no último
elemento, o tempo de busca pode exceder a dezenas de minutos
(dependendo do conjunto software/hardware utilizado). O
pseudocódigo a seguir implementa o algoritmo desse método de
pesquisa, de um valor inteiro. O programa “PesquisaSequencial”
é um exemplo que ilustra a aplicação desse método de pesquisa.
Algoritmo “PesquisaSequencial”
//Exemplos de pesquisa de elemento em vetor através de
//“Pesquisa Sequencial”
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXELE=100 //define máximo de elementos do vetor
Var VetNum: vetor[1..MAXELE] de inteiro
Valor, j, n, Posicao: inteiro
Msg1, Msg2: caractere
Achou: logico
Inicio
{Leitura dos elementos do vetor}
Repita
Escreva(“Digite o número de elementos [min 2-
max”,MAXELE,”]: “)
Leia(n)
n<-Abs(Int(n))
Ate((n>=2) e (n<=MAXELE))
Escreval(“”)
217
Para j De 1 Ate n Faca
Escreva(“Entre com o elemento [“, j, “] do
vetor: “)
Leia(VetNum[j])
FimPara
Escreval(“”)
Escreva(“Digite o valor a ser pesquisado: “)
Leia(Valor)
Valor <- Int(Valor) //garante número inteiro
Msg1 <- “Valor encontrado na posição: “
Msg2 <- “Valor não encontrado.”
{Executa a pesquisa}
Achou <- Falso
j <- 1
Enquanto ((Achou=Falso) e (j<=n)) Faca
Se(valor=VetNum[j]) Entao
Posicao <- j
Achou <- Verdadeiro
FimSe
j <- j + 1
FimEnquanto
Escreval(“”)
Escreval(“”)
{Verifica se a pesquisa teve sucesso}
Se(Achou) Entao
Escreval(Msg1, Posicao)
Senao
Escreval(Msg2)
FimSe
FimAlgoritmo
A figura 5.8a mostra uma saída do programa
“PesquisaSequencial”.
218
Figura 5.8a - Pesquisando elemento “Pesquisa Sequencial”
A figura 5.8b mostra outra saída do programa
“PesquisaSequencial”, considerando o mesmo vetor; agora, no
caso em que a elemento procurado não pertence ao vetor dado.
219
Figura 5.8b - Pesquisando elemento com “Pesquisa Sequencial”
5.9.2.2 - Pesquisa Binária
O método de “Pesquisa Binária” é muito mais rápido e mais
eficiente do que o da “Pesquisa Sequencial”, pois utiliza um sistema
de particionamento recursivo do vetor em dois subsegmentos. Em
termos práticos o método consiste na busca de determinado valor
numa lista previamente ordenada A cada comparação, caso o valor
não seja encontrado um novo intervalo de pesquisa é criado, e a
partir de então é estabelecido um novo local de início e fim da
pesquisa. Este procedimento é repetido até que o início de pesquisa
coincidacom o fim e o intervalo pesquisado reduzido a um único
elemento. Vamos considerar um vetor com quinze elementos de
inteiros, no qual se deseja pesquisar o valor 31, como mostrado no
esquema do quadro 5.2a.
220
Quadro 5.2a - Primeira partição do seguimento
Fazendo a primeira partição o elemento central é o 52; e como 52
é maior que 31 conclui-se que o elemento procurado deve estar à
esquerda de 52. Portanto, uma segunda partição deve ser feita. E
considerando agora o segmento da esquerda, o novo valor central
é o 21; isto pode ser visto no esquema do quadro 5.2b.
Quadro 5.2b - Segunda partição do seguimento
Repetindo o processo chegaremos ao resultado apresentado no
quadro 5.2c em que o elemento central 31 coincide com o valor
procurado. O programa “PesquisaBinaria”, em pseudocódigo,
mostra como funciona esse tipo de pesquisa.
221
Quadro 5.2c - Fim do processo: valor encontrado
Programa "PesquisaBinaria"
//Procura um valor através do método de "Pesquisa
//Binária"
//-------------------------------------------------------
{Vet: Vetor de elementos onde será feita a pesquisa.
PosIni: Posição inicial do intervalo de pesquisa.
PosFim: Posição final do intervalo de pesquisa.
PosCent: Posição do elemento central do intervalo.
NumPesq: Número a ser pesquisado.
Achou: Variável lógica que verifica a pesquisa
}
//-------------------------------------------------------
Declare j, n, NumPesq, Local, PosIni: inteiro
PosFim, PosCent: inteiro
Achou: lógico
Vet: array[1..n] de inteiro
Início
Escreva("Digite o número a ser pesquisado: ")
Leia(NumPesq)
{Lê os elementos do vetor - n conhecido previamente}
Para j De 1 Até n Faça
Escreva("Entre com o elemento[",j,"]do vetor:")
Leia(Vet[j])
FimPara
{ATENÇÃO: Depois de lido o vetor deve ser ordenado}
EscrevaLn("")
Local 0
PosIni 1
PosFim n
222
Achou .F.
Enquanto((PosIni<=PosFim) e (Achou=.F.)) Faça
PosCent Int(PosIni+PosFim)/2 //posição central
Se(Vet[PosCent]=NumPesq) Então
Achou .V.
Local PosCent
Senão
Se(Vet[PosCent]>NumPesq) Então
PosFim PosCent – 1
Senão
PosIni PosCent + 1
FimSe
FimSe
FimEnquanto
Se(Local<>0) Então
EscrevaLn("Valor encontrado na posição: ", Local)
Senão
EscrevaLn("Valor não encontrado")
FimSe
FimPrograma
5.9.3 - Verificando Maior e Menor elemento
Neste caso uma boa técnica de programação é começar
considerando o primeiro elemento do vetor como sendo o maior
e menor, simultaneamente, já que ele é o primeiro e ainda não foi
comparado com nenhum outro da lista. O programa
“VerifMaiorMenor” é uma solução para isto.
A figura 5.9a mostra o programa no editor do Visualg, e a figura
5.9b a saída do programa.
223
Figura 5.9a - Código-fonte do programa “VerifMaiorMenor” no editor
224
Figura 5.9b - Uma saída do programa “VerifMaiorMenor”
Uma outra solução para encontrar o maior e o menor elemento de
um vetor de inteiros, seria: primeiro ordenar (crescentemente) o
vetor, e depois, simplesmente, escrever o maior (último
elemento) e o menor (primeiro elemento). Uma solução,
logicamente, bem simples.
5.9.4 - Soma e Média dos elementos
Tal como saber qual é o maior e o menor elemento de um vetor,
esta é uma ação que poderá ser solicitada em algum momento,
num programa mais geral: “a soma dos elementos de um vetor e
sua média”. Uma solução bem simples é a apresentada no
programa “Soma-MediaElementos”, exibindo a média com
apenas uma decimal.
225
Figura 5.10a - Uma saída do programa “Soma-MediaElementos”
226
Figura 5.10b - Código-fonte de “Soma-MediaElementos” no editor
227
5.9.5 - Invertendo a Ordem dos elementos
A inversão da ordem dos elementos de um vetor, às vezes, é
importante em diversas situações; e existe uma forma bem
simples de fazer isto: mostrar o vetor num loop decrescente de 1,
após a leitura original. Outra técnica, mais elegante é, à medida
que for lendo os elementos do vetor original, criar outro vetor
com os elementos “de trás para a frente”, usando a fórmula:.
VetInv[n-j+1] = VetOrig[j]
Onde VetInv[ ] é o vetor inverso e VetOrig[ ] o vetor lido
originalmente, com n elementos.
Os programas “InverteVetor1” e InverteVetor2” (figuras 5.11a
e 5.11b, respectivamente) mostram as duas maneiras citadas de
inverter um vetor de dez elementos inteiros.
Figura 5.11a - Código-fonte do programa “InverteVetor1” no editor
228
Figura 5.11b - Uma saída do programa “InverteVetor1”
Figura 5.12a - Código-fonte do programa “InverteVetor2” no editor
229
Figura 5.12b - Uma saída do programa “InverteVetor2”
5.9.6 - Verificando Característica de elemento
5.9.6.1- Verificando elemento Múltiplo
Esta é uma situação que pode ocorrer: percorrer os elementos do
vetor e ver qual (ou quais) elemento(s) é múltiplo de um número
dado. Por exemplo, seja o vetor de inteiros:
14 12 25 4 6 32 27 34 22 15
Vamos verificar qual (s) elemento(s) desse vetor é múltiplo de 3.
Neste caso vemos que os elementos que correspondem a esta
questão são: 12, 6, 27 e 15.
230
O programa “VerifEleMultiplo”, mostrado na figura 5.13a, é
uma solução para este problema. A figura 5.13b mostra a saída
do programa para o vetor de elementos sugeridos.
Figura 5.13a - Código-fonte do programa “VerifEleMultiplo” no editor
231
Figura 5.13b - Uma saída do programa “VerifEleMultiplo”
5.9.6.2- Verificando elemento Divisor
Neste caso, a solução é bem parecida com a do item anterior;
agora temos que verificar se um elemento (ou quais) do vetor
divide o número dado. As figuras 5.14a e 5.14b mostram duas
saídas do programa “VerifEleDivisor”, e a figura 5.14c o código-
fonte do programa que implementa a solução, digitado no editor
do Visualg.
232
Figura 5.14a - Uma saída do programa “VerifEleDivisor”
Figura 5.14b - uma saída do programa “VerifEleDivisor”
233
Figura 5.14c - Código-fonte do programa “VerifEleDivisor” no editor
5.9.6.3 - Verificando Paridade e Posição
Neste caso, o que se deseja é mostrar os elementos pares e os
ímpares do vetor e suas posições na lista, O programa
“VerifParidade” da figura 5.15a é uma solução bem simples, e
uma saída é mostrada na figura 5.15b..
234
Figura 5.15a - Código-fonte do programa “VerifParidade” no editor
Figura 5.15b - Uma saída do programa “VeriParidade”
235
5.9.7 - Incluindo, Excluindo e Alterando elemento
Pode acontecer que depois de criar um vetor (através de leitura
ou de atribuições diretas) haja necessidade de incluir, excluir ou
alterar um elemento no vetor. Nestes casos, estes tipos de ações,
através de nova leitura dos elementos fica muito trabalhoso, e
para atribuição direta mais ainda.
5.9.7.1- Incluindo um novo elemento
Neste caso, o que se deseja é fazer a inserção de novo elemento
em algum local do vetor, entre dois elementos, ou mesmo nas
suas extremidades. Por exemplo: seja o vetor de inteiros: 3 5 0
1 9 7 6 4 2 ; e se deseja incluir o elemento 8 na posição 4, isto
e: na posição atualmente do elemento 1. Deste modo o elemento
1 vai passar a ser o quinto elemento do vetor, depois de feita a
inserção do número 8. Os dois esquemas abaixo esclarece.
Situação antes da inserção:
3 5 0 1 9 7 6 4 2
Situação depois da inseçsão:
3 5 0 8 1 9 7 6 4 2
A figura 5.16 mostra a saída do programa, considerando o vetor
mostrado acima.
O programa “IncluiElementoNoVetor” é uma solução em
Visualg que implementa uma solução bem didática e eficiente,
pois, além de fazer a inserção, o vetoré reorganizado com esse
novo elemento na posição desejada.
236
Figura 5.16 - Uma saída do programa “IncluiElementoNoVetor”
Algoritmo "IncluiElementoNoVetor"
//Inclui um novo elementos num vetor de inteiros, e //em
seguida o rearranja.
//Autor: Mário Leite
//-------------------------------------------------------
Var VetOrig, VetAtu: vetor[1..100] de inteiro
j, N, Posi, Num, NovoElem: inteiro
Inicio
LimpaTela
N <- 0
Enquanto ((N<=2) ou (N>100)) Faca
Escreva("Digite o número de elementos do
vetor? [mínimo 2 - max 100]: ")
Leia(N)
FimEnquanto
237
Escreval("")
{Lê e vai mostrando os elementos do vetor}
Para j De 1 Ate N Faca
Escreva("Digite número inteiro e positivo: ")
Leia(Num)
VetOrig[j] <- Abs(Int(Num))
VetAtu[j] <- VetOrig[j]
FimPara
Escreval("")
{Inclui novo elemento no vetor}
Repita
Escreva("Em qual posição deseja incluir o
elemento? [min 1"," - max",N,"]: ")
Leia(Posi)
Ate((Posi>=1) e (Posi<=N))
Escreval("")
Escreva("Digite o valor do novo elemento: ")
Leia(NovoElem)
NovoElem <- Int(NovoElem)
LimpaTela
{Vetor original}
Escreval("Vetor com os elementos lidos")
Para j De 1 Ate N Faca
Escreva(VetOrig[j], " ")
FimPara
Para j De 1 Ate (N+1) Faca
Se(j<Posi) Entao
VetAtu[j] <- VetOrig[j]
FimSe
Se(j=Posi) Entao
VetAtu[j] <- NovoElem
FimSe
Se(j>Posi) Entao
VetAtu[j] <- VetOrig[j-1]
FimSe
238
FimPara
Escreval("")
Escreval("")
{Vetor com o novo elemento}
Escreval("Vetor com o novo elemento incluido")
Para j De 1 Ate (N+1) Faca
Escreva(VetAtu[j], " ")
FimPara
Escreval("")
FimAlgoritmo
5.9.7.2 - Excluindo um elemento
Agora, o que se deseja é excluir um determinado elemento do
vetor. Assim, considerando o vetor do item anterior, suponha que
se deseja excluir o sexto elemento (9) do vetor da figura 5.16,
resultado da inserção do elemento 8.
O programa "ExcluiElementoDoVetor" é uma boa solução com
o Visualg, como na figura 5.17.
Algoritmo "ExcluiElementoDoVetor"
//Exclui um elementos de um vetor de inteiros, e em
seguida o rearranja.
//Autor: Mário Leite
//-------------------------------------------------------
Var VetOrig, VetAtu: vetor[1..100] de inteiro
j, N, Posi, Num, NovoElem: inteiro
Inicio
LimpaTela
N <- 0
Enquanto ((N<=2) ou (N>100)) Faca
Escreva("Digite o número de elementos do vetor?
[mínimo 2 - max 100]: ")
Leia(N)
FimEnquanto
Escreval("")
{Lê e vai mostrando os elementos do vetor}
Para j De 1 Ate N Faca
Escreva("Digite um número inteiro e positivo: ")
239
Leia(Num)
VetOrig[j] <- Abs(Int(Num))
VetAtu[j] <- VetOrig[j]
FimPara
Escreval("")
{Exclui o elemento do vetor}
Repita
Escreva("Deseja excluir o elemento de qual
posição? [min 1", " - max",N,"]: ")
Leia(Posi)
Ate(Posi>=1) e (Posi<=N))
Escreval("")
LimpaTela
{Vetor original}
Escreval("Vetor com os elementos lidos")
Para j De 1 Ate N Faca
Escreva(VetOrig[j], " ")
FimPara
{Exclui o elemento do vetor}
Para j De 1 Ate N Faca
Se(j<Posi) Entao
VetAtu[j] <- VetOrig[j]
FimSe
Se(j>=Posi) Entao
VetAtu[j] <- VetOrig[j+1]
FimSe
FimPara
Escreval("")
Escreval("")
Escreval("Elemento excluido na posição", Posi,":",
VetOrig[posi])
Escreval("")
{Vetor sem o elemento excluido}
Escreval("Vetor sem o elemento exluido")
Para j De 1 Ate (N-1) Faca
Escreva(VetAtu[j], " ")
FimPara
FimAlgoritmo
240
Figura 5.17 - Uma saída do programa “ExcluiElementoDoVetor”
5.9.7.3 - Alterando o valor do elemento
Nesta terceira situação, deseja-se alterar o valor de um
determinado elemento do vetor já constituído. Vamos considerar
que a alteração do vetor da figura 5.17, alterando o valor do
penúltimo elemento (4) para o novo valor 5. A figura 5.18 mostra
o resultado dessa alteração; e a seguir é mostrado o programa que
implementa essa ação: o programa “AlteraElementoDoVetor”.
241
Figura 5.18 - Uma saída do programa “AlteraElementoDoVetor”
Algoritmo "AlteraElementoDoVetor"
//Altera o valor de um elemento de um vetor de inteiros,
//e o rearranja.
//-------------------------------------------------------
Var VetOrig, VetAtu: vetor[1..100] de inteiro
//limita o tamanho do vetor
j, N, Posi, Num, NovoValor: inteiro
Inicio
LimpaTela
N <- 0
Enquanto ((N<=2) ou (N>100)) Faca
Escreva("Digite o número de elementos do
vetor? [mínimo 2 -max 100]: ")
Leia(N)
FimEnquanto
Escreval("")
242
{Lê e vai mostrando os elementos do vetor}
Para j De 1 Ate N Faca
Escreva("Digite o elemento da posição",j,":")
Leia(Num)
VetOrig[j] <- Abs(Int(Num))
VetAtu[j] <- VetOrig[j]
FimPara
Escreval("")
{Altera elemento do vetor}
Repita
Escreva("Deseja alterar o elemento de qual
posição? [min 1", " - max",N,"]: ")
Leia(Posi)
Ate(Posi>=1) e (Posi<=N))
Escreval("")
Escreva("Digite o novo valor do elemento da
posição", Posi, ": ")
Leia(NovoValor)
Escreval("")
{Vetor original}
Escreval("Vetor com os elementos lidos")
Para j De 1 Ate N Faca
Escreva(VetOrig[j], " ")
FimPara
Escreval("")
Escreval("")
VetAtu[Posi] <- NovoValor //faz a alteração
{Vetor com o elemento alterado}
Escreval("Vetor com o elemento alterado")
Para j De 1 Ate N Faca
Escreva(VetAtu[j], " ")
FimPara
FimAlgoritmo
243
❖ Exemplo 5.1 - Calcular o MDC de vários números solicitados.
No Exemplo 1.5, do Capítulo 1, foram apresentados esquemas
de como calcular o MDC de dois números: 36 e 98, formalizado
em pseudocódigo, o qual poderia ser codificado em qualquer das
diversas linguagens de programação. Aquele exemplo foi para
indicar que o importante é a programação (algoritmo da solução
do problema) e não, especificamente. a codificação. Aqui, vamos
mostraremos uma solução mais geral com o Visualg: em vez de
apenas dois números, vamos calcular o MDC de n números
(2<=n<=10), com o programa “CalculaMDCVariosNumeros”.
Algoritmo "CalculaMDCVariosNumeros"
//Calcula o MDC de vários números.
//Autor: Mário Leite
//-------------------------------------------------------
Var VetNum: vetor[1..10] de inteiro //limita vetor
j, n, Aux, MDC, MDCx, Num1, Num2: inteiro
Inicio
Repita
Escreva("De quantos números será calculado o
MDC? ")
Leia(n)
Ate((n>=2) e (n<=10))
Escreval("")
Para j De 1 Ate n Faca
Escreva("Digite o número #",j, ": ")
Leia(VetNum[j])
FimPara
Escreval("")
Para j De 1 Ate (n-1) Faca
Se(j=1) Entao
{Utiliza o "Algoritmo de Euclides"
Num1 <- VetNum[1]
Num2 <- VetNum[2]
Senao
{Considera o segundo número incrementado de 2
Num2 <- VetNum[j+2]
244
FimSe
Enquanto (Num2<>0) Faca
Aux <- Num1
Num1 <- Num2
Num2 <- (Aux Mod Num2)
FimEnquanto
MDCx <- Num1 //MDCx é o VetNum[j,(j+1)]
FimPara
MDC <- MDCx
Escreval("")
Escreval("")
Escreva("MDC(")
Para j De 1 Ate n Faca
Se(j<n) Entao
Escreva(VetNum[j], ",")
Senao
Escreva(VetNum[j], ") =", MDC)
FimSe
FimPara
Escreval("")
FimAlgoritmoFigura 5.19 - Uma saída do programa “CalculaMDCVariosNumeros”
245
5.10 - Erros na utilização de Vetores
Tal como acontece com variáveis simples, erros podem ocorrer,
também. com vetores. Além de incompatibilidade de tipos, um
dos erros mais comuns é sobre a dimensão do vetor; neste caso,
tenta-se acessar um elemento que está fora da faixa definida. Por
exemplo, define-se um vetor de n elementos [1..n], mas, em
alguma linha de código o programa está tentando acessar o
elemento n+1, ou de índice menor que 1. Observe o programa
“AcessaVetor” mostrado na figura 5.20a.
Figura 5.20a - Código-fonte do programa “AcessaVetor” no editor
A figura 5.20b exibe a saída do programa “AcessaVetor”,
mostrando que existe um erro quando se tenta acessar um
elemento que não pertence ao vetor: problema no índice que não
foi definido. Observe que a leitura dos oito elementos ocorre sem
problema dentro do loop, mas, quando é interpretada a linha de
instrução para escrever o nono elemento um erro acontece, pois,
esse elemento não existe (não foi definido dentro da faixa de
índices). O mesmo tipo de erro ocorreria se fosse pedido para
mostrar um elemento de índice j<1.
246
Figura 5.20b - O código-fonte do programa “AcessaVetor”
247
5.11 - Exercícios Propostos
1 - Explique com suas palavras: o que são vetores, e como se
atribui valores a eles no Visualg
2 - Que tipos de dados os elementos de um vetor pode ter no
Visualg? Por quê?
3 - Mostre um exemplo de vantagem do uso de vetores.
4 - Escreva um programa em Visualg para criar um vetor de dez
números pares (menores que 100), gerados aleatoriamente.
5 - Crie um programa que monte um vetor cujos elementos são os
divisores de um número lido N (N>=10). Esse vetor deverá ser
exibido com seus elementos ordenados.
6 - Observe o programa “XXX” abaixo, e explique o que ele faz...
Algoritmo "XXX"
Const MAXELE=1000
Var VetNum: vetor[1..MAXELE] de inteiro
j, n, Col, Cont, Num, RInt: inteiro
RRea: real
Inicio
Repita
Escreva("Digite o número de elementos do vetor
[min 2-max",MAXELE,"]: ")
Leia(N)
Ate((n>=2) e (n<=MAXELE))
Escreval("")
Cont <- 0
Num <- 0
Enquanto (Cont<=n) Faca
Num <- Num + 1
RRea <- RaizQ(Num)
RInt <- Int(RRea)
Se(RRea=RInt) Entao
248
Cont <- Cont + 1
VetNum[Cont] <- Num
FimSe
FimEnquanto
Col <- 0
Escreval("")
Escreval("")
Para j De 1 Ate n Faca
Col <- Col + 1
Se(Col>10) Entao
Escreval("")
Col <- 1
FimSe
Escreva(VetNum[j], " ")
FimPara
Escreval("")
FimAlgoritmo
7 - Crie um programa que leia n valores inteiros e monte um vetor
só com elementos ímpares. Caso não exista nenhum valor ímpar
lido o programa deverá emitir uma mensagem alertando o usuário
para esse fato.
8 - Repita o problema do exercício anterior; agora, porém, os
elementos do vetor criado deverão ser todos primos.
9 - Observe o programa “YYY” abaixo. Marque a alternativa
correta que indica porque o programa não vai rodar.
Algoritmo "YYY"
Const TamMax=100
Var VetRand: vetor[0..TamMax] de inteiro
j, ContEle, TamVet: inteiro
PI: real
Inicio
LimpaTela
Repita
Escreva("Digite o número de elementos que o
vetor terá: ")
Leia(TamVet)
249
TamVet <- Int(TamVet)
Ate((((TamVet>=2) e (TamVet<=TamMax))))
PI <- 3.14159265
Escreval("")
ContEle <- 0
Para j De 1 Ate TamVet Faca
VetRand[j] <- (Randi(1001))*Int(PI)
Escreva(VetRand[j], " ")
ContEle <- ContEle + 1
Se(ContEle>10) Entao
ContEle <- 0
Escreval("")
FimSe
FimPara
Escreval("")
FimAlgoritmo
A ( ) O índice inicial do vetor não pode ser 0,
B ( ) Tem excesso de parênteses na estrutura Repita..Ate,
C ( ) Na estrutura Para..FimPara a variável j deveria
começar com 0.
D ( ) A constante PI não pode ser declarada no Visualg.
E ( ) As declarações das constantes deveriam estar depois
do comando Var.
10 - Rodando o programa “MostraMedia” abaixo, obteve-se o
resultado de 12.4 para a média do aluno, o que é um resultado
inválido, pois deveria ser, de no máximo 10.0. O que faltou no
programa para que o valor da média sempre seja um valor válido?
250
Algoritmo "MostraMedia"
Var VetNotas: vetor[1..4] de real
j: inteiro
Soma, Media: real
Inicio
Para j De 1 Ate 4 Faca
Escreva("Digite a nota",j," do aluno: ")
Leia(VetNotas[j])
Soma <- Soma + VetNotas[j]
FimPara
Escreval("")
Media <- Soma/4
Escreval("Média das notas: ", Media)
FimAlgoritmo
A ( ) O índice inicial do vetor de notas deveria ser 0 (zero).
B ( ) Cada nota deveria ser validada do segu8inte modo:
0<=VetNotas[j]<=10.
C ( ) Cada nota deveria ser validada assim: 0<VetNotas[j]<10.
D ( ) Cada nota deveria ser validada assim: VetNotas[j]<=10.
E ( ) A variável Soma tinha que ser inicializada com valor 0.
11 - O objetivo do programa "MostraDifPrimos" é mostrar os
números primos num intervalo dado, as diferenças entre dois
primos consecutivos, a maior diferença e a quantidade desses
números nesse intervalo. Entretanto, existe um pequeno bug que
inviabiliza o seu funcionamento correto. Mostre onde está esse
bug.
251
Algoritmo "MostraDifPrimos"
//Analisa os primos num determinado intervalo.
//Autor : Mário Leite
//-------------------------------------------------------
Var VetPrimos: vetor[1..1000] de inteiro
j, k, Lim1, Lim2, Num, Cont, Rdiv, IntRaiz:
inteiro
Dif, MaiorDif, PriAnt, PriPrx: inteiro
Cond, TemDiv: logico
Inicio
Escreva("Digite o limite inferior: [maior ou
igual a 1]: ")
Leia(Lim1)
Escreva("Digite o limite superior: [maior que
",Lim1,"]: ")
Leia(Lim2)
Se(Cond) Entao
Escreval("Intervalo inválido!")
Senao
Cont <- 0
Para j De Lim1 Ate Lim2 Faca
PriPrx <- j + 1 //pega o primeiro após j
IntRaiz <- Int(RaizQ(PriPrx))
TemDiv <- Falso
Para k De 2 Ate (IntRaiz) Faca //divisões
RDiv <- (PriPrx Mod k)
Se(RDiv = 0) Entao
TemDiv <- Verdadeiro
Interrompa //abandona loop
FimSe
FimPara
Se(Nao(TemDiv)) Entao //checa se é primo
Cont <- Cont + 1
VetPrimos[Cont] <- PriPrx
Escreval(PriPrx)
FimSe
FimPara //fim do loop para detectar primos
252
Escreval("Quantidade de primos encontrada:
",Cont)
Escreval("")
MaiorDif <- 0
Escreval("Diferenças entre os primos
consecutivos:")
Para j De 2 Ate Cont Faca
Dif <- VetPrimos[j] - VetPrimos[j-1]
Se(Dif>MaiorDif) Entao
MaiorDif <- Dif
PriAnt <- VetPrimos[j-1]
PriPrx <- VetPrimos[j]
FimSe
Escreval(VetPrimos[j],"-",VetPrimos[j-
1],": ",Dif)
FimPara
Escreval("Maior diferença entre dois primos
consecutivos[",PriPrx," –
",PriAnt,"]:",MaiorDif)
FimSe
FimAlgoritmo
253
Capítulo 6 - Trabalhando com Matrizes
6.1 - Introdução ao Capítulo
Matrizes podem ser consideradas como uma generalização de
vetores, uma vez que permitem armazenar e manipular valores
em várias direções, enquanto que nos vetores só é permitido uma
lista de valores em apenas uma direção. Isto quer dizer que,enquanto um elemento de um vetor é identificado por apenas um
único índice inteiro, um elemento de uma matriz é identificado
por mais de um índice inteiro. Se a matriz é bidimensional cada
elemento tem dois índice, funcionando como uma tabela de um
banco de dados.
Este capítulo apresenta um estudo básico sobre o uso de matrizes
em programas implementados em Visualg, com exemplos e
aplicações bem interessantes para os iniciantes, e também para
aqueles que já possuem algum conhecimento de programação.
São mostrados exemplos práticos que podem ser aproveitados em
situações do dia a dia dos profissionais em desenvolvimento de
sistemas: operações com matrizes, matrizes especiais e cálculos
de determinantes.
6.2 - Conceitos Básicos
Tecnicamente, pode-se dizer que um vetor é um caso particular
de matriz: uma matriz unidimensional. Matriz é um array
multidimensional que se constitui, também, numa estrutura
homogênea pois, tal como os vetores, seus elementos têm que ser
todos de um mesmo tipo de dado. Portanto, as matrizes também
são consideradas variáreis indexadas, compostas ou subscritas.
254
E, embora a quantidade máxima de dimensões de uma matriz seja
definida apenas pela memória RAM disponível, o máximo
utilizado é três; mas, na prática utiliza-se duas dimensões (que o
Visualg suporta), tratando uma matriz como se fosse uma tabela
do ambiente de banco de dados. Para matrizes bidimensionais a
primeira dimensão é sempre considerada a LINHA, e a segunda
dimensão a COLUNA (rigorosamente, nesta ordem).
A figura 6.1 mostra um esquema representativo, teórico, de uma
matriz de m linhas e n colunas.
Figura 6.1 - Esquema de representação de uma matriz mxn
Na prática, uma matriz bidimensional pode ser considerada um
arranjo retangular de mxn elementos de um mesmo tipo; e de
acordo com o esquema da figura 6.1 cada par ordenado (aij) é um
elemento da matriz, onde i é o índice da linha e j o índice da
coluna; e se m=n então a matriz é dita quadrada. Então, segundo
o esquema da figura 6.1 a53 é o elemento que ocupa a linha 5 e
coluna 3. Os esquemas das figuras 6.2a e 6.2b mostram o
exemplo de uma matriz de inteiros com dimensões 4x6 (4 linhas
e 6 colunas)
255
2 4 5 8 1 3
0 6 9 5 3 7
5 8 9 0 3 4
4 3 4 1 6 5
Figura 6.2a- Esquema de representação de uma matriz 4x6
A figura 6.2b mostra um esquema da matriz bidimensional.
Observe que é como se tivesse vários vetores horizontais e
verticais compondo a matriz M 4x6.
Figura 6.2b - Representação da matriz M bidimensional
L
i
n
h
a
s
C o l u n a s
256
A tabela 6.1 mostra um exemplo de notas médias obtidas por
quatro turmas (diurnas e noturnas) de Análise e Desenvolvimento
de Sistema em cinco disciplinas diferentes.
Turma/Disc Matemática Português Programação História OSPB
ADS1-N 8.3 9.1 8.7 9.2 6.5
ADS1-D 7.8 5.9 6.8 6.6 6.7
ADS2-D 8.7 7.4 7.5 7.1 7.3
ADS2-N 7.6 8.2 8.0 9.3 7.6
Tabela 6.1 - Tabela matricial de notas de quatro turmas
6.3 - Declaração de Matrizes no Visualg
Embora existam linguagens de programação que consideram o
índice do primeiro elemento de uma matriz como sendo 0 (zero),
o Visualg, e muitos outros ambientes de programação iniciam de
1 (um) - tal como é considerado o início da contagem dos seres
humanos -. E para acessar um dos elementos de uma matriz
bidimensional basta digitar o nome da matriz e colocar seus
índices: [linha,coluna] entre colchetes. No caso do esquema da
tabela 6.1, se for considerada a matriz Notas[ ], então Notas[3,2]
é a nota média obtida em Português pela turma ADS2-D, cujo
valor é 6.4. O esquema abaixo indica como seria definida a matriz
Notas[ ] da tabela 6.1.
257
Var Notas: vetor[1..4, 1..5] de real
Declara matriz
Nome da matriz
Comando de declaração
Faixa da primeira dimensão Tipo de dado da matriz
Faixa da segunda dimensão
[1..4] significa que na primeira dimensão (linha) os elementos
têm índices de 1 a 4.
[1..5] significa que na segunda dimensão (coluna) os elementos
têm índices de 1 a 5. O que resulta em 4*5 = 20 notas médias.
E tal como no caso dos vetores, só é possível manipular matrizes
elemento a elemento, e nas operações matemáticas e lógicas,
desde que essas operações sejam possíveis com os tipos de
matrizes envolvidas. O trecho de programa abaixo calcula e
mostra a média das notas médias em “Português” da tabela 6.1.
...
Var Notas: vetor[1..4, 1..5] de real
Soma, Media: real
j: inteiro
... Turma
Soma 0 Português
Para j De 1 Ate 4 Faca
Soma Soma + Notas[j,2]
FimPara
Media Soma/4
EscrevaLn("Média das notas médias em Português:
", Media)
...
258
Agora, suponha que seja interessante para a coordenadora do
curso de ADS saber a média da turma ADS2-D nas cinco
disciplinas. O fragmento de código abaixo é uma solução, em
Visualg.
...
Var Notas: vetor[1..4, 1..5] de real
Soma, Media: real
j: inteiro
... ADS2-D
Soma 0
Disciplina
Para j De 1 Ate 5 Faca
Soma Soma + Notas[3,j]
FimPara
Media Soma/5
EscrevaLn("Média das notas médias da turma ADS2-
D: ", Media)
...
6.4 - Leitura e Escrita de uma Matriz
No caso de vetor basta um loop para ler/escrever seus elementos;
já, para uma matriz, o número de loops será igual ao número de
dimensões que ela possui; para matrizes bidimensionais
(suportadas pelo Visualg) serão dois loops.
Por exemplo, considerando as notas da matriz Notas[ ]
esquematizada na tabela 6.1, a leitura e escrita das notas
poderiam ser feitas de acordo com o programa
“LeEscreveMatriz1”, com solução de atribuição direta dos
valores daquela tabela, que pode ser visto na figura 6.3.
259
Figura 6.3 - O programa “LeEscreveMatriz1” no editor do Visualg
O programa “LeEscreveMatriz2” da figura 6.4, lê os elementos
de uma matriz com dimensões mxn, com m linhas e n coluna,
determinadas pelo usuário.
260
Figura 6.4 - Código-fonte do programa “LeEscreveMatriz2” no editor
Nota: Observe a instrução Escreval("") - para saltar linha - depois
do loop j na exibição da matriz no programa “LeEscreveMatriz2”.
Ela é fundamental para que cada linha da matriz seja
individualmente impressa, mostrando os elementos na forma de
tabela. Se não houvesse essa instrução nesse local todos os
elementos da matriz seriam exibidos sequencialmente, um atrás do
outro e numa mesma linha.
261
6.5 - Operações com Matrizes
Em princípio, as quatro operações aritméticas podem ser
executadas usando matrizes; entretanto, por se tratar de um
arranjo de elementos com certa lógica, algumas restrições são
impostas, já que os resultados nem sempre são números puros.
6.5.1 - Adição de Matrizes
Para que seja possível somar duas matrizes é necessário que
ambas sejam da mesma ordem: mesmo número de linhas (m) e o
mesmo número de colunas (n). O resultado dessa operação é uma
matriz que também terá as mesmas dimensões (mxn) das duas
matrizes. A operação de adição é feita elemento a elemento:
A(mxn) + B(mxn) = C(mxn) de modo que:
a(11) + b(11) = c(11)
a(21) + b(21) = c(21)
a(31) + b(31) = c(31)
- - - + - - - = - - -
a(mn) + b(mn) = c(mn)
Generalizando para a sintaxe do Visualg fica do seguinte modo:
A[i,j] + B[i,j] = C[i,j] com i=1,m e j=1,n
Observe o esquema abaixo na soma de uma matriz A 3x4 com
uma matriz B 3x4, resultando numa matriz C, também 3x4.
A B C
6 7 5 4 2 2 0 3 8 9 5 7
43 6 8 + 3 1 3 1 = 7 4 9 9
6 5 4 1 2 1 4 2 8 6 8 3
262
Nota: Para somar duas ou mais matrizes, não é necessário que todas
sejam quadradas, mas sim que todas tenham as mesmas dimensões.
O programa “SomaDuasMatrizes” mostra como somar duas
matrizes a partir da leitura de seus elementos. O resultado da
soma é armazenado em uma outra matriz. Todas as três matrizes
são mostradas nas suas formas tabelares.
Algoritmo "SomaDuasMatrizes"
//Faz a soma de duas matrizes mxn lidas pelo teclado fazendo
//validações.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXLIN=20 //define o número máximo de linhas
MAXCOL=20 //define o número máximo de colunas
Var MatA, MatB, MatC: vetor[1..MAXLIN,1..MAXCOL]
de inteiro
i, j, LinMat, ColMat: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2-máx",MAXLIN,": ")
Leia(LinMat)
LinMat <- Int(LinMat)
Ate((LinMat>=2) e (LinMat<=MAXLIN))
Repita
Escreva("Digite o número de colunas da matriz
[min 2-máx",MAXCOL,":")
Leia(ColMat)
ColMat <- Int(ColMat)
Ate((ColMat>=2) e (ColMat<=MAXCOL))
Escreval("")
Escreval("")
LimpaTela
263
{Leitura da matriz A}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz A: ")
Leia(MatA[i,j])
FimPara
Escreval("")
FimPara
Escreval("")
{Leitura da matriz B}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz B: ")
Leia(MatB[i,j])
FimPara
Escreval("")
FimPara
LimpaTela
Escreval("Matriz A na forma tabelar")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatA[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("Matriz B na forma tabelar")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatB[i,j]," ")
FimPara
Escreval("")
FimPara
Escreval("")
{Soma a matriz A com a matriz B para obter a matriz C}
Para i De 1 Ate LinMat Faca
264
Para j De 1 Ate ColMat Faca
MatC[i,j] <- MatA[i,j]+MatB[i,j] //soma
elemento a elemento
FimPara
FimPara
Escreval("")
{Exibe a matriz C na forma tabelar}
Escreval("Matriz C=A+B")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatC[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
FimAlgoritmo //fim do programa "SomaDuasMatrizes"
A figura 6.5 mostra um exemplo de saída do programa
"SomaDuasMatrizes".
Figura 6.5 - Exemplo de saída do programa "SomaDuasMatrizes"
265
6.5.2 - Subtração de Matrizes
Tal como no caso de adição, para subtrair uma matriz de outra é
necessário que ambas tenham as mesmas dimensões. O programa
“SubtraiMatrizes” a seguir, mostra um exemplo de como fazer
esta operação.
Algoritmo "SubtraiMatrizes"
//Faz a subtração de uma matriz de outra, lidas pelo
//teclado.
//Autor: Mário Leite
//------------------------------------------------------
Const MAXLIN=20 //define o número máximo de linhas
da matriz
MAXCOL=20 //define o número máximo de colunas
da matriz
Var MatA, MatB, MatC: vetor[1..MAXLIN,1..MAXCOL]
de inteiro
i, j, LinMat, ColMat: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2-máx",MAXLIN,": ")
Leia(LinMat)
LinMat <- Int(LinMat)
Ate((LinMat>=2) e (LinMat<=MAXLIN))
Repita
Escreva("Digite o número de colunas da matriz
[min 2 - máx",MAXCOL,":")
Leia(ColMat)
ColMat <- Int(ColMat)
Ate((ColMat>=2) e (ColMat<=MAXCOL))
Escreval("")
Escreval("")
LimpaTela
{Leitura da matriz A}
Para i De 1 Ate LinMat Faca
266
Para j De 1 Ate ColMat Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz A: ")
Leia(MatA[i,j])
FimPara
Escreval("")
FimPara
Escreval("")
{Leitura da matriz B}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz B: ")
Leia(MatB[i,j])
FimPara
Escreval("")
FimPara
LimpaTela
Escreval("Matriz A na forma tabelar")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatA[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("Matriz B na forma tabelar")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatB[i,j]," ")
FimPara
Escreval("")
FimPara
Escreval("")
{Subtrai matriz B da matriz A para obter a matriz C}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
267
MatC[i,j] <- MatA[i,j] - MatB[i,j] //soma
elemento a elemento
FimPara
FimPara
Escreval("")
{Exibe a matriz C na forma tabelar}
Escreval("Matriz C=A-B")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatC[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
FimAlgoritmo //fim do programa "SubtraiMatrizes"
Figura 6.6 - Exemplo de saída do programa "SubtraiMatrizes"
268
6.5.3 - Multiplicação de Matriz por Escalar
Um escalar é um número inteiro; e neste caso, o escalar deve ser
multiplicado por cada elemento da matriz, num processo bem
fácil de entender. Veja esquema na figura 6.7a, onde a matriz M
deve ser multiplicada por um escalar de valor 3.
Figura 6.7a - Esquema do produto de uma matriz por um escalar
O programa "MultiplicaMatrizPorEscalar" mostra como pode
ser feita a multiplicação de uma matriz 3x3 de inteiros por um
escalar, e a figura 6.7b exibe um exemplo de saída deste
programa.
269
Algoritmo "MultiplicaMatrizPorEscalar"
//Multiplica uma matriz por um escalar e exibe o
//resultado na forma tabelar.
//Autor: Mário Leite
//-----------------------------------------------------
Var M, R: vetor[1..3,1..3] de inteiro
i, j, Num: inteiro
Inicio
{Leitura do escalar}
Escreva("Digite o valor do escalar: ")
Leia(Num)
Num = Int(Num) //garante um escalar inteiro
Escreval("")
{Leitura da matriz M[]}
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
Escreva("Digite o elemento [",i,j,"] da
matriz M: ")
Leia(M[i,j])
FimPara
FimPara
Escreval("")
{Exibe a matriz M}
Escreval("Matriz lida")
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
Escreva(M[i,j], " ")
FimPara
Escreval("")
FimPara
{Faz a multiplicação do escalar Num pela matriz M}
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
R[i,j] <- Num*M[i,j]
FimPara
FimPara
Escreval("")
{Exibe a matriz R}
Escreval("Matriz resultante")
Para i De 1 Ate 3 Faca
270
Para j De 1 Ate 3 Faca
Se(R[i,j]<10) Entao //apenas para tabular
melhor a saída
Escreva(R[i,j], " ")
Senao
Escreva(R[i,j], " ")
FimSe
FimPara
Escreval("")
FimPara
Escreval("")
FimAlgoritmo //fim do programa
Figura 6.7b - Saída do programa "MultiplicaMatrizPorEscalar"
2716.5.4 - Multiplicação de Matriz por Vetor
A multiplicação de uma matriz por outra matriz não é feita,
exatamente, elemento a elemento, correspondentes, como no caso
da adição e subtração; para que a multiplicação seja possível é
necessário que o número de colunas da primeira seja igual ao
número de linhas da segunda. Deste modo, sendo os vetores casos
particulares de matrizes, então também é possível multiplicar
matriz por vetor, e vice-versa, observando esse detalhe. Observe
o esquema da figura 6.8a, mostrando a matriz M do item anterior
sendo multiplicada pelo vetor V, resultando numa matriz R..
1 2 3 1 14
4 5 6 * 2 = 32
7 8 9 3 50
Matriz M Vetor V Matriz R
Figura 6.8a - Multiplicação de uma matriz por um vetor
O produto é feito [linha*coluna] e somando os resultados de cada
produto obtido; observe o esquema abaixo.
Matriz A Vetor V Resultado
Linha1 → Coluna1: 1*1 + 2*2 + 3*3 = 14
Linha2 → Coluna1: 4*1 + 5*2 + 6*3 = 32
Linha3 → Coluna1: 7*1 + 8*2 + 9*3 = 50
272
Note que a matriz resultando R tem o mesmo número de linhas
da primeira (3) e o mesmo número de colunas da segunda (1).
Algoritmo "MultiplicaMatrizPorVetor"
//Lê uma matriz 3x3 e um vetor de 3 elementos; multiplica
//a matriz pelo //vetor.
//Autor: Mário Leite
//-------------------------------------------------------
Var Mat: vetor[1..3,1..3] de inteiro
Vet, Resultados: vetor[1..3] de inteiro
i, j, Soma: inteiro
Inicio
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
Escreva("Digite o elemento [",i,",",j,"] da
matriz: ")
Leia(Mat[i,j])
FimPara
FimPara
Escreval("")
Para i De 1 Ate 3 Faca
Escreva("Digite o elemento [",i,"] do vetor: ")
Leia(Vet[i])
FimPara
Para i De 1 Ate 3 Faca
Soma <- 0
Para j De 1 Ate 3 Faca
Soma <- Soma + Mat[i,j] * Vet[j]
FimPara
Resultados[i] <- Soma
FimPara
Escreval("")
Escreval("")
Escreval("Matriz resultante")
Para i De 1 Ate 3 Faca
Escreval(Resultados[i])
FimPara
Escreval("")
FimAlgoritmo
273
A figura 6.8b mostra a saída do programa
"MultiplicaMatrizPorVetor
Figura 6.8b - Saída do programa “MultiplicaMatrizPorVetor”
6.5.5 - Multiplicação de Matriz por Matriz
Neste caso, uma regra fundamental tem que ser respeitada: “o
número de colunas da primeira tem que ser o igual ao número de
linhas da segunda”. Por exemplo: para multiplicar uma matriz
M1 por outra matriz M2 (M1*M2) o número de colunas de M1
tem que ser igual ao número de linhas de M2. E como o produto
de duas matrizes não é comutativo, então, para fazer o produto de
M2*M1 o número de colunas de M2 tem que ser igual ao número
de linhas de M1.
Supondo que M1[L1,C1] seja a primeira matriz e M2[(L2,C2] a
segunda; então, o produto M1*M2 só será válido se C1=L2. O
resultado será uma matriz M[L1,C2].
274
O produto entre duas matrizes só será comutativo no caso em que
ambas forem quadradas e de mesma dimensão. Para duas
matrizes genéricas, A e B, é válida a expressão:
(AB)ij = Σ(airbrj) = ai1b1j + ai2b2j + ai3b3j + ... + ainbnj
O esquema da figura 6.9a mostra um esquema para obter o
produto de duas matrizes A e B, sendo: A com dimensões 3x4 e
B com dimensões 4x4, resultando na matriz C(3x4).
Figura 6.9a - Esquema de multiplicação de uma matriz por outra
Por exemplo, para obter C[1,1], pelo esquema mostrado acima,
teremos:
C[1,1]= a11b11 + a12b21 +a13b31 + a14b41= 1*1+2*2+ 3*2+4*1 = 15
Então, o resultado para C = A*B será o seguinte:
15 36 51 57
30 72 102 114
24 59 83 92
O programa “MultiplicaMatrizes” é uma solução desse tipo de
produto, considerando uma situação em que o número máximo
de linhas e de colunas seja 10 (sendo possível alterar esse valor
das constantes).
275
Nota: Observe que, devido à restrição de produto de matrizes, a matriz
A é a primeira e B a segunda (tal como mostra a figura 6.9a). Assim, o
programa faz o produto A*B e não B*A (não faz a validação da
possibilidade deste segundo produto).
Algoritmo "MultiplicaMatrizes"
//Faz o produto de duas matrizes.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXLIN=10
MAXCOL=10
Var A, B, C: vetor[1.. MAXLIN,1..MAXLIN] de real
SomaProd: real
i, j, k, LinMatA, ColMatA: inteiro
LinMatB, ColMatB: inteiro
Inicio
{Leitura e validação da matriz A}
Repita
Escreva("Digite o número de linhas da matriz A
[min2-máx",MAXLIN,"]:")
Leia(LinMatA)
LinMatA <- Int(LinMatA)
Ate((LinMatA>=2) e (LinMatA<=MAXLIN))
Repita
Escreva("Digite número de colunas da matriz
A[min 2-máx",MAXCOL,"]:")
Leia(ColMatA)
ColMatA <- Int(ColMatA)
Ate((ColMatA>=2) e (ColMatA<=MAXCOL))
Escreval("")
{Leitura e validação da matriz B}
Repita
Escreva("Digite número de linhas da matriz B
[min 2-máx",MAXLIN,"]:")
Leia(LinMatB)
LinMatB <- Int(LinMatB)
276
Ate((LinMatB>=2) e (LinMatB<=MAXLIN))
Repita
Escreva("Digite número de colunas da
B[min 2 máx",MAXCOL,"]:")
Leia(ColMatB)
ColMatB <- Int(ColMatB)
Ate((ColMatB>=2) e (ColMatB<=MAXCOL))
Escreval("")
LimpaTela
{Leitura da matriz A}
Para i De 1 Ate LinMatA Faca
Para j De 1 Ate ColMatA Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz A: ")
Leia(A[i,j])
FimPara
FimPara
Escreval("")
{Leitura da matriz B}
Para i De 1 Ate LinMatB Faca
Para j De 1 Ate ColMatB Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz B: ")
Leia(B[i,j])
FimPara
FimPara
LimpaTela
Escreval("Matriz A na forma tabelar")
Para i De 1 Ate LinMatA Faca
Para j De 1 Ate ColMatA Faca
Escreva(A[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("Matriz B na forma tabelar")
Para i De 1 Ate LinMatB Faca
Para j De 1 Ate ColMatB Faca
Escreva(B[i,j]," ")
FimPara
Escreval("")
FimPara
277
Escreval("")
{Faz o produto de A por B}
Escreval("")
Para i De 1 Ate LinMatA Faca
Para j De 1 Ate ColMatB Faca
SomaProd <- 0
Para k De 1 Ate ColMatA Faca
SomaProd <- SomaProd + A[i,k]*B[k,j]
FimPara
{Arredonda para duas decimais}
Se(SomaProd>=0) Entao
C[i,j] <- Int(SomaProd*100+0.50)/100
Senao
C[i,j] <- Int(SomaProd*100-0.50)/100
FimSe
FimPara
FimPara
{Exibe a matriz C=A*B na forma tabelar}
Escreval("Matriz C=A*B na forma tabelar")
Para i De 1 Ate LinMatA Faca
Para j De 1 Ate ColMatB Faca
Escreva(C[i,j]," ")
FimPara
Escreval("")
FimPara.
Escreval("")
FimAlgoritmo //fim do programa "MultiplicaMatrizes"
A figura 6.9b mostra a saída do programa
"MultiplicaMatrizes", baseando nos dados do esquema da
figura 6.9a.
278
Figura 6.9b - Saída do programa “MultiplicaMatrizes”
6.6 - Determinantes de Matrizes
O determinante de uma matriz é definido como sendo “um
número real associado a uma matriz quadrada”. Portanto, o
determinante não é o valor de uma matriz; é um valor numérico
associado a ela. E para calcular o determinante de uma matriz, o
processo utilizado vai depender da ordem (dimensões) dela.
6.6.1 - Determinante de Matrizes de Ordem 2
Para matrizes 2x2 o processo é bem fácil,e a rotina para fazer isto
também é simples. Por exemplo, seja a matriz A abaixo na sua
forma matricial.
1 2
A =
3 4
279
O programa "Determinante2x2" mostra como esse
determinante pode ser calculado.
Algoritmo "Determinante2x2"
//Calcula o determinante de uma matriz 2x2.
//Autor: Mário Leite
//------------------------------------------------------
Var MatA: vetor[1..2,1..2] de real
SomaPos, SomaNeg, detA: real
i, j: inteiro
Inicio
{Leitura da matriz}
Para i De 1 Ate 2 Faca
Para j De 1 Ate 2 Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz: ")
Leia(MatA[i,j])
FimPara
FimPara
LimpaTela
{Exibe a matriz lida na forma tabelar}
Escreval("Matriz Lida:")
Para i De 1 Ate 2 Faca
Para j De 1 Ate 2 Faca
Escreva(MatA[i,j], " ")
FimPara
Escreval("")
FimPara
{Calcula o determinante}
SomaPos <- MatA[1,1]*MatA[2,2]
SomaNeg <- MatA[2,1]*MatA[1,2]
detA <- SomaPos - SomaNeg
Escreval("")
Escreval("")
Escreval("Determinante da matriz lida: ", detA)
Escreval("")
FimAlgoritmo
280
A figura 6.10 exibe a saída do programa "Determinante2x2"
para a matriz A comentada anteriormente.
Figura 6.10 - Saída do programa "Determinante2x2"
6.6.2 - Determinante de Matrizes de Ordem 3
Neste caso, a solução mais implementada é através da clássica
“Regra de Sarrus”[15],, como indicado no esquema da figura 6.11,
onde uma matriz original 3x3 teve suas duas primeiras colunas
repetidas para formar um arranjo 3x5.
Figura 6.11 - Dispositivo para aplicação da “Regra de Sarrus”
281
As setas apontadas para a direita geram fatores do produto
positivo (+) e as apontadas para a esquerda geram fatores do
produto negativo (-). O determinante dessa matriz pode ser dado
pela seguinte expressão algébrica:
det= (a11a22a33+a12a23a31+a13a21a32) - (a13a22a31+a11a23a32+a12a21a33)
O programa "Determinante3x3" mostra como esse
determinante pode ser calculado, e e o resultado pode ser visto na
figura 6.12 para uma matriz 3x3 .
Algoritmo "Determinante3x3"
//Calcula o determinante de uma matriz de 3x3.
//Autor: Mário Leite
//-------------------------------------------------------
Var MatA: vetor[1..3,1..3] de real
SomaPos, SomaNeg, detA: real
i, j: inteiro
Inicio
{Leitura da matriz}
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
Escreva("Entre com o elemento [",i,j,"] da
matriz: ")
Leia(MatA[i,j])
FimPara
FimPara
LimpaTela
{Exibe a matriz lida na forma tabelar}
Escreval("Matriz Lida:")
Para i De 1 Ate 3 Faca
Para j De 1 Ate 3 Faca
Escreva(MatA[i,j], " ")
FimPara
Escreval("")
FimPara
{Calcula o determinante através da "Regra de Sarrus"}
282
SomaPos <- MatA[1,1]*MatA[2,2]*MatA[3,3] +
MatA[1,2]*MatA[2,3]*MatA[3,1]
SomaPos <- SomaPos + MatA[1,3]*MatA[2,1]*MatA[3,2]
SomaNeg <- MatA[1,3]*MatA[2,2]*MatA[3,1] +
MatA[1,1]*MatA[2,3]*MatA[3,2]
SomaNeg <- SomaNeg + MatA[1,2]*MatA[2,1]*MatA[3,3]
detA <- SomaPos - SomaNeg
Escreval("")
Escreval("")
Escreval("Determinante da matriz lida: ", detA)
Escreval("")
FimAlgoritmo
Figura 6.12 - Saída do programa "Determinante3x3"
6.6.3 - Determinante de Matrizes de Ordem Superior a 3
O programa “CalculaDeterminante”, em Visualg, é uma
generalização dos cálculos de determinantes apresentados nos
itens anteriores, calculando o determinante de uma matriz mxm
de qualquer ordem (m>=2). No caso deste programa, as
283
dimensões da matriz lida foi limitada em 10, mas pode ser
generalizado para qualquer número de linhas.
Algoritmo "CalculaDeterminante"
//Calcula o determinante de uma matriz mxm (m>=2)
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXLIN=10 //limita número de linhas da
matriz
Var MatA,MatAx:vetor[0..MAXLIN,0..MAXLIN] de real
MatOrig: vetor[0..MAXLIN,0..MAXLIN] de real
i, j, k, m, Trocas, LinMat, mLin, p, q: inteiro
Detmxm, Aux, Fator: real
Inicio
{Validação e leitura da matriz}
Repita
Escreva("Digite número de linhas da matriz: ")
Leia(LinMat)
LinMat <- Int(Abs(LinMat))
Ate((LinMat>=2) e (LinMat<=MAXLIN))
Escreval("")
Escreval("")
Para p De 1 Ate LinMat Faca
Para q De 1 Ate LinMat Faca
Escreva("Entre com o elemento [",p,q,"]: ")
Leia(MatOrig[p,q]) //matriz original
mLin <- LinMat //preserva o número de linhas
MatA[p,q] <- MatOrig[p,q]
FimPara
Escreval("")
FimPara
{Faz uma cópia da matriz lida para o processamento}
Para i De 0 Ate (LinMat-1) Faca
Para j De 0 Ate (LinMat-1) Faca
MatAx[i,j] <- MatA[i+1,j+1]
FimPara
FimPara
284
Trocas <- 0 //número de permutas de linhas da matriz
{Transforma matriz em triangulo para a "Regra de Chió"}
m <- LinMat
Para i De 0 Ate (m-2) Faca
Se(MatAx[i,i]=0) Entao//detectou elemento [1,1]=0
Para k De i Ate (m-1) Faca //procura um
elemento [1,1]<> 0
Se(MatAx[k,i]<>0) Entao
Para j De 0 Ate (m-1) Faca //permuta
linhas
Aux <- MatAx[i,j]
MatAx[i,j] <- MatAx[k,j]
MatAx[k,j] <- Aux
FimPara
k <- m
FimSe
FimPara
Trocas <- Trocas + 1 //acumula permutas
FimSe
Se(MatAx[i,i]<>0) Entao
{Converte o elemento [1,1] para 1}
Para k De (i+1) Ate (m-1) Faca
Fator <- -1*MatAx[k,i]/MatAx[i,i]
Para j De i Ate (m-1) Faca
MatAx[k,j] <- MatAx[k,j] +
(Fator*MatAx[i,j])
FimPara
FimPara
FimSe
FimPara
Detmxm <- 1.0
{Calcula o determinante}
Para i De 0 Ate (m-1) Faca
Detmxm <- Detmxm*MatAx[i,i]
FimPara
Escreval("")
Escreval("")
285
Se(Trocas Mod 2 <> 0) Entao //permuta ímpar de
linhas
Detmxm <- -Detmxm
FimSe
LimpaTela
{Mostra a matriz na forma tabelar}
Escreval(" Matriz original lida:")
Para p De 1 Ate mLin Faca
Para q De 1 Ate mLin Faca
Escreva(MatOrig[p,q], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("")
Escreval("Determinante da matriz:", Detmxm)
FimAlgoritmo //fim do programa "CalculaDeterminante"
Figura 6.13 - Saída do programa "CalculaDeterminante"
286
6.7 - Matriz Transposta
Dada uma matriz M mxn sua transposta é denotada por MT, tal
que M[m,n] é igual a MT[n,m]; isto é, as linhas da matriz M
tornam-se colunas na matriz MT e as colunas tornam-se linhas na
matriz MT. Matrizes Transpostas são muito importantes na
Álgebra Linear, na resolução de cálculos matriciais. O programa
“MatrizTransposta” que cria e mostra uma matriz transposta a
partir da leitura de uma matriz original. A figura 6.14 mostra a
matriz transposta criada a partir da matriz original lida. Em
seguida é mostrado o código-fonte do programa, em Visualg
Figura 6.14 - Saída do programa "MatrizTransposta"
287
Algoritmo "MatrizTranposta"
//Cria a matriz transposta de uma matriz digitada.
//Autor: Mário Leite
//-------------------------------------------------------
Const MaxLin=10 //limita as dimensões da matriz
MaxCol=10
Var MatO,MatT:vetor[1..MaxLin,1..MaxCol]de inteiroi, j, LinMat, ColMat: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2-máx 10]: ")
Leia(LinMat)
LinMat <- Int((Abs(LinMat))
Ate((LinMat>=2) e (LinMat<=MaxLin))
Repita
Escreva("Digite o número de colunas da matriz
[min 2 - máx 10]: ")
Leia(ColMat)
ColMat <- Int(Abs(ColMat))
Ate((ColMat>=2) e (ColMat<=MaxCol))
Escreval("")
{Lê a matriz original}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva("Digite o elemento [",i,",",j,"] da
matriz: ")
Leia(MatO[i,j])
FimPara
FimPara
Escreval("")
{Exibe a matriz original na forma tabelar}
Escreval(" Matriz original")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatO[i,j], " ")
FimPara
Escreval("")
FimPara
288
Escreval("")
{Cria a matriz transposta}
Para i De 1 Ate ColMat Faca
Para j De 1 Ate LinMat Faca
MatT[i,j] <- MatO[j,i]
FimPara
FimPara
{Exibe a matriz transposta na forma tabelar}
Escreval(" Matriz transposta")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate ColMat Faca
Escreva(MatT[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
FimAlgoritmo
6.8 - Matriz Identidade
Matriz identidade é uma matriz quadrada em que todos os
elementos da diagonal principal têm valor 1 e o restante dos
elementos são todos zeros. Sendo assim, vamos elaborar um
programa para criar uma matriz identidade 3x3.
O programa “MatrizIdentidade”, da figura 6.15a, mostrado no
editor do Visualg, é uma solução para criar uma matriz desse
tipo, e a figura 6.15b o resultado da execução deste programa..
289
Figura 6.15a - Código-fonte do programa "MatrizIdentidade" no editor
290
Figura 6.15b - Matriz Identidade 4x4: Saída de “MatrizIdentidade"
6.9 - Elementos das Diagonais de uma Matriz
Os elementos das diagonais de uma matriz são muito importante
em algumas situações.
O programa “MostrafElementosDasDiagonais" cria uma matriz
4x4 e mostra os elementos das duas diagonais. A figura 6.16
mostra uma saída desse programa, e em seguida seu código-fonte
em Visualg, em texto livre.
291
Figura 6.16 - Saída do programa "MostraElementos das Diagonais"
292
Algoritmo "MostraElementoDasDiagonais"
//Cria uma matriz quadrada mostra os elementos das
//diagonais.
//Autor: Mário Leite
//-------------------------------------------------------
Const MaxLin=10 //limita as dimensões da matriz
Var MatNum: vetor[1..MaxLin,1..MaxLin] de inteiro
VetPrinc,VetSecun:vetor[1..MaxLin] de inteiro
i, j, k, LinMat: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2 - máx 10]: ")
Leia(LinMat)
LinMat <- Int(LinMat)
Ate((LinMat>=2) e (LinMat<=MaxLin))
Escreval("")
{Lê/exibe a matriz}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Escreva("Digite o elemento [",i,",",j,"] da
matriz: ")
Leia(MatNum[i,j])
FimPara
FimPara
Escreval("")
Escreval(" Matriz original")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Escreva(MatNum[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
{Cria vetores com elementos das diagonais}
k <- 0
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Se(i=j) Entao //elemento da diagonal principal
k <- k + 1
293
VetPrinc[k] <- MatNum[i,j]
FimSe
FimPara
FimPara
k <- 0
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Se((i+j)=(LinMat+1)) Então //elemento da
diagonal secundária
k <- k + 1
VetSecun[k] <- MatNum[i,j]
FimSe
FimPara
FimPara
{Exibe os elementos das diagonais}
Escreval("Elementos da Diagonal Principal:")
Para k De 1 Ate LinMat Faca
Escreva(VetPrinc[k], " ")
FimPara
Escreval("")
Escreval("")
Escreval("Elementos da Diagonal Secundária:")
Para k De 1 Ate LinMat Faca
Escreva(VetSecun[k], " ")
FimPara
FimAlgoritmo
❖ Exemplo 6.1 - Ler uma matriz mxn de inteiros e exibir os
pares, os ímpares e os primos com suas respectivas posições.
294
Algoritmo "MostraParesImparesPrimosPosicoes"
//Lê uma matriz mxn de inteiros e exibe os pares, os ímpares
//e os primos com suas respectivas posições.
//Autor: Mário Leite
//-------------------------------------------------------
Const MAXLIN=20 //limita dimensões da matriz
MAXCOL=20
Var MatNum: vetor[1..MAXLIN,1..MAXCOL] de inteiro
i, j, k, NLin, NCol, TotDiv: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2 - max",MAXLIN,"]:")
Leia(NLin)
NLin Int(NLin)
Escreva("Digite o número de colunas da matriz
[min 2-max",MAXCOL,"]:")
Leia(NCol)
NCol Int(NCol)
Escreva("")
Ate((NLin<=MAXLIN) e (NCol<=MAXCOL))
Para i De 1 Ate Nlin Faca
Para j De 1 Ate NCol Faca
Escreva("Digite o elemento [",i,",",j,"] da
matriz: ")
Leia(MatNum[i,j])
MatNum[i,j] Int(MatNum[i,j])
FimPara
FimPara
LimpaTela
{Exibe a matriz lida}
Escreva("Matriz lida:")
Para i De 1 Ate NLin Faca
Para j De 1 Ate NCol Faca
Escreva(MatNum[i,j], " ")
FimPara
Escreval("")
FimPara
295
Escreval("")
Escreval("")
Escreval("Tipo do elemento com sua posição:")
{Acha e exibir os Pares, os Ímpares e os Primos com suas
posições"
}
Para i De 1 Ate NLin Faca
Para j De 1 Ate NCol Faca
Se(MatNum[i,j] Mod 2=0) Entao //elemento par
Se(MatNum[i,j]=2) Entao
Escreval(MatNum[i,j]," ","Par/Primo
","Posição: ","[",i,j,"]")
Senao
Escreval(MatNum[i,j]," ", "Par ",
"Posição: ","[",i,j,"]")
FimSe
Senao
{Verifica se o elemento é primo}
TotDiv 0
Para k De 1 Ate MatNum[i,j] Faca
Se(MatNum[i,j] Mod k = 0) Entao
TotDiv TotDiv + 1
FimSe
FimPara
Se((TotDiv<3)e(MatNum[i,j]<>1))Entao //O
elemento é primo
Escreval(MatNum[i,j]," ","Primo
","Posição: ","[",i,j,"]")
Senao
Escreval(MatNum[i,j]," ","Ímpar
","Posição: ","[",i,j,"]")
FimSe
FimSe
FimPara
FimPara
Escreval("")
FimAlgoritmo //fim do programa
296
A figura 6.17 mostra uma saída do programa
"MostraParesImparesPrimosPosicoes".
Figura 6.17 - Saída do "MostraParesImparesPrimosPosicoes"
❖ Exemplo 6.2 - Criar uma matriz quadrada com as diagonais
(principal e secundária) formadas pela letra "X".
O programa "CriaMatrizX" é uma solução para o Exemplo 6.2.
Observe que, de acordo com a matemática, os elementos da
diagonal da matriz sempre terão índices i,j iguais (i=j); então, é
através dessa lógica que a solução do problema se desenvolve.
297
Algoritmo "CriaMatrizX"
//Cria uma matriz quadrada apenas com as diagonais formadas
//pela letra "X".
//Autor: Mário Leite
//-------------------------------------------------------Var MatX: vetor[1..20,1..20] de caractere
i, j, NLin: inteiro
m: real
Inicio
m <- 1
Enquanto ((m<5) ou (m>20)) Faca
Escreva("Digite o número de linhas da matriz:")
Leia(m)
FimEnquanto
Escreval("")
Se(NLin Mod 2 = 0) Entao //procura o próximo ímpar
NLin <- NLin + 1
FimSe
{Criação/impressão da matriz de "X"}
Para i De 1 Ate NLin Faca
Para j De 1 Ate NLin Faca
Se((i=j) ou (i+j=NLin+1)) Entao
MatX[i,j] <- "X"
Senao
MatX[i,j] <- " "
FimSe
Escreva(MatX[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("")
FimAlgoritmo
298
A figura 6.18 mostra uma saída do programa "CriaMatrizX"
para matriz 12x12
Figura 6.18 - Saída do programa "CriaMatrizX"
6.10 - Exercícios Propostos
1 - O que são matrizes? Qual é a diferença entre matrizes e
vetores?
2 - Como se declara uma matriz no Visualg?
3 - As matrizes podem ter algum elemento de tipo diferente dos
demais? Explique.
4 - Dê um exemplo de uma matriz quadrada.
5 - Leia dois vetores de inteiros de tamanho dez e crie uma matriz,
de modo que as colunas dessa matriz seja formada por esses dois
vetores.
299
6 - Observe as alternativas de declarações de uma matriz Mat[ ]
abaixo, e marque qual delas está correta na sintaxe do Visualg.
A ( ) Var Mat: vetor[1..5,1..4] de inteiro
B ( ) Var Mat: mat[1..5,1..4] de inteiro
C ( ) Var Mat: vetor[5,4] de logico
D ( ) Var Mat: vetor[1..5:1..4] de caractere
E ( ) Var Mat: mat[1..5:1..4] de real
7 - Observe o programa “ZZZ” abaixo e explique qual é o
objetivo da estrutura de decisão composta, em destaque no
código-fonte.
Algoritmo "ZZZ"
Var MatD: vetor[1..7,1..7] de caractere
i, j: inteiro
Inicio
Para i De 1 Ate 7 Faca
Para j De 1 Ate 7 Faca
Se((i=j) ou (i+j=8)) Entao
MatD[i,j] <- "X"
Senao
MatD[i,j] <- " "
FimSe
Escreva(MatD[i,j], " ")
FimPara
Escreval("")
FimPara
FimAlgoritmo
8 - O programa abaixo foi feito para criar a matiz transposta de
uma matriz quadrada lida pelo teclado, de no máximo cinco
linhas. Complete o código nas linhas tracejadas.
300
Algoritmo "MatrizTranposta"
//Cria a matriz transposta de uma matriz digitada.
//-------------------------------------------------------
Var MatO, MatT: vetor[1..5,1..5] de inteiro
i, j, LinMat, ColMat: inteiro
Inicio
Repita
Escreva("Digite o número de linhas da matriz
[min 2-máx 5]: ")
Leia(LinMat)
LinMat <- Int(LinMat)
Ate((LinMat>=2) e (LinMat<=5))
Escreval("")
LimpaTela
{Lê a matriz original MatO}
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Escreva("Digite o elemento [",i,",",j,"] da
matriz: ")
Leia(MatO[i,j])
FimPara
FimPara
Escreval("")
{Exibe a matriz original na forma tabelar}
Escreval(" Matriz original")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Escreva(MatO[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
{Cria a matriz transposta MatT}
------------------------------
------------------------------
------------------------------
------------------------------
------------------------------
301
{Exibe a matriz transposta na forma tabelar}
Escreval(" Matriz transposta")
Para i De 1 Ate LinMat Faca
Para j De 1 Ate LinMat Faca
Escreva(MatT[i,j], " ")
FimPara
Escreval("")
FimPara
Escreval("")
FimAlgoritmo
9 - Observe a tabela abaixo, que mostra as notas obtidas por um
aluno em três disciplinas ao longo de oito meses. Crie um
programa que mostre as médias desse aluno em cada disciplina,
para esses valores de notas.
Disciplina/Mês Mar Abr Mai Jun Ago Set Out Nov
Português 8.3 7.8 7.0 6.9 8.0 7.5 7.0 8.8
Matemática 7.5 7.8 7.9 7.2 8.2 7.2 8.5 8.4
Informática 9.0 8.7 8.8 8.6 8.4 9.3 9.0 8.7
Tabela Disciplina x Mês com as respectivas notas
10 - Crie um programa que exiba uma matriz quadrada de dez
colunas, tal que as linhas ímpares sejam formadas pela letra “X”,
e as linhas pares pela letra “Y”.
11 - Observe o código-fonte do programa abaixo, e explique o
que ele faz.
302
Algoritmo "CriaMatriz"
Var i, j, k, m, x, y: inteiro
Matriz: vetor[1..10,1..10] de inteiro
a: logico
Inicio
LimpaTela
Repita
Escreva("Digite um valor inteiro e positivo: ")
Leia(m)
Ate((m>=2) e (m<=10))
Para j De 1 Ate m Faca
Para k De 1 Ate m Faca
a <- Falso
Enquanto (Nao(a)) Faca
Repita
Escreva("Digite um número inteiro e
positivo: ")
Leia(x)
Ate(x<>0)
x <- Abs(Int(x))
y <- 0
Para i De 1 Ate x Faca
Se(x Mod i = 0) Entao
y <- y + 1
FimSe
FimPara
Se(y=2) Entao
Matriz[j,k] <- x
a <- Verdadeiro
FimSe
FimEnquanto
FimPara
FimPara
Para j De 1 Ate m Faca
Para k De 1 Ate m Faca
Escreva(Matriz[j,k], " ")
FimPara
Escreval("")
FimPara
FimAlgoritmo
303
Capítulo 7 - Trabalhando com Registros
7.1 - Introdução ao Capítulo
Embora o termo “registro” seja considerado, por alguns, como
um assunto avançado de “estrutura de dados” em cursos de
Sistemas de Informações e Ciência da Computação, aqui ele será
mostrado como uma extensão e complemento de vetores e
matrizes, para mostrar que vários tipos de dados podem ser
reunidos em um cadastro, representado por uma variável especial:
variável-registro. O Visualg oferece recursos para trabalhar com
com esse tipo de dado heterogêneo, tal como uma linguagem de
programação real. Neste capítulo serão mostrados vários
exemplos de como utilizar um registro.
7.2 - Conceitos Básicos
Os dois capítulos anteriores focalizaram elementos que definem
uma estrutura de dados homogênea (vetores e matrizes).
Naqueles casos, embora a variável pudesse armazenar muitos
valores ao mesmo tempo, todos os valores tinham que ser de um
mesmo tipo de dado. Entretanto, existem situações em que há
necessidade de trabalhar com valores de tipos de dados diferentes
numa mesma variável; nesses casos as estruturas homogêneas não
podem ser empregadas; utiliza-se estruturas heterogêneas,
definidas pelos registros.
Um registro define as especificações de uma variável composta
de “campos” que podem ser de diferentes tipos de dados. Assim,
um conjunto de registro define uma tabela, tal como acontece
num ambiente de banco de dados, com valores de tipos diferentes.
Por exemplo, seja uma turma de alunos em que cada um deles
304
tenha, obrigatoriamente, os seis seguintes dados cadastrais, com
os respectivos tipos de dados:
• Matricula (inteiro)
• Nome (caractere)
• Sexo (caractere)
• Data de nascimento (caractere)
• Renda Familiar (real)
• Transferido (logico)
Deste modo, observe que uma variável do tipo array (vetor ou
matriz) não poderia ser utilizada para manipular o cadastro de um
aluno, pois os dados são de tipos diversas; mas, utilizando um
registro isto é perfeitamente possível. A criação de um registro é
conhecida no ambiente de desenvolvimento como “criação de um
novo tipo de dado”, pois, é isto o que efetivamente é feito. O
esquema a seguir mostra como deve ser criada uma estrutura do
tipo registro no Visualg.
Palavra-chave que define um novo tipo de dadoIndica que é um registro
Tipo NomeRegistro = registro
campo1: tipo
campo2: tipo
campo3: tipo
- - - campos com seus tipos
- - -
campoN: tipo
FimRegistro fim da estrutura do registro
NomeRegistro é o identificador (nome) do registro, tal como o
de uma variável simples.
305
7.3 - Manipulação de Registros
Para trabalhar com registros são necessários dois passos:
1) Criar o registro;
2) Cria uma variável do tipo-registro.
Só DEPOIS de executar esses dois passos é que se pode trabalhar
com o registro, manipulando uma variável-registro. Como
exemplo, será criado o registro de um aluno com os dados
sugeridos anteriormente: Matrícula, Nome, Sexo, Data de
Nascimento, Renda familiar e Transferido; estes dados são
chamados campos do registro.
1 - Criação do registro:
Tipo TAluno = registro
matric: inteiro
nome: caractere
sexo: caractere
nasc: caractere
renda: real
transf: logico
FimRegistro
2 - Criação da variável-registro
Var Aluno: TAluno
Portanto, só DEPOIS desses dois passos é que o registro poderá
ser utilizado no programa, com a inicialização dos campos da
variável-registro através de atribuições diretas ou de leituras de
seus campos.
306
Nota: Observe que para o identificador da variável-registro foi usado o
termo “Aluno”, retirando apenas o “T” do identificador do registro.
Este será o estilo empregado aqui neste livro (estilo dos autores) e não
uma regra geral. Os identificadores, tanto do registro quanto da
variável-registro, podem ser quaisquer, desde que diferentes um do
outro e obedecendo as regras de identificação de variáveis. Por
exemplo, poderia ser “CadastroGeral” para o identificador do registro
e simplesmente “Aluno” para a variável-registro. Entretanto, como
regra de boa programação e estilo, é melhor que o identificador da
variável-registro fique ligada ao identificador do registro, tornando a
manutenção e percepção do programa muito mais fácil para o
programador.
Para o identificador do registro foi considerado o estilo Pascal/Delphi,
onde o T (maiúsculo) indica Tipo, oriundo das linguagens da linha
turbo: Turbo Pascal, Turbo C, Turbo Basic, etc.
Outro detalhe, muito importante a ser observado é como os dados
devem ser atribuídos para serem armazenados na variável-
registro.
variável-registro.campo ← valor
ponto de ligação
O ponto de ligação (.) vincula o campo à variável-registro em
questão. O valor tem que ser do mesmo tipo de dado do
respectivo campo que o está “recebendo”; se não dará erro de
“incompatibilidade de dado”. Por exemplo, para atribuir, ou ler o
sexo de um aluno:
307
Aluno.sexo ← "F" //atribuição direta
Leia(Aluno.sexo) //leitura pelo teclado
O programa "CadastroAlunos", na figura 7.1, mostra um
exemplo básico e bem simples (sem validações) de como fazer o
cadastro de 25 alunos, baseado no registro sugerido
anteriormente.
Figura 7.1 - Código-fonte do programa “CadastroAlunos” no editor
308
Observem que, por não ser um tipo de dado primitivo, o tipo de
dado da variável-registro não aparece sublinhado no editor do
Visualg. E conforme foi dito anteriormente, o programa
“CadastroAlunos”, não faz nenhuma validação dos dados
entrados; mas, na prática, essas validações são muito importantes
para evitar erros drásticos nos resultados esperados. Por exemplo,
se não for validado o “sexo” do aluno o usuário poderia entrar
com qualquer letra (“X”, “Y”, “Z”, etc), e na hora de listar os
alunos de um dos sexos (“M” ou “F”) a listagem sairia
incompleta, pois não seriam considerados alunos com sexo
diferente de “M” e “F”. Também, a data de nascimento esta deve
ser SEMPRE validada para evitar um “dia” com valor inferior a
28 ou superior a 31, um “mês” com valor inferior a 1 ou superior
a 12, e assim por diante. O mesmo vale para os outros campos.
Deve ficar bem claro que pode ser criado um registro agregando
vários tipos de dados nos seus campos, inclusive arrays[16].
Fazendo uma comparação: enquanto nas matrizes cada elemento
é individualizado através de seus índices, num registro cada
campo é individualizado pela referência ao nome de uma variável
do tipo registro, como na figura 7.2 mostra uma representação
“física” dos dados de um empregado.
Figura 7.2 - Exemplo de uma ficha de um empregado como um registro
309
7.4 - Conjunto de Registros
A figura 7.2 representa uma fica com os dados de apenas 1 (um)
empregado; portanto, UM registro de uma entidade. Para vários
empregados (equivalente a uma tabela no ambiente de Banco de
Dados) é necessário que a variável-registro seja um array, como
foi feito no programa “CadastroAlunos”. Por exemplo,
suponhamos um conjunto de 300 empregados; então a variável
registro deverá ser um vetor com 300 elementos.
Tipo TEmpregado = registro
nome: caractere
matr: inteiro
sexo: caractere
situa: caractere
ende: caractere
cidade: caractere
estado: caractere
cep: caractere
func: caractere
sala: real
admis: caractere
setor: caractere
FimRegistro
Var: Empregado: vetor[1..300] de TEmpregado
O conceito de registro pode ser aplicado para fazer pesquisa de
valores. Os “campos” de um registro se comportam tal como os
campos de uma tabela, fisicamente representados por colunas,
enquanto cada registro representa uma linha dessa tabela. A
tabela 7.1 ilustra um exemplo de tabela dos dados de quatorze
funcionários.
310
Matrícula Nome Setor Salário
1235-20 Cremilda Martins de Souza Contabilidade 1.985,50
1236-19 Creuza da Conceição Dias Pessoal 1.990,35
1237-20 Expedito Cassim de Oliveira Vendas 3.100,32
1238-20 Jefferson de Oliveira Santos Produção 2.875,34
1239-19 Juvino Pereira Alves Almoxarifado 2.860,45
1240-19 Lucycleide Pereira da Costa Pessoal 3.210,54
1241-20 Marinete Correa de Castro Vendas 3.350,40
1242-18 Marlene Figueira Alves Perucci Almoxarifado 2.880,29
1243-19 Ronilson Marques Pereira Contabilidade 1.950,47
1244-18 Rosicleide Maria de Jesus Pessoal 1.954,75
1245-18 Sidnelson Correa de Castro Produção 2.982,75
1246-20 Jucimário Correa de Castro Pessoal 2.150,48
1247-19 Cleonice Romão Santana Vendas 3.420,45
1248-19 Dioney P. dos Santos Pacheco Produção 2.874,42
Tabela 7.1 - Exemplo de uma tabela com dados de funcionários
Assim, de acordo com a tabela 7.1, a definição de um (apenas
um) registro que representará TODOS com as mesmas
características, é definido, assim, no Visualg:
311
Tipo TFuncionarios: registro
matricula: caractere
nome: caractere
setor: caractere
salario: real
FimRegistro
A estrutura acima define um registro; e uma variável do tipo
registro, que alocará valores na memória, por exemplo, Func,
será assim definida:
Var Func: TFuncionarios
E para trabalhar com vários registros, na prática (tal como a
tabela 7.1), a variável-registro deverá se um vetor, assim::
Var VetFunc: vetor[1..14] de TFuncionarios
Nota: O identificador VetFunc foi assim definido, apenas para
diferenciar da variável de um registro simples, como o anterior,
(para apenas um registro); mas, poderia ser Func também, desde
que definida como vetor.
7.5 - Leitura de um Conjunto de Registros
A leitura de um conjunto de registros é feita mediante um loop
que varre todos os registros do conjunto, campo a campo. O
programa “LeEmpregados” mostra como pode ser feito. dentro
de um loop com o seguinte formato:
312
Algoritmo "LeEmpregados"
//Lê um conjunto de registros sem validações.
//Autor: Mário Leite
//-------------------------------------------------------
Tipo TEmpregado = registro
nome: caractere
matr: inteiro
sexo: caractere
situa: caractere
ende:caractere
cida: caractere
uf: caractere
cep: caractere
func: caractere
sala: real
admis: caractere
setor: caractere
FimRegistro
Var Empregado: vetor[1..300] de TEmpregado
j: inteiro
Inicio
{Loop de leitura dos dados dos empregados}
Para j De 1 Ate 300 Faca
Escreva("Entre a matrícula do empregado: ")
Leia(Empregado[j].matr)
Escreva("Entre o nome do empregado: ")
Leia(Empregado[j].nome)
Escreva("Entre o sexo do empregado: ")
Leia(Empregado[j].sexo)
Escreva("Entre a situação atual do empregado
[Efetivo/Temporário: ")
Leia(Empregado[j].situa)
Escreva("Entre com endereço do empregado: ")
Leia(Empregado[j].ende)
Escreva("Entre com a cidade do empregado: ")
Leia(Empregado[j].cida)
Escreva("Entre com o estado: ")
Leia(Empregado[j].uf)
Escreva("Entre com o CEP do endereço: ")
Leia(Empregado[j].cep)
313
Escreva("Entre com a função do empregado: ")
Leia(Empregado[j].func)
Escreva("Entre com o salário bruto: ")
Leia(Empregado[j].sala)
Escreva("Entre com a data de admissão: ")
Leia(Empregado[j].admis)
Escreva("Entre com o nome do setor: ")
Leia(Empregado[j].setor)
Escreval("") //salta linha para um novo registro
FimPara //fim do loop de leitura dos dados dos
Escreval("")
FimAlgoritmo
❖ Exemplo 7.1 - O programa "ControleEmpregados" faz o
registro de cinco empregados e calcula: Valor da folha de
pagamento, maior salário, menor salário e salário médio.
Algoritmo "ControleEmpregados"
//Faz o registro de vários empregados e calcula: valor
//da folha de pagamento maior salário, menor salário e
//salário médio.
//Autor: Mário Leite
//-----------------------------------------------------
Tipo TEmpregado = registro
Matr: inteiro
Nome: caractere
Salario: real
FimRegistro
Var Empregado: TEmpregado
j,k, n: inteiro
SalMedio, Maior, Menor, Soma: real
NomeMa, NomeMe: caractere
Inicio
Escreva("Entre com o número de empregados: ")
Leia(n) //considere n válido
Escreval("")
Soma <- 0
Para j De 1 Ate n Faca
314
Escreva("Entre com o nome do empregado: ")
Leia(Empregado.Nome)
Escreva("Entre com a matrícula de ",
Empregado.Nome, ": ")
Leia(Empregado.Matr)
Repita
Escreva("Entre com o salário de ",
Empregado.Nome, ": ")
Leia(Empregado.Salario)
Ate(Empregado.Salario>0)
Soma <- Soma + Empregado.Salario
Se(j=1) Entao //é o primeiro empregado!?
Maior <- Empregado.Salario
Menor <- Empregado.Salario
NomeMa <- Empregado.Nome
NomeMe <- Empregado.Nome
FimSe
Se(Empregado.Salario>Maior) Entao
Maior <- Empregado.Salario
NomeMa <- Empregado.nome
FimSe
Se(Empregado.Salario<Menor) Entao
Menor <- Empregado.Salario;
NomeMe <- Empregado.Nome
FimSe
Escreval("")
FimPara //salta linha para ler um novo registro
SalMedio <- Soma/n
LimpaTela
Escreval("Relatório final sobre a Folha Salarial")
Escreval("----------------------------------")
Escreval("Maior salário: ",Maior,"==>", NomeMa)
Escreval("Menor salário:",Menor,"==>", NomeMe)
Escreval("Folha de pagamento: ", Soma:4:2)
Escreval("Salário médio: ", SalMedio:4:2)
Escreval("")
FimAlgoritmo
315
As figuras 7.3a e 7.3b mostram, respectivamente, as entradas
para cinco empregados e a saída do programa
Figura 7.3a - Entradas para o programa "ControleEmpregados"
316
Figura 7.3b - Saída do programa "ControleEmpregados"
❖ Exemplo 7.2 - Considerar cinco alunos, cada um cadastrado
com os seguintes dados:
• nome (caractere)
• nota1 (real)
• nota2 (real)
• nota3 (real)
• nota4 (real)
O programa terá que ler os dados de cinco alunos, calcular a
média aritmética das notas de cada um deles, e verificar se foi
“Aprovado” (média maior ou igual de 7) ou “Reprovado” (média
317
menor que 7). O programa “MediaRegistro”, mostrado na figura
7.4, é uma solução para o problema do Exemplo 7.2.
Figura 7.4 - Código-fonte do programa “MediaRegistro” no editor
318
7.6 - Pesquisa em Conjunto de Registros
A pesquisa num conjunto de registro pode ser feita em função de
algum campo, semelhantemente ao caso de arrays. É claro que a
pesquisa deve ser feita por um campo que tenha um valor único;
na maioria dos casos uma chave. Considere uma empresa com
200 funcionários, onde cada um tem uma ficha com os dados:
• Matrícula (inteiro)
• Nome (caractere)
• Setor (caractere)
• Salario (real)
O programa “PesqFuncionario” faz a leitura, ordena os registros
e faz pesquisa de um determinado funcionário.
Algoritmo "PesqFuncionario"
//Pesquisa um funcionário pela sua matrícula no cadastro
//de uma empresa.
//Autor: Mário Leite
//-------------------------------------------------------
Tipo TFunc = registro
matric: inteiro
nome: caractere
setor: caractere
salario: real
FimRegistro
Var Func: vetor[1..100] de TFunc //define variável-
vetor de registro
i, j, Local, Mat, PosIni, PosFim, PosCent,
AuxMatric: inteiro
AuxNome, AuxSetor: caractere
AuxSalario: real
Achou: logico
Inicio
{Loop para leitura dos dados dos funcionários}
Para j De 1 Ate 5 Faca //considera 5 funcionários
Escreva("Digite a matrícula do funcionário: ")
Leia(Func[j].matric)
319
Repita //valida matricula
Escreva("Digite a matrícula do funcionário: ")
Leia(Func[j].matric)
Ate(Func[j].matric)>0)
Escreva("Digite o nome do funcionário: ")
Leia(Func[j].nome)
Escreva("Digite o setor do funcionário: ")
Leia(Func[j].setor)
Repita
Escreva("Digite o salário do funcionário: ")
Leia(Func[j].salario)
Ate((Func[j].salario)>0)
Escreval("") //salta linha para um novo funcionário
FimPara //fim do loop para leitura dos dados
Escreval("")
Escreva("Entre com a matrícula a ser pesquisada:")
Leia(Mat)
{Ordena funcionários pela matr para "Pesquisa Binária"}
Para i De 1 Ate 4 Faca
Para j De (i+1) Ate 5 Faca
Se(Func[i].matric>Func[j].matric) Entao
{Salva dados em variáveis auxiliares antes
AuxMatric <- Func[i].matric
AuxNome <- Func[i].nome
AuxSetor <- Func[i].setor
AuxSalario <- Func[i].salario
{Faz a trocas}
Func[i].matric <- Func[j].matric
Func[j].matric <- AuxMatric
Func[i].nome <- Func[j].nome
Func[j].nome <- AuxNome
Func[i].setor <- Func[j].setor
Func[j].setor <- AuxSetor
Func[i].salario <- Func[j].salario
Func[j].salario <- AuxSalario
FimSe
FimPara
FimPara
Escreval("")
Local <- 0
PosIni <- 1
320
PosFim <- 5 //número de funcionários
Achou <- Falso
{Loop para fazer a pesquisa}
Enquanto ((PosIni<=PosFim) ou (Achou=Falso)) Faca
PosCent <- Int((PosIni+PosFim)/2)
Se(Func[PosCent].matric=Mat) Entao
Achou <- Verdadeiro
Local <- PosCent
Interrompa
Senao
Se(Func[PosCent].matric>Mat) Entao
PosFim <- PosCent - 1
Senao
PosIni <- PosCent + 1
FimSe
FimSe
FimEnquanto //fim do loop de pesquisa}
{Verifica o funcionário pesquisado}
Se(Local<>0) Entao
Escreval("Funcionário ",Func[PosCent].nome,"
já cadastrado")
Escreval("Matrícula: ",Func[PosCent].matric)
Escreval("Setor: ",Func[PosCent].setor)
Escreval("salário:",Func[PosCent].salario)
Senao
Escreval("Funcionário matrícula ", Mat, " NÃO
está cadastrado")
FimSe
Escreval("")
FimAlgoritmo //fim do programa "PesqFuncionario"
Nota: No programa "PesqFuncionario" a pesquisa de um funcionário
foi feita através do método de “Pesquisa Binária”; e por imposição
desse método, o conjunto de registros teve que ser previamente
ordenado em ordem crescente, que nesse caso foi utilizado o método
“Bubble Sort” Também é importante observar que para fazer a
ordenação foram empregadas variáveis auxiliares antes de fazer as
trocas exigidas por esse método de ordenação pois, caso contrário, os
campos dos registros ficariam “bagunçados” e sem sincronia com o
nome.
321
Figura 7.5 - Saída do programa "PesqFuncionario”
❖ Exemplo 7.3 - Ler os dados de cinco alunos (matrícula, nome,
sexo, turma) e listar seus nomes e suas médias em ordem
decrescente de médias.
322
Algoritmo "OrdenaMedias"
//Lê alunos de uma turma, calcula suas médias, e exibe os
//nome com suas respectivas médias em ordem decrescente.
//Autor: Mário Leite
//-------------------------------------------------------
Tipo TAluno = registro
matr: inteiro
nome: caractere
sexo: caractere
turma: caractere
nota1: real
nota2: real
nota3: real
nota4: real
media: real
FimRegistro
Var i, j, k , Cont: inteiro
Aluno: vetor[1..5] de TAluno
Medias: vetor[1..5] de real
Aux2, SomaNotaAlu: real
Aux1: caractere
Inicio
Para i De 1 Ate 5 Faca //teste com apenas 5 alunos
Repita
Escreva("Digite a matrícula do aluno: ")
Leia(Aluno[i].matr)
Ate(Aluno[i].matr>0)
Repita
Escreva("Digite o nome do aluno: ")
Leia(Aluno[i].nome)
Ate(Aluno[i].nome<>"") //evita nome em branco
Repita
Escreva("Digite o sexo do aluno [M/F]: ")
Leia(Aluno[i].sexo)
Aluno[i].sexo <- Maiusc((Aluno[i].sexo))
Ate((Aluno[i].sexo="M") ou (Aluno[i].sexo="F"))
Repita
Escreva("Digite a turma do aluno: ")
Leia(Aluno[i].turma)
Ate(Aluno[i].turma<>"")
323
SomaNotaAlu <- 0.00
Repita
Escreva("Digite a primeira nota de
",Aluno[i].nome,": ")
Leia(Aluno[i].nota1)
Ate((Aluno[i].nota1>=0) e (Aluno[i].nota1<=10))
Repita
Escreva("Digite a segunda nota de
",Aluno[i].nome,": ")
Leia(Aluno[i].nota2)
Ate((Aluno[i].nota2>=0) e (Aluno[i].nota2<=10))
Repita
Escreva("Digite a terceira nota de
",Aluno[i].nome,": ")
Leia(Aluno[i].nota3)
Ate((Aluno[i].nota3>=0) e (Aluno[i].nota3<=10))
Repita
Escreva("Digite a quarta nota de
",Aluno[i].nome,": ")
Leia(Aluno[i].nota4)
Ate((Aluno[i].nota4>=0) e (Aluno[i].nota4<=10))
SomaNotaAlu <- SomaNotaAlu + Aluno[i].nota1 +
Aluno[i].nota2
SomaNotaAlu <- SomaNotaAlu + Aluno[i].nota3 +
Aluno[i].nota4
Medias[i] <- (SomaNotaAlu/4)
Aluno[i].media <- Medias[i]
Escreval("") //salta linha para ler novos dados
FimPara
{Classifica médias em ordem decrescente com nomes}
Para j De 1 Ate 5 Faca
Para k De (j+1) Ate 4 Faca
Se(Aluno[j].media < Aluno[k].media) Entao
{Preserva os campos antes das trocas}
Aux1 <- Aluno[j].nome
Aux2 <- Aluno[j].media
{Faz as trocas para ordenar}
Aluno[j].nome <- Aluno[k].nome
Aluno[k].nome <- Aux1
Aluno[j].media <- Aluno[k].media
Aluno[k].media <- Aux2
FimSe
324
FimPara
FimPara
Escreval("")
Escreval("Nomes e médias:")
Para i De 1 Ate 5 Faca
Escreval(Aluno[i].nome,"
",Aluno[i].media:4:1) //com uma decimal
FimPara
Escreval("")
FimAlgoritmo //fim do programa "OrdenaMedias"
A figura 7.6 mostra um exemplo de saída do programa
“OrdenaMedias”.
325
Figura 7.6 - Saída do programa “OrdenaMedias”
326
7.7 - Exercícios Propostos
1 - O que é são estruturas Heterogêneas e Homogêneas no
Visualg?
2 - Qual é a maior vantagem de se usar uma Estrutura
Heterogênea?
3 - Depois de definir um registro, ainda é necessário usar vetores
individuais no Visualg? Explique!
4 - Monte um programa que calcule a média aritmética usando
um registro para até 10 alunos diferentes e com quatro notas.
5 - Sabendo que TProduto é o nome de um registro que controla
os dados de um produto, marque a instrução correta, em Visualg,
para definir uma variável desse tipo.
A ( ) Var Produto: vetor[1..5:1..4] de real
B ( ) Var Produto: inteiro
C ( ) Var Mat: vetor[5,4] de TProduto
D ( ) Var: vetor[1..5] de TProduto
E ( ) Var Produto: TProduto
6 - Sabendo que TFuncionario é uma estrutura de registros para
os funcionários de uma empresa, então marque a alternativa
correta que pode indicar atribuição de um valor ao salário do
décimo primeiro funcionário da empresa.
A ( ) Salario <- Funcionario[11]
B ( ) Salario[11] <- TFuncionario
C ( ) Func[11].salario <- valor
D ( ) Salario <- Func.salario[11]
E ( ) Func.Salario[11] <- TFuncionario
7 - Crie uma estrutura heterogênea para cadastro de um professor,
e que contenha seis campos.
327
Capítulo 8 - Modularização
8.1 - Introdução ao Capítulo
O objetivo da Programação Modular é criar pequenos módulos e
agregá-los de maneira lógica, até conseguir compor a aplicação
como um todo. É como construir a fachada de uma casa com
azulejos; cada azulejo seria um módulo, e a agregação de todos
eles resultaria na fachada da casa. O mesmo raciocínio pode ser
aplicado na construção de um software a partir de pequenos
módulos funcionais, que por sua vez podem ser construídos a
partir de outros módulos menores. A essência desse tipo de
programação é conseguir criar unidades independentes,
funcionais e o mais genéricas possíveis para serem empregados
em sistemas maiores. Esta técnica facilidade muito as
manutenções dos programas, além de oferecer diversos tipos de
benefícios e vantagens no desenvolvimento de grandes sistemas:
Permite o reaproveitamento de códigos já construídos; o trabalho
seria apenas o de “encaixá-los” no programa.
• Evita que um bloco de código seja repetido várias vezes num
mesmo programa.
• Permite alterações no programa de forma mais rápida,
localizando o erro pontual e isolando-o de outros blocos.
• Limita o tamanho dos blocos de instruções melhorando,
consideravelmente, a legibilidade e, por conseguinte, a
manutenção do sistema.
• Permite separar o programa em partes que podem ser
logicamente compreendidas de forma encapsulada.
328
8.2 - Conceitos Básicos
Todos os programas em Visualg apresentados anteriormente
formavam um bloco único de linhas de códigos, começando com
a instrução Algoritmo “NomeDoPrograma” e terminando com
FimAlgoritmo. Este é o modelo básico de um programa do tipo
stand-alone no Visualg, indicando um único módulo (o
principal), identificado em “NomeDoPrograma”. Um programa
desse tipo é aquele em que só existe um bloco com várias linhas
de instruções; o programa principal (obrigatório). Assim, ao
carregar (rodar) o programa, o Visualg começa a
ler/interpretar/executar cada linha de código desde a palavra-
chave Algoritmo até FimAlgoritmo. Um programa, assim
concebido, pode se tornar tão complexo e com tantas linhas de
códigos, que sua manutenção (devido à algum bug) pode ficar
muito difícil e trabalhosa para o programador. A ideia, então, é a
de “quebrar” o programa em partes, de modo que elas possam se
comportarcomo “programinhas” independentes mas, ligados ao
programa principal de maneira lógica e funcional, executando
linhas de código para cumprir tarefas específicas. Por exemplo,
se o programa, em geral, é para somar os n primeiros números
primos, então pode existir um “programinha” específico, dentro
do programa geral só para verificar se um desses n números é
primo; se for, ele será somado; se não for, não será somado. Deste
modo, todas as vezes que precisar verificar se um determinado
número é primo, esse “programinha” será chamado para fazer
essa verificação e reportar ao “programa principal”, ou a qualquer
outro “programinha” que o chamou. Essa técnica é chamada de
“Modularização”, obrigatória em todos os sistemas que envolvam
mais de uma rotina (programa), como é o caso da maioria dos
sistemas comerciais.
329
8.3 - Dividir para Unificar
De acordo com a Enciclopédia Livre Wikipédia
“Em política e sociologia, dividir para conquistar (ou dividir
para reinar), consiste em ganhar o controle de um lugar
através da fragmentação das maiores concentrações de poder,
impedindo que se mantenham individualmente. O conceito
refere-se a uma estratégia que tenta romper as estruturas de
poder existentes e não deixar que grupos menores se juntem”
No ambiente de desenvolvimento de programas também é muito
importante dividir (fragmentar) um programa grande, que possui
muitas linhas de código, em fragmentos (partes) menores com
especificidades individuais, porém, mantendo o objetivo final do
programa, para o bem comum. Fundamentalmente, isto significa
observar um dos quatro pilares do Método Cartesiano[17] que diz:
“Analisar, ou seja, dividir ao máximo as coisas, em suas unidades
de composição, fundamentais, e estudar essas coisas mais
simples que aparecem”. Em outras palavras, essas “coisas mais
simples” devem trabalhar individualmente, com suas tarefas
particulares, mas, integrada ao programa como um TODO.
8.4 - Programação Modular
Programação Modular, baseada no método bottom-up (de baixo
para cima), é uma técnica de escrita de código em que o desenho
do software é feito a partir de módulos independentes; em outras
palavras, na Programação Modular é aplicada a abordagem
cartesiana em vez da abordagem sistêmica. O objetivo da
Programação Modular é criar pequenos módulos e agregá-los de
maneira lógica para criar módulos cada vez maiores até conseguir
compor o programa como um TODO. É como construir uma
parede com tijolos; cada tijolo seria um módulo, e a agregação de
https://pt.wikipedia.org/wiki/Pol%C3%ADtica
https://pt.wikipedia.org/wiki/Sociologia
330
todos eles resultaria na parede desejada. O mesmo raciocínio
pode ser aplicado na construção de um software a partir de
pequenos módulos funcionais, que por sua vez podem ser
construídos a partir de outros, menores ainda. Em resumo, a
Programação Modular começa com as partes para se conseguir o
TODO; sua essência é criar módulos independentes, funcionais,
e o mais genéricos possíveis para serem empregados em sistemas
maiores. Isto tem um preço: o tempo de desenvolvimento é maior
do que em outros paradigmas de programação, mas, por outro
lado, uma vez criados esses módulos podem ser reutilizados.
Nota: Um tipo de programação modular é a chamada “Programação
Orientada a Objetos” (OOP, na sigla em Inglês), onde os módulos são
entes chamados de “objetos” que herdam características (atributos) e
operações(métodos) definidas por uma classe.
A construção de uma casa pode ser usada para explicar a
importância da modularização no desenvolvimento dos
programas de computador. Observe as figuras 8.1a e 8.1b; elas
mostram o esquema de uma casa com apenas um cômodo, e a
mesma constituída de cômodos, respectivamente.
Figura 8.1a - Casa com apenas um cômodo
Fonte: “Curso Básico de Programação-Teoria e Prática”, 2017, Mário Leite
331
Figura 8.1b - Casa com vários cômodos separados
Fonte: “Curso Básico de Programação-Teoria e Prática”, 2017, Mário Leite
Observando as duas figuras acima, fica evidente que uma casa
construída em cômodos (módulos) é bem mais agradável e mais
funcional que aquela do tipo “tudo junto”, pois, cada cômodo
funciona como um módulo funcional e independente permitindo,
entre outras coisas, a privacidade. Por exemplo, se for preciso
reparar algum vazamento no Lavabo basta isolá-lo de outros
cômodos e fazer o reparo lá mesmo; não haveria necessidade de
interditar toda a casa para executar o serviço. Assim, tal como no
exemplo da casa em cômodos (figura 8.1b), um programa pode
ser “quebrado” em vários módulos funcionais que se comunicam
logicamente por via de um “módulo principal”. A figura 8.2
mostra que um “programa de controle comercial” pode ser
dividido em vários “programinhas” que executam tarefas
específicas para compor o sistema com um TODO.
332
Figura 8.2 - Um programa feito em módulos
Fonte: “Curso Básico de Programação-Teoria e Prática”, 2017, Mário Leite
Na figura 8.2 “Cadastros”, “Relatórios”, “Controle Bancário”,
“Pagamentos”, “Contas a Pagar”, “Contas a Receber”,
“Compras”, “Vendas”, “Movimentação” e “Saída” são os
módulos que compõem o programa. Cada um deles é executado
para executar uma tarefa específica; até o “Saída”, que pode
conter apenas uma linha de código. Então, por exemplo, se
“Relatórios” estiver com algum problema o programador só terá
o trabalho de verificar esse módulo, particularmente, pois o
sistema não pode ser interrompido por algum erro em um dos seus
módulos. Já pensou se, para se para consertar o módulo
“Relatórios” fosse preciso parar o cadastramento de novo
clientes!? Seria como abandonar a casa só para o encanador
resolver um problema de vazamento no Lavado! Os tais
“programinha” (módulos) são, tecnicamente, considerados sub-
rotinas (ou, simplesmente rotinas) que são ligadas, logicamente,
à uma rotina principal (programa principal) mas, executando
tarefas autônomas, bem específicas.
Um programa pode ser entendido como um conjunto de linhas de
instruções contendo ordens precisas para serem executadas pelo
computador. E dependendo do tipo de problema a ser resolvido,
333
da qualidade e da quantidade de informações a ser extraída, o
programa pode ter desde dezenas até milhões de linhas de
instruções. Mas, como já explicado, um programa não deve ser
um bloco único - como uma casa com apenas um grande espaço
único -, pelo contrário, para que seja modular e de fácil
manutenção ele deve ser composto de vários subprogramas (sub-
rotinas) que se “encaixam” logicamente formando o todo. Esta
metodologia de modularizar um programa é feita através de
técnicas formais: uma delas é a Programação Procedural, que é o
caso deste livro. Em qualquer tipo de linguagem, sob qualquer
tipo de técnica de programação, um bloco de instruções
previamente identificado e que tenha o objetivo de executar uma
tarefa específica dentro de um programa é denominado “rotina”.
Se o programa é um sistema mais amplo e desenvolvido para
executar vários módulos específicos, normalmente ele possui
uma “rotina principal” que comanda todas as outras que, então,
passam a ser denominadas “sub-rotinas”. Assim, um conjunto de
sub-rotinas comandadas por uma rotina principal, se constitui
num programa, sob a técnica da Programação Modular.
8.5 - Sub-rotinas
Na grande maioria das linguagens de programação - com raras
exceções - os módulos dos programas são implementados por
dois tipos distintos de sub-rotinas:
• Procedimentos
• Funções
Ambos cumprem o papel de tratar um subconjunto específico
(módulo) do programa: executar um bloco de instruções quando
solicitado. Entretanto, existe uma diferença entre eles: enquanto
a função executa o bloco de instruções e retorna um valor
específico para a rotina que a chamou, o procedimento não
retorna nada! Portanto,se for invocada uma função e o valor do
334
retorno tiver que ser publicado, isto pode ser feito na rotina que a
chamou; mas se for invocado um procedimento, esse valor só será
conhecido localmente: no próprio procedimento pois, neste caso,
a rotina chamadora não terá acesso a ele. Uma das exceções
aludidas acima é o caso da linguagem C que não contempla
procedimentos; apenas funções. De qualquer forma, uma sub-
rotina sempre é carregada, inicialmente, pelo programa principal,
e só DEPOIS disto é que poderá chamar e/ou ser chamada.
8.5.1 - Procedimentos
Um procedimento pode ser definido como sendo uma sub-rotina
capaz de executar uma tarefa bem determinada, mas sem retornar
valor para a rotina que o chamou. O formato geral de um
procedimento em Visualg é mostrado na sintaxe a seguir, onde a
primeira linha define o nome do procedimento; logo abaixo vem
a área de declarações (arquivos, constantes, registros e variáveis
- nesta ordem) e, finalmente, entre as palavras-chave Início e
FimProcedimento são escritas as linhas de código, contendo as
instruções. O esquema a seguir mostra um modelo em Visualg.
Procedimento NomeProcedimento[(parâmetros)
{Declarações de elementos locais}
Declarações de arquivos
Declarações de constantes
Declarações de registros
Declarações de variáveis
Inicio
Linha1
Linha2
Linha2
...
LinhaN
FimProcedimento
335
Como pode ser observado, o formato de um procedimento no
Visualg é quase igual ao formato geral de um programa único; a
diferença indicada aqui é entre os termos Algoritmo e
Procedimento. Outro detalhe a ser notado é a inclusão do termo
“parâmetros”; valores recebidos pelo procedimento para serem
utilizados no processamento, e que podem ser necessários ou não,
dependendo do que o procedimento faz ao ser chamado.
❖ Exemplo 8.1 - Calcular a quantidade de números primos que
existe desde 1 até 100.
Procedimento ProCalculaQuantPrimos
//Calcula a quantidade de primos de 1 a 100.
//Autor: Mário Leite
//-------------------------------------------------------
var j, k, TotDiv, ContPrimos: inteiro
Inicio
ContPrimos <- 0
Para j De 1 Ate 100 Faca
TotDiv <- 0
Para k De 1 Ate j Faca
Se(j Mod k = 0) Entao
TotDiv <- TotDiv + 1
FimSe
FimPara
{Verifica se o número j é primo}
Se(TotDiv=2) Entao //o número é primo
ContPrimos <- ContPrimos + 1
FimSe
FimPara
Escreval("Número de primos de 1 a 100: ",ContPrimos)
FimProcedimento
336
8.5.2 - Funções
Uma função executa um módulo de programa tal como faz um
procedimento; mas, existe uma diferença bem marcante entre
esses dois tipos de sub-rotinas: enquanto o procedimento não
retorna nenhum valor para o módulo que o chamou, a função
sempre retorna algum valor. Observe abaixo o formato de uma
função no Visualg.
Funcao Nomefunção [(parâmetros)]: tipo
{Declarações de elementos locais}
Declarações de arquivos
Declarações de constantes
Declarações de registros
Declarações de variáveis
Inicio
Linha1
Linha2
Linha3
...
LinhaN
Retorne valor //retorno da função
FimFuncao
Nota: Embora nos dois tipos de sub-rotinas tenha sido colocado como
sendo possível a declaração de registros e constantes, tanto nos
procedimentos como para as funções, a criação de registros e
constantes é normalmente feita no programa principal para que possam
ser utilizados em todas as sub-rotinas do programa. Um registro ou uma
constante são, normalmente, elementos do programa com visibilidade
global, e não apenas local a uma determinada sub-rotina.
337
O esquema de modelo de uma função no Visualg apresenta três
novidades em relação ao modelo para procedimento:
1ª) A palavra-chave Funcao em vez de procedimento para
informar que se trata de uma sub-rotina (módulo) do tipo função.
2ª) tipo - informa que tipo de dado terá o valor encontrado pela
função; isto é, qual será o tipo de dado do seu retorno. O
procedimento não tem isto.
3ª) Retorne valor - é uma instrução (com o comando Retorne)
que define o retorno da função; o valor que calculado deve ser
informado ao módulo que a chamou; e é obrigatório nas funções,
embora a instrução possa variar de acordo com a linguagem de
programação.
A seguir, observe uma segunda situação com o mesmo problema
do Exemplo 8.1: calcular a quantidade de números primos em
uma faixa”. Neste segundo caso foi empregado uma função em
vez de procedimento; e o valor (quantidade de primos na faixa
determinada) NÃO FOI EXIBIDO na função, mas retornada para
o módulo que chamou a função. E é nesse módulo (chamador)
que esse valor poderá ser utilizado (exibido ou usado em algum
cálculo...); não interessa o emprego desse valor na própria função
chamada: sua tarefa é apenas calculá-lo e retorná-lo! Outro
detalhe a ser observado é que no Exemplo 8.1 com procedimento
a faixa de pesquisa dos números primos foi previamente
estabelecida: de 1 a 100; e o resultado foi, e será SEMPRE 25. Já
no segundo caso, com função, essa faixa (início e fim) foi passada
como PARÂMETRO para a função pesquisar os números primos.
Deste modo, o usuário poderá escolher qualquer faixa de valores
para calcular a quantidade de números primos num intervalo
qualquer; e essa quantidade vai variar de acordo com o intervalo
desejado. Isto torna a sub-rotina mais flexível, mais genérica e
bem mais interativa com o usuário. Por exemplo, para os números
primos na faixa de 10 a 131 a quantidade encontrada seria 28, já
338
que existem vinte e oito números primos desde 10 até 131. Por
outro lado, observe que no caso de uso do procedimento o valor
(quantidade de primos na faixa de 1 a 100) teve que ser exibida
no próprio procedimento, pois, não retorna valor para o módulo
chamador.
Funcao FunCalculaQuantPrimos(Ini,Fim:inteiro): inteiro
//Função para calcular a quantidade de primos numa faixa.
//Autor: Mário Leite
//-------------------------------------------------------
var j, k, TotDiv, ContPrimos: inteiro
Inicio
ContPrimos <- 0
Para j De Ini Ate Fim Faca
{Loop para fazer as divisões de um número}
TotDiv <- 0
Para k De 1 Ate j Faca
Se(j Mod k = 0) Entao
TotDiv <- TotDiv + 1
FimSe
FimPara //fim do loop das divisões
Se(TotDiv=2) Entao //o número é primo
ContPrimos <- ContPrimos + 1
FimSe
FimPara
FimPara
Retorne ContPrimos //valor obtido: retorno da função
FimFuncao
ProCalculaQuantPrimos : calcula a quantidade de primos de 1
a 100.
FunCalculaQuantPrimos(Ini,Fim): calcula a quantidade de
primos em uma faixa definida pelo usuário, começando em Ini e
terminando em Fim.
339
Na função “FunCalculaQuantPrimos” apareceram dois
parâmetros: Ini e Fim. O primeiro indica o início da faixa
numérica desejada, e o segundo o fim dessa faixa.
Fazendo uma comparação “física” pode-se considerar uma
função como uma “máquina” que executa uma operação bem
definida: os parâmetros representam a matéria prima que ela
precisa para trabalhar, e o retorno o produto final. Por exemplo,
uma garapeira (função) necessita de cana (parâmetro) para
produzir o caldo (retorno). A garapeira pode receber uma, duas
ou três fieiras de canas (parâmetros), mas produz (retorna)
apenas um produto: o caldo; e esse produto (caldo) pode ser
colocado num copo (variável) da pessoa (rotina) que a solicitou.
É claro que, se a garapeira (função) requer cana (tipo de dado) ela
não poderá trabalhar (processar) se nela for introduzido
(passado) um tubo de aço (tipo de dado inválido); ela quebraria;
falharia!
Nota: Embora as duas sub-rotinas mostradas anteriormente (função e
procedimento) tenham sido apresentadas fora de um programa, isto foi
feito apenas como exemplos de tipos de módulos;entretanto, numa
situação real elas SEMPRE terão que estar integrada a um programa,
ou “guardadas” como arquivos numa biblioteca. à espera de serem
requisitadas.
O esquema da figura 8.3 mostra um exemplo de programa com
várias sub-rotinas, integradas à rotina (programa) principal.
340
Programa principal
Figura 8.3 - Escopos de variáveis num programa
Fonte: Leite, (2006, p. 153)
341
Os elementos mais básicos num programa são as variáveis e as
constantes; o escopo (visibilidade, abrangência) destes elementos
pode ser: Global ou Local. Nas áreas de declarações tem-se o
seguinte:
▪ Declarações globais (ente os termos Inicio e
FimAlgoritmo): todas as constantes e variáveis declaradas
nesta área serão vistas em todas as sub-rotinas, pois terão escopo
global; são elementos públicos.
▪ Declarações locais (instruções colocadas entre
Procedimento/Funcao e FimProcedimento/FimFuncao):
Todas as constantes e variáveis declaradas nessas áreas só
podem ser vistas na sub-rotina onde foram declaradas; são
elementos com escopo local. Então, por exemplo, se uma
variável x for declarada numa sub-rotina1 ela só pode ser
vista (manipulada, acessada) nessa sub-rotina, pois nenhuma
outra rotina terá acesso a essa variável.
O esquema da figura 8.3 mostra como funcionam as
visibilidades das variáveis num programa composto de várias
sub-rotinas, e informa o seguinte:
✓ Variáveis A, B: Escopo global; são visíveis em todas as
rotinas e sub-rotinas do programa; qualquer unidade do
programa poderá acessá-las.
✓ Variáveis C, D: Escopo local à rotina 1; são visíveis nas sub-
rotinas 1.1 e 1.2.
✓ Variável E: Escopo local à sub-rotina 1.1 (visível apenas
nesta sub-rotina).
✓ Variáveis F, G: Escopo local à sub-rotina 1.2 (visíveis só
nesta sub-rotina).
✓ Variáveis H, I: Escopo local à rotina 2, e são visíveis nas suas
três sub-rotinas 2.1, 2.2 e 2.3.
✓ Variáveis J, K, L: Visíveis apenas na sub-rotina 2.1;
342
✓ Variáveis L, M, N: Escopo local à sub-rotina 2.2 (só serão
visíveis nesta sub-rotina); mas, a variável L desta sub-rotina
não tem nada a ver com a variável L da sub-rotina 2.1, pois
ambas são locais a sub-rotinas diferentes.
✓ Variáveis M, N, O, P, Q: Escopo local à sub-rotina 2.3; mas,
as variáveis M e N desta sub-rotina não têm nada a ver com
suas homônimas da sub-rotina 2.2.
Nota: Se por acaso, uma variável local for declarada com o mesmo
identificador de outra variável global a preferência é sempre da variável
local. Isto quer dizer que, se por exemplo, alguma sub-rotina do
programa do esquema da figura 8.3 tivesse uma variável A o valor
considerado desta variável dentro desta sub-rotina seria o local e não o
global. A preferência de uso de variáveis deve ser sempre pelas locais
e não globais, pois as globais tornam o programa mais lento, além de
sofrer interferências de todas as sub-rotinas do programa; só as use em
casos de registros e constantes.
8.6 - Parâmetros
A sub-rotina “FunCalculaQuantPrimos”, trabalhou com
parâmetros que indicavam o início e o fim, respectivamente, da
faixa numérica, De um modo bem geral, pode-se definir
parâmetros como sendo “valores passados a uma rotina para que
ela possa executar sua tarefa”. No caso da função
“FunCalculaQtePrimos” a linha de código de definição dessa
sub-rotina é explicada no esquema a seguir...
343
Nome da função
tipo de dado dos dois parâmetros
Funcao FunCalculaQtePrimos(Ini,Fim:inteiro): inteiro
Primeiro parâmetro (recebe início da faixa) tipo de retorno da função
Segundo parâmetro (recebe fim da faixa)
De um modo geral, qualquer sub-rotina pode receber parâmetros
de acordo com o esquema da figura 8.4 que define procedimento
e função, respectivamente, no Visualg.
Figura 8.4 - Esquema de um Procedimento e de uma Função
344
Nota1: Analisando o esquema da figura 8.4, pode ser notado que além
da diferença entre as palavras-chave que definem o tipo de sub-rotina
(procedimento e função), existe uma outra diferença
FUNDAMENTAL entre elas: o termo “Tipo” que aparece logo depois
dos parênteses, imediatamente após dois pontos (:). Os procedimentos
não os possuem, mas as funções têm, por obrigação de sempre indicar
o tipo de dado do retorno.
Nota2: Nos casos em que dois ou mais parâmetros possuem um mesmo
tipo de dados, então eles devem ser separados por vírgulas e no final da
lista colocar : e o tipo. Por exemplo, se os parâmetros P1 e P2 fossem
do tipo inteiro e o T3 do tipo caractere, ficaria assim:
(p1, p2:inteiro; p3:caractere)
A vírgula (,) separa os parâmetros de um mesmo tipo e o ponto-e-
vírgula (;) separa os tipos.
8.6.1 - Passagem de Parâmetros
Passagem de parâmetros pode ser definida como sendo “o
mecanismo pelo qual valores externos são entregues a uma sub-
rotina, com os quais ela deve operar para executar a tarefa que
lhe foi atribuída”. No esquema da figura 8.5a, o programa
principal chama a função FunCalculaRaiz() para calcular a raiz
k-ésima de N. Depois de calculada essa raiz a função retorna
(devolve) ao programa principal o valor calculado.
345
Figura 8.5a - Exemplo de passagem de parâmetros para uma função
A seta sólida, indicada esquematicamente na figura 8.5a, mostra
como é feita a passagem de parâmetros; no caso estão sendo
passados os parâmetros N e k (parâmetros reais, ou argumentos;
nesta ordem) que representam o número do qual se deseja extrair
a raiz e o índice dessa raiz, respectivamente. O programa
“Principal” chama a função FunCalculaRaiz() passando-lhe
esses dois parâmetros reais (ou argumentos) que são recebidos
como parâmetros formais em num e pot, respectivamente. A
função calcula a raiz, armazena-a na variável local raiz e retorna
esse valor para o programa que a chamou (indicado pela seta
tracejada). Esse retorno (valor da raiz k-ésima de N) é
armazenado na variável global R do programa “Principal” e
posteriormente exibido. Por exemplo, se o número para calcular
a raiz cúbica fosse 64, então os valores seriam:
346
N = 64
k = 3
Esses dois valores seriam passados para a função
FunCalculaRaiz() que os receberia formalmente assim: 64 em
num e 3 em pot. Em seguida, essa função executaria a linha de
código raiz <- (num^(1/pot)) cujo resultado seria 4 (raiz cúbica
de 64); e finalmente, esse valor calculado pela função (o seu
retorno) seria devolvido ao programa principal que o colocaria na
variável R, para depois exibi-lo.
No esquema da figura 8.5b o programa principal chama o
procedimento ProCalculaRaiz() para calcular a raiz k-ésima do
de N. Depois de calculada a raiz esse valor é exibido lá mesmo
(no procedimento), já que esse tipo de sub-rotina não tem retorno;
não pode retornar o valor da raiz para o programa “Principal”
que que o chamou.
347
Figura 8.5b -Exemplo passagem de parâmetros para um procedimento
348
Notas:
1) N, k e R são variáveis globais (declaradas no programa principal)
e normais, entretanto N e k ganham status de parâmetros reais
quando são envolvidas na interação com a sub-rotina.
2) Os parâmetros formais num e pot poderiam ter os mesmos
identificadores dos parâmetros reais (N e k, respetivamente), sem
qualquer problema, mas nesta ordem! Os parâmetros passados
(reais) não precisam ter, necessariamente, os mesmos identificadores
que os dos parâmetros recebidos (formais), ou vice-versa.
3) Os parâmetros formais num e pot (da função) não podem ser
declarados, pois já são considerados variáveis locais à função; ao
contrário dos parâmetros reais N e k (do programa principal) que têm
que ser declarados, pois não são parâmetros formais.
4) As variáveis R (do programaprincipal) e raiz (da função) não são
parâmetros; são variáveis normais, pois não estão envolvidos na
passagem de parâmetros.
5) O retorno de uma função não é, normalmente, exibido na própria
função, e sim na rotina que a chamou. Já no caso de procedimento,
como não existe retorno, o resultado de seu processamento deve ser
exibido lá mesmo!
6) Quando se utiliza procedimento a rotina chamadora (seja o
programa principal ou outra sub-rotina qualquer) não pode acessar o
valor calculado pelo procedimento porque ele não retorna nada.
Então, na figura 8.5b ficou bem claro que após calculada a raiz k-
ésima do número N esse valor teve que ser exibido no próprio
procedimento, já que o programa “Principal” não pode “ver” esse
valor que é encapsulado (protegido) na sub-rotina chamada.
É importante observar, também, as duas formas bem distintas de
chamar (invocar) uma função e um procedimento. Para chamar
uma função a rotina chamadora (no caso o programa
“Principal”) pode “pegar” o retorno e atribui-lo a uma variável;
como aconteceu no caso do esquema da figura 8.5a:
349
R ← FunCalculaRaiz(N,k)
Já no caso de procedimentos a linha de código se resume à apenas
uma instrução: a chamada; e pronto! Não se pode pegar o retorno,
já que procedimentos não retornam nada. Assim, no caso do
esquema da figura 8.5b, ficou simplesmente assim:
ProCalculaRaiz(N,k). Deste modo, as chamadas de funções e
procedimentos são bem diferentes.
1) Para chamar uma função é assim:
R ← NomeFuncao([parâmetros]) //R é variável local da rotina
Para chamar um procedimento é assim:
NomeProcedimento([parâmetros])
Nota: Formalmente, os valores passados a sub-rotina são chamados de
“argumentos” (ou parâmetros reais), e esses valores quando recebidos
pela sub-rotina é que são os “parâmetros” (ou parâmetros formais).
Embora esta formalidade não altere a essência da passagem de
parâmetros, é bom que fique registrada esta diferença, muito
considerada, academicamente.
8.6.1.1 - Passagem Por Valor
Quando é feita a passagem de um parâmetro Por Valor, o que é
passado, na verdade, é uma cópia do valor dessa variável; e a
ligação estabelecida entre elas pode ser considerada fraca. Isto
quer dizer que a rotina chamada (a que recebe o parâmetro) pode
alterar esse parâmetro, mas, o seu valor na rotina chamadora não
é alterado. Este modo de passar parâmetros é o padrão na maioria
dos processamentos. Nos esquemas das figuras 8.5a e 8.5b para
calcular a raiz de índice k de um número N, a passagem de
parâmetros para as sub-rotinas foi feita “Por Valor”. Observe o
esquema da figura 8.6a, explicando esse tipo de passagem,
quando N é passado como 64 e k como 3 para a função.
350
Figura 8.6a - Exemplo de passagem de parâmetros “Por Valor”
A figura 8.6a mostra que mesmo que a função chamada
FunCalculaRaiz() altere o valor recebido: de 64 para 999, o
parâmetro N continuará valendo 64 na rotina “Principal”.
8.6.1.2 - Passagem Por Referência
Neste caso o que é recebido pela rotina chamada não é apenas o
valor da variável, mas também o endereço de memória dessa
variável. Deste modo, a ligação que se estabelece entre elas é
forte. Por isto, se a rotina chamada fizer alguma alteração nesse
parâmetro isto será refletido na rotina chamadora. Considerando,
ainda, o exemplo para calcular a raiz de índice k de um número
N, observe o esquema da figura 8.6b, sendo a passagem do
parâmetro N sendo feita “Por Referência”.
351
Figura 8.6b - Exemplo de passagem de parâmetros “Por Referência”
O esquema da figura 8.6b mostra que o valor da variável N do
programa “Principal “ se alterou: de 64 (valor passado para a
função) para 999, devido à alteração promovida no parâmetro
formal num na função FunCalculaRaiz(). Observe que a
indicação de que o parâmetro N foi passado (ou recebido) “Por
Referência” é a presença da palavra-chave var (de variável) na
frente do parâmetro formal num. Por sua vez, o parâmetro k
continua sendo passado “Por Valor”. E embora os exemplos de
passagem de parâmetros (“Por Valor” e “Por Referência”)
mostrados nas figuras 8.6a e 8.6b tenham sido feitos com função,
352
as passagens de parâmetros também podem ser feitas com
procedimento, mesmo estes não tendo retorno; entretanto, na
maioria das vezes a passagem é sempre feita “Por Valor”. Por
isto, quando se cria uma sub-rotina esta deve receber parâmetros
“Por Valor”, sempre que possível, por ser o modo seguro. De
qualquer forma, em qualquer situação, quando o processamento
de uma sub-rotina gerar algum valor mensurável como resultado,
deve-se optar por função; pois se optar por procedimento a
variável que armazena o resultado dos cálculos terá que ter
abrangência global para que o programa principal a “enxergue”;
mas neste caso, TODAS as outras sub-rotinas também poderão
acessar essa variável, o que é extremamente perigoso, ferindo a
segurança de dados.
Nota: Seguindo o padrão do Pascal, a indicação de que uma sub-rotina
recebe um parâmetro “Por Referência” é o termo var antes desse
parâmetros; mas isto pode variar de linguagem para linguagem; como
no Clipper/xHarbour que @. Em alguns casos, esse tipo de indicação
pode nem existir, explicitamente, como no caso do Python.
❖ Exemplo 8.2 - Criar uma sub-rotina que calcula o MMC
(Mínimo Múltiplo Comum) de dois números. Neste caso, como
o objetivo é obter um valor bem determinado, a solução mais
indicada é uma função. A função “FunMMC1( )” é uma solução.
353
Funcao FunMMC1(Num1,Num2:inteiro): inteiro
//Função que retorna o MMC de dois números.
//Autor: Mário Leite
//-------------------------------------------------------
var i, j, k, m, M1, M2, MMC: inteiro
VetMult1,VetMult2: vetor[1..MAX] de inteiro
Verdade: logico
//MAX deve ser maior número dos recebidos como parâmetros
Inicio
Para j De 1 Ate MAX Faca
VetMult1[j] <- Num1*j
VetMult2[j] <- Num2*j
FimPara
Verdade <- Falso
Para i De 1 Ate MAX Faca
Para j De 1 Ate MAX Faca
Se(VetMult1[i]=VetMult2[j])Entao //achou
MMC <- VetMult1[i]
Verdade <- Verdadeiro //encontrou o MMC
Interrompa //sai do loop mais interno
FimSe
FimPara
Se(Verdade) Entao
Interrompa //sai do loop mais externo
FimSe
FimPara
Retorne MMC //retorno da função
FimFuncao
A função “FunMMC2( )” a seguir, é uma outra solução mais
refinada e mais enxuta do problema do Exemplo 8.2 em que não
há necessidade de se ter um valor MAX e nem vetores para
calcular o MMC.
354
Funcao FunMMC2(Num1,Num2: inteiro): real
//Função que retorna o MMC de dois números.
//Autor: Mário Leite
//-------------------------------------------
var R, N1, N2: inteiro
Inicio
N1 <- Num1
N2 <- Num2
Repita
R <- (N1 Mod N2)
N1 <- N2
N2 <- R
Ate(R=0)
Retorne Int(Num1*Num2)/N1)
FimFuncao
8.7 - Programas com Sub-rotinas
As figuras 8.7a, 8.7b, 8.8a e 8.8b mostraram, esquematicamente,
um programa modular contendo exemplos de processamento para
ilustrar passagens de parâmetros. Na prática, entretanto, é um
pouco diferente: no Visualg as sub-rotinas podem ser
“encaixadas” no programa de duas formas:
1) “dentro” do programa principal
2) antes do programa principal
A primeira forma é a mais tradicional, mostrada no programa
“Principal1”: entre as instruções Algoritmo "Principal1" e
“FimAlgoritmo”, como mostra a figura 8.7a, com as variáveis
globais do programa definidas ANTES das sub-rotinas.
355
Figura 8.7a - Código-fonte do programa “Prinipal1” no editor
A figura 8.7b mostra a saída do programa “Principal1”, quando
se deseja calcular a raiz cúbica de 64.
356
Figura 8.7b- Exemplo de saída do programa “Principal1”
A segunda forma de “encaixar” sub-rotinas num programa em
Visual é mostrada no programa “Principal2”. Neste caso, as sub-
rotina permanecem ANTES das instruções Algoritmo
"Principal2" e “FimAlgoritmo, porém as variáveis globais,
também são definidas dentro dessa área, e não antes das funções.
357
Figura 8.8a - Código-fonte do programa “Prinipal2” no editor
A figura 8.8b mostra a saída do programa “Principal2”, com o
mesmo propósito: calcular e exibir raiz cúbica de 64.
358
Figura 8.8b- Exemplo de saída do programa “Principal2”
Nota: Observe que tanto no layout do programa “Principal1” quanto
no “Principal2”, a ÚLTIMA linha de código é FimAlgoritmo, pois, é
esta instrução que determina o FIM DO PROGRAMA. Não pode existir
NADA depois desta instrução; é como o comando End. em programas
codificados em Pascal.
As linhas tracejadas são apenas para mostrar os limites das rotinas, nada
mais que isto; apenas um estilo de programação, e não é obrigatório;
mas com elas o programa fica mais legível
Outra informação importante a respeito de programas em Visualg
(seja modular ou não) é que o nome do programa NÃO TEM
NADA A VER com o nome do arquivo no qual ele será gravado.
359
Deste modo, o nome do arquivo poderá ser qualquer um, desde
que respeite as regras de identificação de arquivos exigidas pelo
Sistema Operacional que o carregará para a memória; e deverá ter
a extensão .alg (de algoritmo). Por outro lado, mesmo podendo
ter qualquer nome válido, é uma boa atitude profissional gravar o
arquivo com o MESMO NOME do programa. Então, neste caso,
o arquivo que contém o programa “Principal1” poderia ser
Pringipal1.alg. É assim que será feito neste livro: os arquivos
que contém programas em Visualg terão o mesmo nome do
programa contido nele. A figura 8.9 mostra alguns arquivos de
uma pasta com programas deste livro, em Visualg.
Figura 8.9 - Exemplo de arquivos de programas em Visualg
360
Nota: Embora o arquivo-fonte de um programa feito em Visualg possa
ser editado em qualquer editor de texto (sem formatações), é fortemente
aconselhável utilizar SEMPRE o seu próprio editor. Isto dá mais
segurança e maior produtividade ao programador, uma vez que o editor
do Visualg mostra possíveis erros de sintaxe com a indicação de cores
no código à media que o programa vai sendo digitado. Além disto, o
editor próprio da ferramenta é um IDE (Integrated Development
Environment - Ambiente de Desenvolvimento Integrado) que oferece
várias opções para a criação/teste/depuração/gravação do programa
editado, de maneira bem interativa e customizável. Por exemplo, se ao
tentar digitar a palavra-chave RaizQ para calcular a raiz quadrada de
um número e digitar apenas Raiz, vai notar que essa palavra vai
continuar com a cor preta em vez de azul, como o Editor do Visualg
mostraria para indicar que se trata de uma função interna da ferramenta.
Assim, o programador poderá, já nesse exato momento, corrigir o seu
erro; mas, se utilizar um outro editor de texto como, por exemplo, o
Bloco de Notas do Windows®, esse erro vai passar despercebido e a
produtividade do programador cai.
❖ Exemplo 8.3 - Criar um programa modular que gera e exibe
os n primeiros números pares ou ímpares para um vetor,
exibindo-os na forma de tabela, e os números formatados com
cinco dígitos.
O programa "ProgGeraParesOuImpares", mostrado a seguir,
em texto livre do editor, é uma boa solução para o problema do
Exemplo 8.3.
361
Algoritmo "ProgGeraParesOuImpares"
//Gera os primeiros n números pares ou ímpares para um
//vetor, mostrando-os na forma de tabela de números
//formatados com cinco dígitos.
//Autor: Mário Leite
//-------------------------------------------------------
//Elementos globais
Const MAXELE=1000 //limita a quantidade de números
Var VetNum: vetor[1..MAXELE] de inteiro
VetNumS: vetor[1..MAXELE] de caractere
NOp, TamVet: inteiro
Op: caractere
//-------------------------------------------------------
Funcao FunVerifOpcao(xp:caractere): inteiro
//Retorna o tipo de número: 0=Par, -1=Ímpar
var Ret: inteiro
Inicio
Se(xp="P") Entao
Ret <- 0
Senao
Ret <- -1
FimSe
Retorne Ret
FimFuncao //fim da função "FunVerifOpcao"
//----------------------------------------------------
Procedimento ProCriaVetor(Num:inteiro)
//Cria o vetor de números a serem exibidos
var n: inteiro
Inicio
n <- 0
Enquanto (n<TamVet) Faca
Num <- Num + 2
n <- n + 1 //incrementa o índice do vetor para
VetNum[n] <- Num
{Seleciona a formatação adequada do número}
Escolha VetNum[n]
Caso 1 Ate 9
VetNumS[n] <- "0000" + NumpCarac(VetNum[n])
Caso 10 Ate 99
VetNumS[n] <- "000" + NumpCarac(VetNum[n])
Caso 100 Ate 999
362
VetNumS[n] <- "00" + NumpCarac(VetNum[n])
Caso 1000 Ate 9999
VetNumS[n] <- "0" + NumpCarac(VetNum[n])
OutroCaso
VetNumS[n] <- NumpCarac(VetNum[n])
FimEscolha
FimEnquanto
FimProcedimento //fim do procedimento "ProCriaVetor"
//----------------------------------------------------
Procedimento ProExibeVetor
//Exibe o vetor
Var j, Col: inteiro
Inicio
Col <- 0
Para j De 1 Ate TamVet Faca
Col <- Col + 1
Se(Col>9) Entao //máximo de nove blocos de
elementos por linha
Escreval("") //salta para uma nova linha
Col <- 1 //recomeça na coluna 1 da nova linha
FimSe
Escreva(VetNumS[j], " ")
FimPara
FimProcedimento //fim do procedimento
//=======================================================
//Programa principal
Inicio
{Validação das dimensões da matriz}
Repita
Escreva("Digite o número de elementos [min 2"," –
max",MAXELE,"]: ")
Leia(TamVet)
TamVet <- Int(TamVet)
Ate((TamVet>=2) e (TamVet<=MAXELE))
Escreval("")
Repita
Escreva("Deseja elementos pares ou elementos
ímpares?[P/I]: ")
Leia(Op)
Op <- Maiusc(Op)
Ate((Op="P") ou (Op="I"))
NOp <- FunVerifOpcao(Op) //verifica opção desejada
363
ProCriaVetor(NOp) //chama rotina: cria vetor
LimpaTela
ProExibeVetor //chama rotina: exibir números criados
Escreval("")
FimAlgoritmo //fim do programa "ProgGeraParesOuImpares"
Observe que o programa "ProgGeraParesOuImpares"
empregou três sub-rotinas: uma função e dois procedimentos;
assim ele ficou bem mais explicativo.
As figuras 8.10a e 8.10b mostram, respectivamente, os cento e
vinte primeiros pares e ímpares formatados com cinco dígitos.
Figura 8.10a - Cem primeiros números pares formatados 5 dígitos
364
Figura 8.10b-Cem primeiros números ímpares formatados com 5 dígitos
Exemplo 8.4 - Tornar modular o programa para calcular o
determinante de matrizes de ordem superior a 3, mostrado no
item 6.6.3 do Capítulo 6.
Naquela ocasião o problema de calcular o determinante de
matrizes de ordem superior a 3 foi resolvido com um programa
único (sem sub-rotinas). Entretanto, como pode ser notado, caso
ocorra algum erro no programa, o programador terá que vascular
todas as linhas de código, até encontrar o erro. Por isto, é
importante separar o programa em módulos, e neste caso
apresentamos soluções em três situações, e mais manutenível.
365
• Para determinantes de matrizes de ordem 2
• Para determinantes de matrizes de ordem3
• Para determinantes de matrizes de ordem qualquer
“ProgCalculaDeterminante” é uma solução modular de
programa em Visualg, com sub-rotinas que implementam a
solução de forma mais profissional e elegante.
Algoritmo "ProgCalculaDeterminante"
//Calcula o determinante de uma matriz mxm de inteiros.
//Autor: Mário Leite
//-------------------------------------------------------
//Elementos globais
Const MAXLIN=10 //limita as dimensões da matriz
Var MatOrig vetor[1..MaXLIN,1..MAXLIN] de real
MatA: vetor[1..MaXLIN,1..MAXLIN] de real
MatX: vetor[1..MaXLIN,1..MAXLIN] de real
Mat3x3: vetor[1..MaXLIN,1..MAXLIN] de real
p, q, mLin, LinMat: inteiro
SomaPos, SomaNeg, DetA: real
//----------------------------------------------------
Funcao FunCalculaDet2x2: real
//Calcula determinante de ordem 2 na forma mais simples
var Det2: real
Inicio
SomaPos <- MatA[1,1]*MatA[2,2]
SomaNeg <- MatA[2,1]*MatA[1,2]
Det2 <- SomaPos - SomaNeg
Retorne Det2
FimFuncao //fim da função "FunCalculaDet2x2"
//----------------------------------------------------
Funcao FunCalculaDet3x3: real
//Calcula determinante de ordem 3 pela "Regra de Sarrus"
var Det3: real
Inicio
SomaPos <- MatA[1,1]*MatA[2,2]*MatA[3,3] +
MatA[1,2]*MatA[2,3]*MatA[3,1]
366
SomaPos <- SomaPos +
MatA[1,3]*MatA[2,1]*MatA[3,2]
SomaNeg <- MatA[1,3]*MatA[2,2]*MatA[3,1] +
MatA[1,1]*MatA[2,3]*MatA[3,2]
SomaNeg <- SomaNeg +
MatA[1,2]*MatA[2,1]*MatA[3,3]
Det3 <- SomaPos - SomaNeg
Retorne Det3
FimFuncao //fim da função "FunCalculaDet3x3"
//----------------------------------------------------
Funcao FunCalculaDetmxm: real
//Calcula o determinante de ordem superior a 3
var MatAx: vetor[0..MAXLIN, 0..MAXLIN] de real
i, j, k, m, Trocas: inteiro
Detmxm, Aux, Fator: real
Inicio
{Faz uma cópia da matriz lida para o processamento}
Para i De 0 Ate (LinMat-1) Faca
Para j De 0 Ate (LinMat-1) Faca
MatAx[i,j] <- MatA[i+1,j+1]
FimPara
FimPara
Trocas <- 0 //número de permutas de linhas da
{Transforma a matriz num triângulo para Regra Chió
m <- LinMat
Para i De 0 Ate (m-2) Faca
Se(MatAx[i,i]=0) Entao //detectou o elemento
[1,1] = 0
Para k De i Ate (m-1) Faca //procura um
elemento [1,1] <> 0
Se(MatAx[k,i]<>0) Entao
Para j De 0 Ate(m-1) Faca //permuta
Aux <- MatAx[i,j]
MatAx[i,j] <- MatAx[k,j]
MatAx[k,j] <- Aux
FimPara
k <- m
FimSe
FimPara
Trocas <- Trocas + 1 //acumula o número
de permutas de linhas
FimSe
367
Se(MatAx[i,i]<>0) Entao
{Converte o elemento [1,1] para 1}
Para k De (i+1) Ate (m-1) Faca
Fator <- -1*MatAx[k,i]/MatAx[i,i]
Para j De i Ate (m-1) Faca
MatAx[k,j] <- MatAx[k,j] +
(Fator*MatAx[i,j])
FimPara
FimPara
FimSe
FimPara
Detmxm <- 1.0
{Calcula o determinante}
Para i De 0 Ate (m-1) Faca
Detmxm <- Detmxm*MatAx[i,i]
FimPara
Escreval("")
Escreval("")
Se(Trocas Mod 2 <> 0) Entao //houve permuta ímpar
Detmxm <- -Detmxm
FimSe
Retorne Detmxm
FimFuncao //fim da função "FunCalculaDetmxm"
//=======================================================
//Programa principal
Inicio
{Validação e leitura da matriz}
Repita
Escreva("Digite o número de linhas da matriz: ")
Leia(LinMat)
LinMat <- Int(LinMat)
Ate((LinMat>=2) e (LinMat<=MAXLIN))
Escreval("")
Escreval("")
Para p De 1 Ate LinMat Faca
Para q De 1 Ate LinMat Faca
Escreva("Entre com o elemento [",p,q,"]: ")
Leia(MatOrig[p,q]) //matriz original lida
mLin <- LinMat //preserva o número de linhas da
matriz original
MatA[p,q] <- MatOrig[p,q] //faz cópia da matriz
para usar nos cálculos
368
FimPara
Escreval("")
FimPara
{Seleciona o tipo de função a ser chamada para calcular
o determinante}
Escolha LinMat
Caso 2
DetA <- FunCalculaDet2x2 //para matrizes de
ordem 2x2
Caso 3
DetA <- FunCalculaDet3x3 //para matrizes de
ordem 3x3
OutroCaso
DetA <- FunCalculaDetmxm //para matrizes de
ordem superior a 3
FimEscolha
LimpaTela
{Mostra a matriz na forma tabelar}
Escreval(" Matriz orinal lida:")
Para p De 1 Ate mLin Faca
Para q De 1 Ate mLin Faca
Escreva(MatOrig[p,q], " ")
FimPara
Escreval("")
FimPara
Escreval("")
Escreval("")
Escreval("Determinante da matriz:", DetA)
Escreval("")
FimAlgoritmo //fim do programa "ProgCalculaDeterminante"
A figura 8.11 mostra uma saída do programa
“ProgCalculadeterminante”,para uma matriz 5x5.
369
Figura 8.11 - Calculando o determinante de uma matriz 5x5
8.8 - Acesso a Arquivos
Como já foi explicado no início deste livro, o Visualg NÃO É
uma linguagem de programação, formalmente considerada; é
uma pseudolinguagem para testar os algoritmos (em forma de
pseudocódigos) que o programador cria para solucionar um
problema. O Visualg é uma ferramenta baseada na escrita em
portugol, criada para substituir os antigos “Testes de Mesa” que
estavam os fluxogramas da solução do problema. Deste modo,
embora consiga processar programas até bem complexos, esta
ferramenta não tem muita flexibilidade na manipulação
(leitura/escrita) de arquivos tal como as linguagens reais. Mas,
mesmo com bastante limitações, o Visualg consegue ler/gravar
em arquivos textos; mesmo que primitivamente. A instrução para
criar um arquivo-texto identificado como “Arq1.txt” é a seguinte
Arquivo "Arq1.txt"
370
Esta instrução, quando existir num programa, deverá ser a
primeira na “Seção de Declarações” de uma rotina. A extensão
do arquivo pode ser qualquer uma (txt, dat, arq, etc), mas deve
estar presente para completar a identificação do arquivo, mas é
aconselhável não usar a extensão alg para não confundir com
algum programa-fonte do Visualg. O comando que acessa os
caracteres do arquivo é Leia(x), onde x é um caractere do arquivo.
Se o arquivo ainda não existir será criado; e cada valor de x deverá
ser digitado para ser gravado no arquivo; se já existe, então
Leia(x) lerá o valor contido nessa variável, um por um,
sequencialmente, dentro de um loop. O programa
“ProgAcessandoArquivo” cria/acessa um arquivo com n
valores inteiros, e depois usa esses valores para criar um vetor.
//-----------------------------------------------------
Procedimento ProAcessaArquivo(n:inteiro)
//Procedimento que acessa o arquivo com n caracteres
Arquivo "Arq1.txt" //abre o arquivo
var j, x: inteiro
Inicio
Escreval("Elementos gravados no arquivo: ")
Para j De 1 Ate n Faca //loop para criar/ler
valores do arquivo
Escreva("Digite o elemento",j,": ")
Leia(x)
VetX[j] <- x*2 //cria cada elemento do vetor
FimPara
Escreval("")
Escreval("Elementos do vetor:")
Para j De 1 Ate n Faca
Escreva(VetX[j]," ") //exibe elemento
FimPara
FimProcedimento //fim do procedimento
371
//=====================================================
//Programa principal
Algoritmo "ProgAcessandoArquivo"
//Acessa um arquivo com cinco valores e cria um vetor
//onde cada elemento é o dobro de cada valor gravado
//nesse arquivo. Exibe os valores gravados no //arquivo
//e os elementos do vetor criado.
//Autor: Mário Leite
//-----------------------------------------------------
//Elementos globais
Const MAXELE=50 //limita o número de caracteres no
Var Vetx: vetor[1..MAXELE] de inteiro
n: inteiro
Inicio
n <- 0
Repita
Escreva("Digite o número de caracteres
contidos no arquivo: ")
Leia(n)
Ate((n>=1) e (n<=MAXELE))
Escreval("")
ProAcessaArquivo(n) //chama rotina/acessa o arquivo
Escreval("")
FimAlgoritmo //fim do programa "ProgAcessandoArquivo"
ATENÇÃO: O programa “ProgAcessandoArquivo” CRIA/LÊ um
novo arquivo chamado “Arq1.txt” e em seguida cria um vetor cujos
elementos são o dobro de cada valor do arquivo. E uma vez criado, esse
arquivo passa a conter, definitivamente, os elementos que foram
digitados no procedimento “ProAcessaArquivo”. Se for necessário
valores diferentes deve-se criar um novo arquivo, pois esses elementos
gravados não poderão ser editados. Assim, só utilize valores gravados
em arquivos com o Visualg se REALMENTE for muito necessário.
Esta é uma limitação séria do Visualg, que poderá ser corrigida nas
próxima versões.
372
A figura 8.12 mostra uma saída do programa
“ProgAcessandoArquivo”.
Figura 8.12 - Criação de arquivo: programa “ProgAcessandoArquivo”
A figura 8.13 mostra o arquivo Arq1.txt gravado com o “Bloco
de Notas”.
Figura 8.13 - O arquivo “Arq1.txt “
373
8.9 - Exercícios Propostos
1 - Observe o programa abaixo. O que está errado nele?
Procedimento VerificaPrimo(num:inteiro): logico
var Resp: logico
j: inteiro
Inicio
j <- 1
Resp <- Verdadeiro
Enquanto (j<=num) Faca
Se(j<>1) e (j<>num) Entao
Se(num Mod j = 0) Entao
Resp <- Falso
j <- num + 1
FimSe
FimSe
j <- j + 1
FimEnquanto
Retorne Resp
FimProcedimento
//---------------------------------------------------
Funcao VerificaQuadrado(num:inteiro): logico
var Resp: logico
Raiz: real
Inicio
Raiz <- RaizQ(num)
Se(Int(Raiz) = Raiz) Entao
Resp <- Verdadeiro
Senao
Resp <- Falso
FimSe
Retorne Resp
FimFuncao
374
//---------------------------------------------------
Funcao CalculaRaiz(num:real; k:inteiro): real
Inicio
Retorne <- num^(1/k)
FimFuncao
//====================================================
Var x,y: inteiro
Algoritmo "ProgCalculos"
Inicio
Escreva("Digite um número: ")
Leia(x)
y <- VerificaPrimo(x)
Se(y) Entao
Escreval("O número",x,"é primo. ")
Senao
Escreval("O número",x,"não é primo.")
FimSe
FimAlgoritmo //fim do programa "ProgCalculos"
2 - Explique por que um programa com mil linhas de códigos
deve ser “partido” em sub-rotinas. Qual seria a vantagem disso?
3 - Explique por que uma constante, tal como a aceleração da
gravidade, deve ser declarada no programa principal e não nas
sub-rotinas?
4 - Qual a diferença entre uma variável global e uma local?
5 - Para que servem os parâmetros? Qual é a vantagem de utilizá-
los em uma sub-rotina?
6 - Explique o porquê das variáveis locais serem preferenciais,
em vez das globais?
7 - Suponha que você tenha que criar uma sub-rotina que mostre
todos os divisores de um número muto grande (acima de um
milhão); por qual você optaria: função ou procedimento?
Explique sua preferência.
375
8 - Suponha um programa em Visualg que possua quatro sub-
rotinas: duas do tipo função e duas do tipo procedimento. Ao
rodar (carregar) o programa, qual delas, CERTAMENTE, será
chamada primeiro?
A ( ) A primeira rotina dentro do programa.
B ( ) A segunda rotina dentro do programa.
C ( ) A terceira rotina dentro do programa.
D ( ) A quarta rotina dentro do programa.
E ( ) Nada pode ser afirmado.
9 - Observe as declarações abaixo, em Visualg. Explique por
que vai dar erro ao tentar rodar o programa.
Var Lado1, Lado2: inteiro
Const G=9.80665
Arquivo "Candidatos.txt"
Tipo TPolitico = registro
nome: caractere
sexo: inteiro
idade: real
partido: caractere
reeleição: logico
FimRegistro
10 - Por que quando ocorre uma passagem de parâmetros “Por
Referência”, se a rotina chamada alterar um dos parâmetros essa
alteração será sentida na rotina chamadora?
11 - O procedimento “ProListaBissextos” mostra todos os anos
bissextos deste o ano 1583 até o ano 2099. Esse procedimento
poderia ser substituído por uma função para fazer a mesma coisa?
Explique a sua resposta.
376
Procedimento ProListaBissextos
//Procedimento para listar os anos bissextos desde o ano
//1583 até o ano 2099.
//-----------------------------------------------------
var Resp, Cond1, Cond2: logico
Ano, Cont: inteiro
Inicio
Cont <- 0
Ano <- 1583
Escreval("Anos bissextos desde o ano 1583 até o
ano 2099")
Enquanto (Ano<=2099) Faca
Cond1 <-((ano Mod 4=0) e (ano Mod 100 <>0))
Cond2 <-(ano Mod 400 = 0)
Se(Cond1 ou Cond2) Entao
EscrevaLn(Ano) //ano bissexto
Cont <-Cont + 1
FimSe
Ano <-Ano + 1
FimEnquanto
Escreval("")
Escreval("Existem",Cont," anos bissextos desde
1583 até 2099")
FimProcedimento
12 - Observe o programa “MostraFatotrial”, abaixo. Esse
código em Visualg é clássico para resolver um problema assim; e
neste caso, o número tem que ser primo. Entretanto, ele pode ser
melhorado; e como isto pode ser feita essa melhoria? Quais as
melhorias poderiam ser introduzidas nele?
377
Algoritmo "MostraFatorial"
//Calcula o fatorial de um número primo digitado.
-------------------------------------------------------
Var VetNumS: vetor[1..2] de caractere //limita
tamanho do número
NumS: caractere
j, TotDiv, NumN: inteiro
Fat: real
EhNumero, EhPrimo, Primo: logico
Inicio
Repita
EhNumero <- Verdadeiro
Escreva("Digite o número: ")
Leia(NumS)
Para j De 1 Ate Compr(NumS) Faca
VetNumS[j] <- Copia(NumS,j,1)
//Verifica se o caracter digitado é um dígito
[0 a 9]
Se((Asc(VetNumS[j]) < 48) ou
(Asc(VetNumS[j])> 57)) Entao
EhNumero <- Falso //não é digito
Interrompa
FimSe
FimPara
//Verifica se o número digitado é primo
Se(EhNumero) Entao
NumN <- CaracpNum(NumS)
//Calcula o fatorial do núemro digitado
TotDiv <- 0
Para j De 1 Ate NumN Faca
Se(NumN Mod j = 0) Entao
TotDiv <- TotDiv + 1
FimSe
FimPara
Se(TotDiv=2) Entao
EhPrimo <- Verdadeiro
Senao
EhPrimo <- Falso
378
FimSe
FimSe
Ate((EhNumero) e (EhPrimo) e (NumN<=23
//Calcula fatorial do número primo digitado e o exibe
Fat <- 1
Se(NumN<>0) Entao
Para j De 1 Ate NumN Faca
Fat <- Fat*j
FimPara
FimSe
Escreval("")
Escreva("Fatorial de", NumN, ":", Fat)
FimAlgoritmo
379
Anexo - Solução dos Exercícios Propostos
Capítulo 1
1 - Explique, com suas próprias palavras, o que é “Lógica de
Programação”.
Resposta: Lógica é a forma ordenada do pensamento. Então, para
a lógica de programação, é aforma ordenada de colocar as ordens
(instruções) nos programas para resolver um problema através da
computação.
2 - Por que não se deve partir direto para a codificação de um
programa sem, antes, criar o algoritmo/pseudocódigo.
Resposta: Por que a solução de um problema é dada pelo
algoritmo/pseudocódigo, e não pela linguagem de programação.
A codificação apenas traduz a solução do problema para a sintaxe
da linguagem. Codificar não é programar!
3 - Qual é a vantagem de se declarar um endereço de memória
RAM como constante, em vez de variável? Dê um exemplo.
Resposta: O conteúdo de uma variável pode ser alterado em
qualquer momento do programa; mas, na constante o conteúdo
não poderá ser alterado por atribuição e/ou leitura. Por exemplo:
o número PI, que é sempre um valor usado em cálculos que
envolvem áreas, seu valor é utilizado frequentemente com apenas
duas decimais (3.14); assim, caso se desejar usar essa constante
com mais decimais, basta alterar na declaração, que esse novo
valor será alterado, automaticamente, em todo o programa.
380
4 - Qual é a vantagem de fazer o pseudocódigo depois do
algoritmo de um programa?.
Resposta: A solução de um problema é dada na fase de
algoritmo/pseudocódigo do programa; não na codificação. Então,
sem algoritmizar a solução do problema, a codificação ficará
muito difícil de ser conseguida; além do mais, caso haja algum
erro de lógica no programa, e tiver que rever a solução, isto deve
ser feito antes da codificação.
5 - Explique por que o conceito de variável é fundamental na
programação,
Resposta: O endereço de memória é o local onde são guardados
os dados/informações, temporariamente, antes de serem
processados. Como o programador não sabe o endereço real na
memória RAM, então uma variável é utilizada como endereço
simbólico. Portanto, as variáveis representam o que é de mais
importante para o programador; como se fossem locais de sua
“mesa de trabalho”.
6 - Se você tivesse que nomear uma variável para armazenar o
nome do Campeonato Mundial de Futebol da FIFA para 2024,
qual dos identificadores é o mais apropriado?
A ( ) CampeonatoMundialDeFutebol2024
B ( ) CampeonatoMundialFIFA2024
C (X) FIFA2024
D ( ) FutebolFIFA2024
E ( ) CampeonatoFIFA2024
7 - Explique, com um exemplo, a diferença entre Algoritmo e
Pseudocódigo.
Resposta: Um pseudocódigo é quase um algoritmo, e muitos
autores o consideram assim; entretanto, em termos mais técnicos,
381
o algoritmo é uma “descrição informal da solução do problema”,
enquanto que o pseudocódigo é uma “descrição formal da
solução do problema”, utilizando recursos de programação e
variáveis de memória. Por exemplo: “Somar dois números e
mostrar o resultado”.
Algoritmo: Pseudocódigo:
1) Pegar o primeiro número. Leia(N1)
2) Pegar o segundo número. Leia(N2)
3) Somar os dois números. S <- N1 + N2
4) Mostrar o resultado da soma. Escreva(S)
Observe que o pseudocódigo já é quase um código pronto; uma
descrição mais compacta da solução do problema.
8 - De acordo com as teorias de Mark A. Changizi[7], se os
vulcanianos - planeta natal do Dr. Spock - tiverem três dedos em
cada mão (tal como a criaturinha do filme ET - O Extraterrestre),
então, provavelmente, o sistema de numeração deles seria o da
base hexa (base 6). Considerando essa teoria, marque nas
alternativas abaixo a que aparece um número (representado na
Base Decimal) que jamais poderia ser escrito na Base Vulcaniana,
considerando que a Matemática vale para todo o Universo.
Explique, o porquê da sua resposta.
A ( ) 31234
B (X) 4356 //base 6 não pode conter o dígito 6
C ( ) 234100
D ( ) -1
E ( ) 0
9 - Sabemos que para realizar uma tarefa é necessário executar
alguns passos (poucos ou muitos, dependendo da solução
adotada). Suponha que um cliente deseja que você resolva um
382
problema para ele, através de um programa; e, considerando o
esquema abaixo, qual dos três caminhos você escolheria para
solucionar esse problema?
A ( ) O caminho de cima.
B ( ) O caminho do meio.
C ( ) O caminho de baixo.
D (X) Aquele que produzisse uma solução mais eficaz.
E ( ) Qualquer um serviria.
10 - Explique porque a instrução X = X + 1 escrita na linguagem
C, por exemplo, não pode ser interpretada como uma equação
matemática.
Resposta: Matematicamente, a equação acima não tem solução,
pois, não existe nenhum número X tal que o membro da esquerda
fique idêntico ao membro da direita. Por isto, a interpretação em
C, ou em qualquer outra linguagem que use = como operador de
atribuição, seria: “X recebe X + 1” não “X é igual a X + 1”
11 - Crie um algoritmo para verificar se um determinando número
é primo, ou não.
1) Leia um número inteiro.
2) Descubra os seus divisores.
3) Some a quantidade dos divisores
4) Se (o número de divisores for dois) Então é primo, Senão
não é primo.
5)
383
Capítulo 2
1 - Qual é a vantagem de se usar a “Barra de Ícones” do Visualg
para executar uma ação na criação de um programa, sabendo que
essas mesmas ações podem ser obtidas na “Barra do Menu
Principal”?
Resposta: A vantagem de usar a Barra de Ícones é a maior
agilidade na execução das opções oferecidas pela ferramenta.
2 - Qual é a diferença entre comandos e funções (internos) no
Visualg? Dê exemplos.
Resposta: As funções sempre retornam algum valor quando
executadas; assim, podemos atribuir esse retorno (resultado) à
uma variável; por exemplo, X <- RaizQ(16). Os comandos são
ordens executadas, e o resultado não pode ser atribuído à uma
variável; apenas observar, sentir, seu efeito; por exemplo, o
comando LimpaTela apenas limpa a tela; não retorna nada.
3 - Se o Visualg não é uma linguagem real, qual é a sua
importância no aprendizado de Linguagem de Programação?
Resposta: Embora não seja uma linguagem real de programação,
o Visualg é uma ferramenta poderosíssima para testar o algoritmo
da solução do problema, traduzido em pseudocódigo (portugol),
e o testa, o que auxilia muito no aprendizado de Programação.
4 - Existem erros no programa “AreaCirculo” escrito em
Visualg. Mostre quais são esses erros.
384
Algoritmo "AreaCirculo"
//Calcula a área de um círculo, dado o seu raio.
//-----------------------------------------------------
Var raio, area: inteiro
Const: PI=3.14159265
Inicio
Escreva("Digite o valor do raio do círculo: ")
Leia(raio)
area <- PI*raio^2
Escreva("Área do círculo: ", area)
FimAlgoritmo
Resposta: Existem dois erros: o primeiro é que a declaração da
constante PI não pode ser feita, por ser uma palavra reserva do
Visualg; e além disto, mesmo se pudesse, a declaração de
constantes tem que vir ANTES das declarações de variáveis. O
segundo erro está no tipo de dado declarado para a variável area,
que deveria ser real e não inteiro, pois, seu cálculo resultará num
valor não inteiro.
5 - Observe o programa abaixo, em Visualg: ele vai rodar?!.
Explique!
Algoritmo "AreaTriangulo"
//Calcula a área de um triângulo dadas sua base e altura.
//-----------------------------------------------------
Var B, h, Area: real
Início
Escreva("Digite o valor da base: ")
Leia(b)
b <- Abs(b)
Escreva("Digite o valor da altura: ")
Leia(h)
h <- Abs(h)
area <- b*h
EscrevaLn("Área do triângulo:", Area)
FimAlgoritmo
385
Resposta: Sim, vai rodar (se os dados forem entrados
corretamente); mas, o resultado para a área do triângulo seria
exibido com valor incorreto, devido ao erro no seu cálculo.
6 - Marque com V os identificadores válidos para variáveis e com
F para os não válidos.
A ( V ) DevIR20
B ( V ) AmanhaDeManhaVouPedirOCafePraNosDois
C ( F ) MédiaGeral
D ( F ) QteMaçãs
E ( F ) 2aNota
F ( V )