ApPascal Jan 2000
ApPascal Jan 2000
ApPascal Jan 2000
A PROGRAMAR NA
PRÁTICA
Virgílio V. Vilela
"A rocha é imensa e dura. O cortador bate uma, duas, três, dez vezes,
nenhuma rachadura. Ele dá 100 marteladas, só tirando lascas. Na
centésima primeira batida, a rocha imensa e dura se parte em duas. O
cortador de pedras sabe que não foi somente aquela martelada a que
conseguiu, mas também todas as que vieram antes".
APRESENTAÇÃO____________________________________________________________________3
COMO ESTUDAR NESTA APOSTILA___________________________________________________5
1. INTRODUÇÃO À PROGRAMAÇÃO DE COMPUTADORES_________________________7
1.1. Programas e programação______________________________________________________________7
1.2. Conhecendo os programas______________________________________________________________8
1.3. A linguagem do computador____________________________________________________________8
1.4. Linguagens de alto nível_______________________________________________________________9
1.4.1 Tipos de instruções de alto nível____________________________________________________10
1.5. Conversão do programa-fonte__________________________________________________________11
1.6. Orientação das linguagens de alto nível___________________________________________________12
1.7. Linguagem Pascal___________________________________________________________________12
1.8. Software que você precisa ter ou conhecer________________________________________________13
1.9. Fatores de sucesso___________________________________________________________________14
1.10. Para você que está começando__________________________________________________________15
1.11. Atividades suplementares_____________________________________________________________16
2. PENSANDO A PROGRAMAÇÃO________________________________________________17
2.1. Meu Primeiro Robô__________________________________________________________________17
2.2. Brincando de robô___________________________________________________________________22
2.3. Algoritmos_________________________________________________________________________26
2.3.1 Representando problemas e situações________________________________________________27
2.4. Atividades suplementares_____________________________________________________________30
3. O PROCESSO DE PROGRAMAR_______________________________________________31
3.1. Estratégia geral de programação________________________________________________________31
3.2. Etapas da programação_______________________________________________________________32
3.3. Especificação do programa____________________________________________________________32
3.4. Projeto de programas_________________________________________________________________35
3.4.1 O que os programas fazem________________________________________________________35
3.4.2 Tipos de programas______________________________________________________________36
3.4.3 Estrutura de programas___________________________________________________________38
3.4.4 Projetando programas____________________________________________________________40
3.5. Visão geral de um programa-fonte_______________________________________________________44
3.6. Teste e qualidade de programas_________________________________________________________45
3.6.1 O que testar____________________________________________________________________47
3.7. Atividades suplementares_____________________________________________________________48
4. O AMBIENTE TURBO PASCAL________________________________________________51
4.1. O Turbo Pascal______________________________________________________________________51
4.2. Instalando o Turbo Pascal_____________________________________________________________51
4.3. Acessando o Turbo Pascal_____________________________________________________________52
4.4. Editando texto______________________________________________________________________52
4.5. Alternativas para obter ajuda___________________________________________________________55
4.6. O DOS Shell: um pouco de MS-DOS____________________________________________________56
5. PRIMEIROS PROGRAMAS____________________________________________________59
5.1. Primeiras instruções__________________________________________________________________59
5.2. Mais de Write_______________________________________________________________________63
5.3. Turbo Debugger_____________________________________________________________________69
5.4. Expressões aritméticas________________________________________________________________70
5.5. Units______________________________________________________________________________74
5.6. Funções___________________________________________________________________________78
5.6.1 Funções matemáticas____________________________________________________________78
5.6.2 Números aleatórios______________________________________________________________81
5.7. Constantes declaradas________________________________________________________________83
5.8. Atividades suplementares_____________________________________________________________84
6. MEMÓRIA E ENTRADA DE DADOS____________________________________________87
6.1. Comandos de memória________________________________________________________________87
6.2. Tipos de dado_______________________________________________________________________90
6.2.1 Tipos de dado do Turbo Pascal_____________________________________________________90
6.3. Mais do tipo de dado char_____________________________________________________________97
6.4. Mais do tipo de dado string____________________________________________________________99
6.5. Descobrindo variáveis_______________________________________________________________101
6.6. Declarando seus próprios tipos de dado__________________________________________________106
6.7. Conversões entre tipos de dados_______________________________________________________107
6.8. Atividades suplementares____________________________________________________________109
7. ALTERNATIVAS E DECISÃO_________________________________________________113
7.1. Decisão e expressões lógicas: IF_______________________________________________________113
7.2. Múltiplas alternativas: CASE__________________________________________________________120
7.3. Reconhecendo decisões______________________________________________________________124
7.4. Organizando o pensamento: árvores de decisão___________________________________________127
7.5. Atividades suplementares____________________________________________________________128
8. REPETIÇÃO_________________________________________________________________133
8.1. While____________________________________________________________________________133
8.2. Repeat____________________________________________________________________________136
8.3. For______________________________________________________________________________138
8.4. Casos freqüentes e problemas com comandos de repetição__________________________________142
8.5. Programando repetições______________________________________________________________144
8.6. Atividades suplementares____________________________________________________________155
9. CRIAÇÃO DE INSTRUÇÕES E MODULARIZAÇÃO_____________________________157
9.1. Instruções criadas pelo programador____________________________________________________157
9.2. Tipos e características de instruções____________________________________________________158
9.3. Declarando procedimentos____________________________________________________________159
9.4. Parâmetros por referência____________________________________________________________165
9.5. Funções declaradas pelo programador___________________________________________________169
9.6. Independência e reusabilidade_________________________________________________________171
9.7. Roteiro para criar novas instruções_____________________________________________________173
9.8. Reusabilidade total: units_____________________________________________________________177
9.9. Atividades suplementares____________________________________________________________183
10. LISTAS NUMERADAS: VETORES E MATRIZES________________________________189
10.1. Vetores___________________________________________________________________________189
10.2. Declaração de vetores_______________________________________________________________190
10.3. Operações com vetores______________________________________________________________191
10.4. Processando todo um vetor___________________________________________________________194
10.5. Registros_________________________________________________________________________200
10.6. Matrizes__________________________________________________________________________203
10.7. Atividades suplementares____________________________________________________________207
11. TRABALHO FINAL__________________________________________________________209
11.1. Especificação______________________________________________________________________209
11.2. Projeto___________________________________________________________________________209
11.3. Programa-fonte_____________________________________________________________________210
11.4. Teste_____________________________________________________________________________215
11.5. Idéias para trabalhos_________________________________________________________________215
APÊNDICE A: PERGUNTAS FREQÜENTES____________________________________________219
APÊNDICE B: PROCEDIMENTOS E FUNÇÕES DO TURBO PASCAL_______________________221
APÊNDICE C: FERRAMENTAS DE PENSAMENTO______________________________________223
APÊNDICE D: TABELA ASCII________________________________________________________227
BIBLIOGRAFIA____________________________________________________________________229
ÍNDICE REMISSIVO________________________________________________________________231
APRESENTAÇÃO
A linguagem adotada é o Turbo Pascal 7.0 da Borland, uma versão para DOS. Uma razão
básica para isso é reduzir a quantidade de informações necessárias para que o estudante obtenha
resultados. De qualquer maneira, este não é um livro destinado a esgotar os recursos da
linguagem. O objetivo não é formar especialistas, e sim apoiar a formação básica de
programadores, cuja prioridade maior consiste em desenvolver as habilidades centrais
mencionadas acima. Feito isso, o programador estará em condições de dominar outras
linguagens rapidamente.
Estrutura do curso
Uma das primeiras atividades é colocar o aprendiz em contato com os programas, para
criar uma visão das possibilidades e do que ele vai fazer. Por isto, é imprescindível que ele tenha
os programas de demonstração que acompanham este texto.
De maneira geral os capítulos iniciam com práticas que mostram ao aluno como funciona
algum recurso da linguagem, o que em alguns casos será suficiente. Caso seja necessário, ele
pode recorrer às explicações, embora o mais importante seja o aluno fazer coisas e perceber o
feedback proporcionado pelo computador; isto é considerado mais didático do que exigir que o
aluno saiba descrever como as coisas funcionam. Nesta edição também se procurou fornecer
uma estratégia geral de programação, envolvendo especificação, projeto e implementação, com o
objetivo de suprir o aluno com uma estrutura, independente de linguagens, que organize seu
pensamento na direção dos resultados desejados.
Várias das modificações efetuadas nesta versão refletem conceitos e métodos da
Aprendizagem Dinâmica, de Robert B. Dilts e Todd Epstein, que acredito vão efetivamente
facilitar para os alunos o desenvolvimento das habilidades de programar.
O autor
Agradecimentos
Ao Professor Sílvio Moreira Santana, por me mostrar que os alunos poderiam ir muito
além das minhas expectativas e das deles; ao Professor Vicente P. Teixeira, pelo Apêndice B; ao
Professor Roberto Silveira, então chefe do Departamento de Informática da UNEB, pela
liberdade e apoio proporcionados.
Comentários, críticas e sugestões serão muito bem-vindos e podem ser enviados via
Internet, para [email protected].
Brasília, Janeiro/2000.
COMO ESTUDAR NESTA APOSTILA
Em algumas páginas há caixas com textos explicativos. Uma vez que o objetivo é
formar programadores, não é estritamente necessário ler essas explicações; o
essencial é saber programar, e não saber explicar ou contar como é que se
programa. Programar é implementar causas para efeitos desejados, e se você sabe
o que acontece quando escreve Write(N) em um programa, não se considera aqui
que você deva saber descrever para alguém o que é este comando.
0. INTRODUÇÃO À PROGRAMAÇÃO DE
COMPUTADORES
Um computador é uma máquina que, para realizar algo, precisa que alguém lhe indique o que
fazer, de uma forma que ele entenda. Para que você possa fazer isso, é preciso que:
Conheça o computador e os recursos disponíveis;
Saiba o que quer que o computador faça;
Instrua o computador, através de um programa escrito em uma linguagem de programação.
Nesta introdução veremos informações básicas para se aprender uma linguagem de programação
de computadores. Pressupomos aqui que você está familiarizado com os fundamentos do processamento
de dados, incluindo operação do computador e periféricos, sistema operacional e sistema de arquivos.
Uma diferença entre máquinas em geral e o computador é que este pode fazer muito mais coisas,
portanto precisa de uma variedade maior de comandos. E outra diferença fundamental: o computador
pode armazenar os comandos, agrupados em programas, para execução posterior.
8
Quando viajamos, nossa principal referência é o destino desejado, que nos guia nas decisões de
para onde virar. Nesta seção você vai conhecer o nosso destino: programas prontos. Há uma infinidade
deles; aqui veremos aqueles dentro dos nossos propósitos.
Para as atividades desta seção, você vai precisar dos programas que são parte do curso. Todos
podem ser executados a partir do programa principal, chamado "demoap.exe". Se você não possui o
disquete de programas, obtenha-os na Internet, na página indicada no final da apresentação da apostila. Se
os programas foram fornecidos em um único arquivo compactado, descompacte-os em uma única pasta.
Para que os programas de demonstração possam ser executados, eles precisam constar do
cadastro do programa (arquivo "cadprog.dat"). Outros programas podem ser cadastrados a partir de uma
opção no menu principal.
Os programas que você vai ver foram feitos por ex-alunos, pelo próprio autor ou obtidos na
Internet. Divirta-se!
1 2 3 4 5 6 ...
56 23 0 247 154 87 ...
Esquema simplificado da memória RAM: endereços, bytes e respectivos valores.
Para não termos que programá-lo nessa linguagem difícil, foram desenvolvidas as linguagens de
alto nível. Estas nos permitem descrever o que queremos que o computador faça utilizando instruções
mais próximas da nossa linguagem. Além de facilitar a descrição dos processos a serem executados, as
linguagens de alto nível simplificam a utilização da memória do computador, diminuindo a quantidade de
detalhes com os quais deve ocupar-se o programador. Assim, ao invés de lidarmos com bits, bytes,
endereços de memória e uma infinidade de outros detalhes, podemos pensar em "limpar a tela", "imprimir
uma linha de texto", somar e subtrair variáveis como na matemática e tomar uma decisão na forma "se...
então".
Veja um exemplo específico: as instruções abaixo, na linguagem Pascal, determinam que a tela
seja limpa e uma soma seja efetuada, e o resultado desta mostrado na tela:
ClrScr;
Write(513 + 450 + 1200);
Uma linguagem de programação de alto nível possui várias características em comum com a
nossa linguagem. Elas possuem um alfabeto (letras, números e outros símbolos) e palavras. Há palavras
predefinidas na linguagem, mas também podemos formar as nossas próprias. Frases podem ser
construídas com as palavras, respeitando-se certas regras. O conjunto de regras de construção de palavras
e frases numa linguagem de alto nível, assim como nas linguagens comuns, chama-se sintaxe.
10 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
O que você pode fazer dentro de um programa, utilizando uma linguagem de alto nível? Vamos
ver algumas analogias com outras máquinas.
Para poder executar uma gravação programada, seu videocassete precisa tomar
pelo menos duas decisões: quando iniciá-la, e quando interrompê-la. Assim é num
programa: em várias situações será necessário fazer verificações e tomar decisões de
quando executar ou não um conjunto de instruções, ou executar um ou outro conjunto. Por
exemplo, um programa que lê uma nota que um aluno tirou em uma disciplina e deve
informar se ele foi aprovado ou não. Ou o programa informa que o aluno passou ou que foi
reprovado, mas nunca as duas coisas. Portanto, numa linguagem de alto nível, também
você pode esperar que existam instruções para tomada de decisões.
Para explorar a enorme capacidade de processamento de um computador, que tal deixarmos para
ele fazer coisas que exigem a repetição de um procedimento uma certa quantidade de vezes, sejam duas
ou milhões de vezes? Você também encontrará numa linguagem instruções para programar repetição
condicional de um grupo de instruções. Suponha que você quer escrever um programa que escreva seu
nome em cada linha da tela. Ao invés de escrever 25 instruções, uma para cada linha, você pode usar uma
instrução para repetir 25 vezes a instrução que mostra seu nome na tela. Em outros casos você terá um
padrão a ser seguido, como no caso do cálculo da média aritmética: lê o número, calcula a soma parcial,
incrementa um contador, lê outro número, calcula a soma parcial, incrementa um contador, e assim por
diante; no final da leitura, divide a soma pelo contador. Uma vez identificado o padrão, você escreve
apenas uma vez as instruções que se repetem e inclui um comando que controle a repetição.
Para facilitar a vida do programador, as linguagens de alto nível também contêm vários outros
tipos de instruções: todos contêm operações matemáticas básicas (soma, subtração, multiplicação e
divisão) e também funções matemáticas como seno, co-seno, logaritmo e exponencial. Algumas
linguagens disponibilizam instruções gráficas, para desenhar retas, círculos e outros objetos, colorir
objetos e muitas outras.
0 - INTRODUÇÃO À PROGRAMAÇÃO DE COMPUTADORES 11
E o melhor dos mundos: você também poderá criar suas próprias instruções e funções, que
depois de testadas e corretas, poderá usar como se fizessem parte do repertório da linguagem. Por
exemplo, você poderá escrever uma instrução chamada RepeteMeuNome, que mostra seu nome na tela 25
vezes. Uma vez testada, correta e gravada, basta inserir o nome da instrução na posição apropriada do
programa ("chamar" a instrução) para mostrar seu nome 25 vezes. E se quiser mostrar seu nome mais 25
vezes, basta "chamar" de novo a instrução. Para melhorar ainda mais, você pode criar a instrução de
forma que a quantidade de repetições seja definida somente quando o programa for executado.
Como o computador não entende as instruções de um programa-fonte, para que este possa ser
executado, ele precisa ser convertido para a linguagem que o computador reconhece, a linguagem de
máquina. Uma instrução em uma linguagem de alto nível pode corresponder a centenas ou até milhares
de instruções em linguagem de máquina. A conversão é feita por programas apropriados, e pode ser feito
antes ou durante a execução do programa.
te x to lin g u a g e m d e lin g u a g e m d e
m á q u in a m á q u in a
Note que não é a linguagem em si que é compilada e interpretada. Essa característica depende da
disponibilidade de um compilador ou um interpretador; pode haver ambos para uma linguagem, ou até
nenhum.
As instruções disponíveis em uma linguagem de alto nível podem não ser apropriadas para uma
determinada aplicação. Programas científicos têm muitas diferenças em relação a programas comerciais,
que também podem diferir bastante de programas voltados para tratar imagens ou de inteligência
artificial. Assim, foram desenvolvidas linguagens para áreas específicas. A primeira linguagem de alto
nível criada, o compilador FORTRAN, é direcionada para aplicações científicas. A linguagem COBOL,
também compilada, é orientada para aplicações comerciais. O interpretador BASIC é voltado para
iniciantes. A linguagem PL/I foi criada pela IBM para ser a união de várias linguagens. Há também várias
linguagens que facilitam o tratamento de grandes quantidades de dados, como SQL (Structured Query
Language).
Uma distinção importante a ser feita é que uma coisa é a linguagem, outra coisa é a
implementação comercial desta linguagem. Há uma definição padrão para a linguagem Pascal, por
exemplo, e há compiladores comerciais desta linguagem, como o Turbo Pascal. Normalmente os
ambientes de programação comerciais incluem instruções extras, conhecidas como extensões da
linguagem, o que os torna menos compatíveis com os outros. Os melhores compiladores comerciais
incluem outras facilidades, como ajuda on-line, exemplos e vários outros recursos.
O PASCAL (não fale "pascoal"!) foi desenvolvido por Niklaus Wirth para ser a primeira
linguagem de programação a ser aprendida. É bem fácil de ensinar e aprender, e sua estrutura é um pouco
mais rígida do que a de outras linguagens, visando estimular maior organização e disciplina no
programador. Isso se justifica devido ao fato de que as linguagens, ao mesmo tempo em que permitem a
elaboração de grandes soluções, possibilitam que se cometa grandes erros, principalmente em programas
maiores. Um programa pode estar sintaticamente correto e no entanto conter erros como seqüência
inadequada das instruções, valores incorretos ou também a sua execução pode nunca terminar
normalmente, porque as condições de terminação nunca são atingidas (esses erros são chamados “bugs”
ou erros de lógica).
Para a construção de programas grandes e com estrutura muitas vezes complexa demais para
nossos limites atuais, foram (e ainda continuam sendo) criadas várias técnicas e metodologias de
desenvolvimento e estruturação de programas mais fáceis de serem testados, alterados ou corrigidos. Mas
não se iluda: qualquer que seja a linguagem ou a metodologia, é possível produzir programas
0 - INTRODUÇÃO À PROGRAMAÇÃO DE COMPUTADORES 13
desorganizados, incompreensíveis e repletos de erros ou que não fazem o que deveriam fazer. A
qualidade final dos produtos dependerá predominantemente do programador.
Sistema operacional - Como programador, você precisa ter um mínimo de informações sobre o
sistema ou ambiente operacional em que vai trabalhar, como por exemplo:
Como executar programas
Os nomes que você pode dar aos arquivos
Como organizar seus arquivos em pastas ou subdiretórios
Como listar, excluir, renomear e copiar arquivos
Se o computador em que você trabalha está conectado a uma rede, você vai precisar de um nome
registrado, associado a uma senha, para poder acessar arquivos e programas da rede.
Editor de textos - Um programa Pascal é um texto simples, sem caracteres de controle do tipo
negrito, tamanho de fonte, paginação, etc. Você vai precisar de um editor para digitar seu programa no
computador. Editores que produzem tais textos são o Edit, que vem com o MS-DOS, o Bloco de Notas
(NotePad), que vem com o Windows, e vários outros. Textos formatados pelo Word, WordPad ou Carta
Certa não servem. Os compiladores comerciais normalmente trazem um editor; usá-los será normalmente
mais prático. O Turbo Pascal traz um ótimo editor, e você não precisará se preocupar com isto, exceto
talvez para imprimir os programas.
Compilador - Uma vez que você digitou o texto do programa, precisará convertê-lo para
linguagem de máquina. Para isso você precisa de um compilador. Como compiladores comerciais da
linguagem Pascal temos por exemplo as várias versões do Turbo Pascal, da Borland. Há versões para
DOS (até 7.0) e para Windows. Há vários outros, como o Free Pascal, compatível com o Turbo Pascal e
que você pode transferir via Internet gratuitamente.
Escolhemos o Turbo Pascal 7.0 por vários motivos: facilidade de instalação, ótima curva de
aprendizagem, por ser a base do Delphi (um dos ambientes de programação profissional mais usados
atualmente em micros) e ainda o fato de ser o "queridinho" da Internet: há muitos sites especializados
nele, e quase nada dos outros. O Turbo Pascal 7.0 é vendido até hoje, e não o acho exatamente barato, o
que é uma medida do interesse geral por ele.
14 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Um programador pode atuar em várias áreas. Como funcionário de uma empresa, normalmente
trabalha em equipe, recebendo especificações dos analistas de sistemas. Pode ter uma empresa, com
outros programadores ou não, e através dela comercializar seus programas. Outra possibilidade é
distribuir seus programas via Internet, na forma de shareware, modalidade de distribuição na qual o
usuário tem acesso ao programa para avaliação antes da decisão de compra. Há muitas pessoas que
programam por hobby, por gostarem, e vários deles acabam se profissionalizando, inclusive porque são
muitas as oportunidades para quem está disposto a fazer um bom trabalho.
Para que isso se materialize, são essenciais alguns recursos materiais e, além destes, há recursos
pessoais que, quanto mais desenvolvidos, mais enriquecem a competência do programador:
Computador pessoal - É fundamental que você tenha o seu próprio computador, para que se
dedique mais e melhor, para que pratique quando quiser e puder e mais um monte de razões. Para
começar, não é preciso ter um Pentium; é possível rodar o Turbo Pascal, nosso compilador, até em um
processador 286 e sistema operacional DOS 3.0. Por tudo isto, faça o que for preciso para ter o seu
próprio microcomputador ou para ter acesso a um.
Datilografia ou digitação - Se você é um (mau) “datilógrafo”, corra para fazer um curso, a não
ser que queira sofrer. Sua produtividade será bastante prejudicada.
Inglês - A menos que você tenha um compilador com ajuda ou manual em Português, procure
desenvolver pelo menos alguma habilidade de ler inglês. É essencial, por exemplo, para poder usufruir da
ajuda sensível ao contexto dos compiladores: você aperta uma tecla e aparecem informações sobre a
palavra onde está o cursor da tela. Não saber inglês é uma forma de analfabetismo da área de informática!
Tempo e dedicação - São os principais recursos que você pode investir, e constituem fatores
críticos de sucesso. Sem eles, nada será possível.
Limites - Ter uma consciência clara de que você tem limites permite que eles sejam respeitados e
também que possa ir além deles. Em um determinado momento, há limites para o que você sabe do
sistema operacional, da linguagem, do compilador. Há limites também para sua capacidade de organizar
mentalmente informações em maior quantidade. Conhecer seus limites pode evitar aborrecimentos, no
sentido de que você saberá exatamente quando precisa de melhores informações ou métodos e que está na
hora de buscá-los.
"Se algo está difícil, eis aí uma indicação de algo que você não sabe"
Richard Bandler & John Grinder
Experiência - Aprender a programar computadores é um processo que tem um início, mas não
um fim, e se há limites para o que você sabe, não há limites para o que você pode aprender. Você vai
0 - INTRODUÇÃO À PROGRAMAÇÃO DE COMPUTADORES 15
aprender de livros, exemplos, ao ver outros fazendo e outras formas. Mas a meu ver, a experiência (e o
que você fizer com ela), incluindo os erros aproveitados e os desafios vencidos, será seu melhor professor
e o que lhe proporcionará os aprendizados mais consistentes. E o que você pode aprender depende pura e
simplesmente de sua dedicação e de sua calma em progredir passo a passo.
Neste capítulo você obteve algumas noções básicas sobre o que é programar computadores e do
que você precisa para iniciar. Já sabe que tudo que é feito com e através do computador só é possível
porque há pessoas elaborando os programas necessários. E cada um desses programas foi produzido por
um programador ou uma equipe de programadores. Nos programas maiores podem estar envolvidos
vários tipos de pessoas: programadores visuais, consultores e até compositores para as trilhas sonoras.
Mas o programador é o único com presença garantida em qualquer projeto de programação.
Mas na vida de todo programador houve um tempo em que ele não sabia nada; teve que começar,
e do jeito mais simples. Primeiro aprendendo algo sobre como o computador funciona, depois aprendendo
as primeiras instruções. Quase sempre o primeiro programa mostra uma frase na tela ou efetua uma
operação aritmética básica. Após dominar os princípios da coisa, ele aprende novas instruções, como
fazer um programa tomar decisões e controlar repetições, depois cria as suas próprias instruções. Conhece
uma nova linguagem, descobre novas formas de programar, aplica suas próprias idéias, ultrapassa
obstáculos e aproveita várias oportunidades, sucessivamente atingindo graus crescentes de maturidade.
Provavelmente (e isto é bom) você tem vários pontos de interrogação: É difícil? Será que eu
consigo? É legal? Dá pra ganhar dinheiro programando? Como é que é esse Pascal? Tem que dedicar
muito pra ficar bom? E por aí vai.
encontrará também temas não diretamente técnicos que podem ser, em certos momentos, até
mais importantes.
Obstáculos fazem parte da vida de quem aprende; quem está aprendendo nem sempre está na
"zona de conforto", pelo contrário, está avançando sobre limites. Certos fatos, chamados em
outros contextos de "problemas", para profissionais de informática são na verdade
oportunidades de melhoria, são feedback; bons profissionais aprendem como fazer e também
como não fazer.
O que vai acontecer depende basicamente de quanto você estiver disposto a investir, sabendo que
às vezes semeamos para colher os frutos algum tempo depois, e que cada minuto dedicado com certeza
dará seus frutos. Siga a receita do sucesso: estabeleça onde quer chegar (em etapas, se necessário) e tome
as medidas necessárias para chegar lá, modificando suas atitudes ou estratégias quando verificar que o
que está fazendo não está funcionando.
C P I A X A D E C I S Ã O
O S S I N T A X E V N O I
M M A R T E O P M N A R N
P O X Ó Y S E E I E F W T
I T E M E T E R R O U A E
L I R E P E T I Ç Ã O R R
A V E M L A I Ê O O H N F
Ç A Ç A H S K N C P L O A
Ã Ç O I N G O C I M A T C
O Ã Ç A C I F I C E P S E
S O L E I F X A A T O J P
1. PENSANDO A PROGRAMAÇÃO
Você sabe que cada disciplina possui formas peculiares de pensar: a forma de resolver problemas
de Matemática não é a mesma da Biologia. A forma de pensar da Física inclui a da Matemática e algumas
outras. De forma análoga, a programação de computadores requer raciocínios apropriados, chamados em
geral de "lógica de programação". Essa lógica é uma combinação de elementos simples, que todos
usamos no dia a dia mas nem sempre estamos cientes: executar uma seqüência de ações, tomar decisões
diante de alternativas e controlar ações repetidas.
Uma vez que você já conhece essas ações, este capítulo vai prepará-lo para lidar com esses tipos
de ações, na forma como são usados na programação.
PARTE I: UAU!
Ano: 2010. Cenário: sua casa. No seu aniversário, você realizou um sonho: ganhou um magnífico
robô tipo humano, modelo sem-sexo. Não é o mais moderno, é verdade, mas sem dúvida é sensacional.
E agora você deve aprender a operá-lo, e para isso dispõe tão-somente do manual de instruções (e
quando tiver grana, talvez você faça o curso da loja...).
Você então faz o primeiro teste: virando-se para o robô estático, você diz:
Ligue a televisão no canal 10. O robô fica imóvel. Você insiste:
Robô, ligue a televisão! E ele responde! Numa voz masculina, algo metálica, mas não
desagradável, ele diz:
Instrução não compreendida.
Pô, robô, como é que você funciona?
Instrução não compreendida.
Você então se resigna e pega o manual. Lá, descobre que todas as comunicações com o robô
devem iniciar-se com a palavra “ROBÔ”, e que ele entende a linguagem, mas não como falamos
normalmente. Seus comandos devem ser instruções num formato específico: algumas regras devem ser
obedecidas. Além disso, o robô tem um repertório limitado de instruções: só é capaz de fazer o que já tem
programado.
Mais resignado (ou resignada) ainda, você pacientemente dá uma olhada geral no manual,
enquanto procura pelas instruções que o robô entende. Encontra então uma seção de aprendizagem rápida,
e descobre que para fazer o robô falar algo, deve dizer-lhe:
Fale(Frase, Entonação).
Mas o manual alerta para dizer o Fale, não pronunciar os parênteses, substituir Frase pelo que
você quer que ele fale, e substituir Entonação por uma das palavras: Normal, Enfático, Sussurrante,
Nervoso, Autoritário e Staccato. Você pode omitir a entonação, e o robô assumirá Normal. Testando,
você diz ao robô:
Fale Você é muitcho legal, Staccato.
18
maneiras de por objetos em sua mão é através da instrução Pegue(Objeto). Pensando “primeiro tem que
pegar, para depois colocar”, você diz:
Robô, Pegue Lego. Robô, Coloque Caixa do Lego.
O robô imediatamente se abaixa, pega uma peça e a coloca na caixa.
Robô, é pra você guardar todas!
Favor reformular a instrução.
Angustiado com a possibilidade de ter que dizer ao robô 200 vezes as instruções ou, pior, você
mesmo guardar as peças, de repente se lembra de um amigo que já teve um robô com ULP (e agora tem
um modelo com-sexo!). Liga pra ele e fica sabendo que vai ter que programar o robô, criando uma nova
instrução que o ensine a guardar todos os legos. O amigo disse que você poderia programar 200 vezes o
Pegue e Coloque, mas seria mais simples usando uma instrução de repetição.
Conferindo o que seu amigo disse, você lê no manual que, para programar o robô você deve
descrever, na linguagem dele, o padrão de comportamento que ele deve seguir. As instruções que
descrevem o padrão são armazenadas na memória do robô sob um nome que você mesmo atribui, depois
da palavra algoritmo, que é o nome dos programas do robô. Após a programação, basta dizer ao robô o
nome dado para que as instruções sejam executadas. Mas atenção, alerta o manual: se um algoritmo tiver
comando de repetição e o robô não achar uma condição de terminação, ele o executará até que seja
desligado ou acabe a bateria.
Sem entender muito bem o que o manual queria dizer com o alerta, mas muito interessado, você
tenta um pequeno programa. Após verificar como fazer a programação, diz ao robô:
Robô, programar.
Registrado.
Algoritmo LigarTV. Ligue(Televisão). Sintonize(Televisão, 10). Fim algoritmo. O robô, sem se
mexer:
Registrado.
Robô, LigarTV.
Ele imediatamente se dirige à televisão e a liga, sintonizando no canal 10. “Bom, bom”.
Pensando agora no problema de catar o lego, você procura a seção do manual que trata de
programação de repetições, conforme indicado pelo seu amigo. Chamam sua atenção as instruções:
ALGORITMO GuardeLego
REPITA 100 VEZES
Pegue(Lego)
Coloque(Caixa do Lego)
FIM-REPITA
FIM-ALGORITMO
Você repassa mentalmente as instruções e acha que está tudo na seqüência correta. Já acostumado
com aquele jeito estranho de conversar, comanda o robô, enquanto lê suas anotações:
Robô, programar.
Registrado.
Algoritmo Guarde Lego. Repita 100 vezes. Pegue Lego. Coloque Caixa do Lego. Fim Repita.
Fim algoritmo.
Registrado.
- Robô, guarde lego.
Sucesso! O robô, com seu jeito mecânico, pega e guarda as peças, uma a uma, até que para.
Ainda restam peças no chão.
Você começa a pensar em como poderia utilizar a instrução REPITA..ATÉ para mandar o robô
guardar as peças até não restar nenhuma. Mas outra idéia vem, você faz uma expressão marota e diz ao
robô:
Robô, programar.
Registrado.
Algoritmo Chateie Irmã. Execute 1000 vezes. Fale você não deve mexer no robô, Staccato. Fale
você não deve mexer no robô, Enfático. Fim Execute. Fim algoritmo.
Registrado.
Parte II: Tomando decisões
Agora você quer descobrir como fazer o robô catar o lego até não restar nenhuma peça. Já
familiarizado com o manual, você procura no índice alfabético pela palavra “FIM”. Nada. Depois tenta
“TÉRMINO”, e nada ainda. De súbito, vem uma idéia e você procura “DECISÃO”. E lá está: “Decisões,
tomando”. Abrindo na página indicada, encontra a descrição da seguinte instrução:
SE <condição> ENTÃO
<instrução 1>
<instrução 2>
...
FIM-SE
Nesta instrução, se a <condição> for verdadeira, o robô executará as instruções depois de
ENTÃO e até FIM-SE. Por isso, no lugar de <condição> você deve colocar uma instrução que tenha
resposta do tipo VERDADEIRO ou FALSO.
Procurando no índice “CONDIÇÃO”, e abrindo na página indicada, você descobre que o robô é
capaz de fazer avaliações do ambiente, através da instrução
CONDIÇÃO (Objeto, Estado).
Ao instruir o robô, Objeto deve ser trocado por lâmpada, porta, algum aparelho ou outro objeto
que o robô reconheça. Estado deve ser substituído por aberto, fechado, ligado, desligado ou outro, que
faça sentido para o objeto informado. O exemplo do manual lhe pareceu uma das formas mais estranhas
que já tinha visto de se comunicar com alguém:
SE Condição(Lâmpada, Acesa) ENTÃO Desligue(Lâmpada).
2 - PENSANDO A PROGRAMAÇÃO 21
Ande(X passos)
As respostas dos exercícios devem ter a forma de um algoritmo, como na história. Veja um
exemplo:
Solução:
Algoritmo BuscaOPote_2
Ande(10 passos)
Vire(90 graus)
Ande(3 passos)
Vire(-90 graus)
Ande(8 passos)
Fim
Algoritmo BuscaOPote_com_erro
Ande(10 passos)
Vire(90 graus)
Ande(4 passos)
Vire(90 graus)
Ande(8 passos)
Vire(90 graus)
Ande(4 passos)
Vire(-90 graus)
Ande(8 passos);
Fim
?
Verifique que o algoritmo deve ter os seguintes passos:
"Ande até o local do obstáculo"
"Se puder passar"
"Ande até o pote"
"Senão"
"Volte ao ponto de partida".
Lembre-se de que o robô, diante de alternativas, pode tomar decisões, na forma:
Se <condição> então
Ações
Senão
Outras ações.
Consultando o manual, verificamos que o robô entende uma instrução do tipo verdadeiro ou falso, no
formato Possível(Verbo), onde verbo é uma ação. Uma das ações pode ser andar, ou seja, a instrução
informa verdadeiro quando o robô pode dar um passo e falso quando não pode. Com essa instrução,
podemos converter os passos acima para um algoritmo que o robô entenda:
Algoritmo BuscaOPoteComDecisão;
Ande(6 passos)
Se Possível(Andar) então
Ande(6 passos)
Senão
Vire(180 graus)
Ande(6 passos);
fim.
2 - PENSANDO A PROGRAMAÇÃO 25
Algoritmo AndandoComRepetição
Repita
Ande(1 passo)
Até que Impossível(Andar);
Vire(90 graus);
Repita
Ande(1 passo)
Até que Impossível(Andar)
Vire(-90 graus)
26 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Repita
Ande(1 passo)
Até que Impossível(Andar)
Vire(90 graus)
Ande(6 passos)
Vire(-90 graus)
Ande(6 passos)
fim
Note que para a maioria do percurso não precisamos mais saber quantos passos o robô deve dar, o que
sem dúvida proporciona muito mais flexibilidade.
1.3. Algoritmos
Como você viu na história do robô, algoritmos descrevem padrões de ação para se resolver um
problema ou atingir um determinado resultado, usando um repertório de ações disponíveis. A elaboração
de algoritmos é a alma da programação; boa parte desta consiste em se achar soluções que possam ser
implementadas com os recursos disponíveis no computador e em uma linguagem de programação. O
personagem da história estava envolvido em elaborar algoritmos para conseguir que o robô fizesse o que
queria, assim como você, nos exercícios, estava envolvido em fazer o robô chegar até o pote.
Todos estamos familiarizados com algoritmos, já que aplicamos vários no dia-a-dia. Quando você
decide que vai a algum lugar e escolhe o meio (a pé, de carro, de ônibus) e um itinerário, está elaborando
um algoritmo. Assim como os algoritmos do robô, você executa ações (andar), repete alguma ação até
que uma condição seja atingida (andar até chegar ao destino ou a um ponto intermediário) e toma
decisões (qual caminho tomar, para onde virar em encruzilhadas). Até quando paquera você elabora
algoritmos, embora possa não ter consciência disto. Ele ou ela me interessa? O que fazer primeiro, flertar
ou mandar um bilhetinho? Talvez você repita alguns comportamentos que funcionaram em outras
oportunidades (ou imite o padrão de alguém...).
2 - PENSANDO A PROGRAMAÇÃO 27
E se sabe fazer qualquer coisa ao fogão, seja ferver água ou preparar macarrão à bolonhesa, sabe
que, se não executar certas ações em uma determinada seqüência, não vai atingir os resultados desejados.
Mesmo para ler esta página está usando algum algoritmo. Assim, algoritmo para você é mais um nome
novo para algo familiar.
Uma página pode ser lida de várias maneiras: a que aprendemos na escola, a leitura dinâmica, a
fotoleitura. Ou seja, há vários algoritmos de leitura. O mesmo ocorre com os algoritmos de computador;
para um mesmo problema ou resultado desejado, podem haver várias soluções possíveis. Um problema
muito comum é ordenar uma série de valores em ordem crescente ou decrescente, como uma lista de N
nomes de clientes. Uma forma de fazer isto é percorrer a lista à procura do maior e colocá-lo em outra
lista, repetindo isto N vezes, a cada vez escolhendo o maior dentre os que restaram. Para o problema da
ordenação há vários outros algoritmos, como o da bolha, o quick-sort e o heap-sort, cada um apropriado a
um tipo de situação. No caso de ir a algum lugar pela primeira vez, você em geral estará procurando o
melhor algoritmo dentre várias alternativas para chegar lá.
b b 2 4ac
x
2a
A fórmula acima indica o que se deve fazer para achar as soluções usando os coeficientes, ou
seja, o padrão de comportamento que se deve seguir, e é um tipo de algoritmo. Designamos com nomes o
que é importante para descrever a situação (a, b, c) e indicamos a solução por meio de algum tipo de
representação das ações que devem ser executadas (operações matemáticas). E quando formos resolver o
problema para algum caso específico, trocamos os nomes pelos respectivos valores e executamos as
operações previstas.
De maneira geral, um algoritmo envolve coisas ou objetos, e ações sobre ou usando esses
objetos. Na equação acima os objetos são os coeficientes, representados por suas letras, e as ações são
elevar ao quadrado, subtrair, somar, dividir. Na história do robô os objetos eram legos, e as ações eram
procurar, pegar, colocar, além de ações de controle, como decisão e repetição. Lembre-se do que acontece
no Windows quando clica com o botão direito sobre um objeto, como um ícone de arquivo: aparece um
menu com as ações ou operações que você pode executar sobre aquele objeto.
Tudo se resume então a duas perguntas: como representar objetos e como representar ações sobre
os objetos, de uma forma mais fácil e mais apropriada. No Windows, representa-se arquivos como ícones
ou pequenas imagens, e esta é uma forma que alguém considerou apropriada para lidar com eles. No
antigo ensino primário, uma incógnita de um problema era representada por um ٱ. No nosso contexto
computacional, os objetos são representados de forma semelhante à matemática, usando-se variáveis.
Uma variável é um nome atribuído a um valor ou característica para generalizá-lo. Na equação do
segundo grau, "a" é o nome dado ao coeficiente do termo ao quadrado, que representa todos os
coeficientes possíveis para o termo.
28 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Veja como usamos variáveis no dia a dia: se você vai comprar um sapato,
o vendedor lhe pergunta: qual é o seu número? Você pergunta: quanto
custa? O número e o preço são variáveis que representam características
de um objeto, um sapato. Outras variáveis de um sapato podem ser de
interesse, conforme a pessoa: cor, marca ou altura do salto. Ao decidir se
paquera ou não alguém, você procura "valores" para certas variáveis de
seu interesse: sexo, idade, cor do cabelo, e por aí vai.
Como você já viu na história do robô, no contexto da programação há mais flexibilidade ao se dar
nomes a variáveis. É muito mais fácil entender nomes como "NomeCliente", "CodigoProduto" (não se
usa acentos nem espaços) e "Contador" do que com NC, CP ou C.
O que se pode fazer com as variáveis de um problema? Genericamente, o que se faz com
variáveis é armazenar valores ("atribuição") e recuperar valores armazenados (através do respectivo
nome). Outras operações dependem do papel da variável. Subtração, por exemplo, é uma ação apropriada
para se fazer com números. No caso de uma pessoa, "pegar" é uma ação apropriada para uma peça de
lego, mas "comer" não parece ser. Assim, as operações sobre as variáveis vão depender do que contém a
variável: se representa um número qualquer, pode-se fazer contas com ele. Se o número representa a
população de uma cidade ou a quantidade de faltas de um aluno, outras coisas podem ser feitas.
E uma vez que se sabe o que fazer, qual é a melhor forma de representar as ações? Para os nossos
propósitos, você pode imaginar um algoritmo como um "ser" ou processador (com memória) que recebe
uma entrada, na forma de variáveis, executa ações e produz uma saída também na forma de variáveis ou
um resultado:
E n tra d a
S a í d a o u r e s u lt a d o
A ções
a, b, c
X 1, X 2
C a lc u la r
ra íz e s
Se o algoritmo visasse um desenho, por exemplo, não haveria uma saída na forma de variáveis (e
talvez você desenhasse o próprio círculo na seta da saída).
2 - PENSANDO A PROGRAMAÇÃO 29
Assim, para representar uma solução algorítmica não há regras rígidas, você vai escolher a
melhor de acordo com o contexto e com o que conhece. Pode ser a matemática ou uma narrativa, como
acima. Pode ser como os algoritmos do robô. Existem formas mais visuais, como o fluxograma e o
diagrama de Chapin (ver por exemplo Guimarães e Lajes). Se muitas decisões devem ser tomadas em
seqüências, pode-se usar uma árvore de decisão (veja o capítulo 6). Você pode usar uma forma sua de
expressão, pode misturar tudo e pode inventar comandos. As diretrizes principais são usar algo que você
conheça e ficar próximo ao formato estruturado das linguagens de programação (o que você só pode fazer
quando conhecer uma). Elaborar um algoritmo pode ser um grande prazer, que não deve ser prejudicado
por nenhuma regra rígida.
2. O PROCESSO DE PROGRAMAR
Neste capítulo você vai ver tópicos que são imprescindíveis a qualquer programador e à
elaboração de qualquer programa. Conhecer e saber usar este material tornará tudo mais fácil, e não
conhecê-los pode realmente tornar todo o resto impossível.
Pense no seu corpo; o que imagina? Provavelmente pensou no seu corpo inteiro, um todo. Este
todo pode ser visto em um nível de estruturação: cabeça, tronco e membros. Ao ler isso, você deve ter
imaginado essas partes. Agora focalize os membros: estes também podem ser vistos de uma forma
estruturada: braços e pernas. Agora imagine um braço e suas partes... Continuando, passaremos pelo nível
fisiológico e pelos níveis celular, molecular, atômico e é possível descer ainda mais.
De forma análoga, você pode observar o universo, uma galáxia, um sistema solar,
um planeta, um continente, um país, um estado, uma cidade, um bairro, uma casa, um quarto
e...você praticando programação! Videogames têm fases, quebra-cabeças têm peças, livros têm
capítulos e por aí vai.
Esta estratégia é usada por um programador em todos os níveis, como você verá nas
seções seguintes.
Você já teve contato com alguns programas prontos. Viu que um programa faz algumas coisas,
outro faz outras diferentes. Viu como são os programas por fora, na visão do usuário, e já sabe que o que
produz esses efeitos no computador é um programa executável, programado originalmente como um
programa-fonte, que foi convertido para linguagem de máquina.
E S P E C IF IC A Ç Ã O
PR
OJ
ET
AR
AR
ST
TE
P R O G R AM A PR O G R AM A
F O N TE PR O JETAD O
IM P L E M E N T A R
Uma pessoa pode dirigir um automóvel de pelo menos duas maneiras: com destino ou sem
destino. Se não há destino definido, a pessoa pode andar a esmo por horas a fio, virando para qualquer
direção que lhe der na cabeça, que não fará muita diferença. Porém, se a pessoa sai de casa pretendendo ir
a algum lugar, a direção para onde vai determinará se vai ou não chegar ou se chegará com atraso. Isso
vale também para certos equipamentos domésticos: ao programar a gravação de um videocassete, por
exemplo, você terá em mente uma descrição precisa do que quer, como por exemplo:
3 - O PROCESSO DE PROGRAMAR 33
Você também sabe exatamente qual é o produto final: uma fita gravada com o programa
desejado. Reflita por um momento como você conseguiria programar o videocassete sem alguma das
informações acima.
Portanto, a primeira coisa a se ter em mente ao programar computadores é saber o que será feito,
uma descrição objetiva do que se espera que um programa faça, chamada especificação. Uma
especificação contém as características e detalhes relevantes de um programa: o que entra, o que sai,
instruções para cálculos, podendo incluir também figuras e diagramas ilustrativos. A especificação indica
o objetivo primário do programador. É o ponto de partida e o ponto de chegada. É a referência para ele
saber se está certo ou errado, e se está progredindo ou não. Certo é o que atende à especificação.
Uma especificação também deve ser completa, em termos de seus objetivos. Quando completa,
contém todos os detalhes necessários e suficientes para que o programa possa ser elaborado. Uma das
grandes causas de atrasos no desenvolvimento de programas são especificações incompletas, que obrigam
o programador a rever decisões anteriormente tomadas, com todo o retrabalho que isso pode causar. Por
exemplo, suponha que você entregou o programa dos juros, pronto, para o usuário testar. Ele então
descobre que esquecera de lhe informar que o cálculo dos juros, em uma determinada época, era feito de
forma diferente. Lá vai você então alterar o programa e testar tudo de novo.
"Mantenho seis servidores honestos, eles me ensinaram tudo o que sei. Seus nomes são: O quê e Por
Quê e Quando e Como e Onde e Quem".
Rudyard Kipling
O fato de haver especificações decorre em geral de haver alguém querendo um programa e não
sabe ou não quer fazê-lo, e então pede para um programador. Nesta situação, e em qualquer outra em que
o programa não foi concebido pelo próprio programador, este precisa entender o que o outro quer, para
que possa atendê-lo. A melhor forma de fazer isto é criar uma visão do resultado final, que aqui
chamamos de projetar o programa.
Ao ver pela primeira vez a especificação, você está no ponto em que dispõe da menor quantidade
de informações. Se está começando e não tem muita experiência, pode ter um "branco" ou um "preto"
total. Isto é natural; quando iniciamos algo, você sabe que é previsível que teremos alguma dificuldade,
muito mais pela falta de informação que por falta de habilidade. Também é comum ocorrerem no início
erros de interpretação da especificação, que vão sendo esclarecidos à medida que se prossegue. Não é
nem necessário chamar isto de "erros": se preferir, chame de "interpretações iniciais".
Todos esses fatores remetem a um só ponto: é preciso elaborar um projeto do programa, conceber
como ele ficará quando pronto. Imagine, por exemplo, que um jogo de computador deve ser programado.
Como será mais fácil fazer isto, começando de algumas frases no papel ou depois de já ter "jogado" o
jogo algumas vezes na cabeça? Na verdade, nenhum programador consegue fazer um programa sem tê-lo
na mente; o que às vezes ocorre é que o desenho vem sem que precisemos pensar conscientemente nele, o
que é inclusive evidência de maior maturidade.
Para projetar programas, você precisa saber como são os programas e o que é possível fazer com
eles e com o computador. Parte da experiência você já teve, ao experimentar os programas de
demonstração; veja mais a seguir.
Entrada – Programas efetuam leituras de dados (um número, um texto, uma tecla), normalmente
digitados pelo usuário. Após lido, um dado é guardado na memória para que possa ser usado depois.
Decisões – Diante de alternativas, os programas tomam decisões: o aluno passou? O número lido
é válido, ou seja, está dentro de uma faixa de valores esperada? Qual opção do menu deve ser executada?
Repetição – Por vezes os programas repetem algo que fizeram anteriormente, só parando quando
alguma condição for atingida. Em um menu, por exemplo, o programa só deve parar quando for digitada
a opção que indica o término.
36 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Cálculos e outras computações – algumas coisas que um programa faz podem não estar visíveis.
Por exemplo, em um programa que calcule raízes de equações do segundo grau, na tela vão aparecer
mensagens pedindo para informar os coeficientes da equação e para mostrar os resultados, mas o cálculo
feito não é indicado.
Talvez você esteja familiarizado com programas para Windows, com barras de menus e de
ferramentas, botões, ícones, caixas de diálogos e outros tipos de objetos. Os programas que veremos aqui
não possuem a tela em modo gráfico, como no Windows, e sim em modo texto. Neste modo a tela é
dividida em linhas e colunas, assim:
T E X T O _
X X X X X
X X
X X
- - - X X
| | X X X X X
- - -
Esta tela é característica do sistema operacional MS-DOS (e suas variações), que era o padrão dos
PCs antes do Windows. O DOS executa somente um programa de cada vez, e todos os programas
compartilham a mesma tela, ao contrário do Windows, no qual cada programa tem sua janela. Veja mais
sobre DOS em outro capítulo à
frente.
Programas "máquinas de
escrever" Entre nome:
Fulano
Entre disciplina:
Chamamos os programas Linguagem
Entre nota:
de seqüenciais quando sua tela é 6
formada de maneira parecida com Fulano, Você passou em Linguagem
uma máquina de escrever. O texto
aparece de cima para baixo, uma
linha de cada vez. Veja ao lado um
exemplo de tela de programa
seqüencial. O programa pede o
nome, o usuário digita o nome e
tecla Enter. Depois o programa
pede para digitar a disciplina, a
nota e finalmente informa se o
aluno passou ou não, terminando em seguida. Após cada digitação o usuário do programa tecla Enter para
informar a conclusão.
3 - O PROCESSO DE PROGRAMAR 37
Há programas que apresentam algumas opções na tela, e o usuário deve escolher o quer fazer. O
programa de demonstração é um desses. O menu pode ser horizontal ou vertical, e mais ou menos
sofisticado: podem permitir que o usuário escolha o que quer fazer por uma letra ou número, podem
destacar a opção com uma cor diferente ou brilho. Cada seleção pode conduzir a uma ação ou a outro
menu secundário. Um estilo muito fácil de implementar é o de menus simples e verticais, como o da
figura abaixo.
MENU PRINCIPAL
0 - Termina
1 - Cadastro de programas
2 - Programas por tipo
3 - Programas por categoria
Outros tipos
Não importa quais operações os programas executem, nem qual o seu tipo; todos tem uma
estrutura, e podem ser vistos de uma forma segmentada. Na visão mais geral, os programas têm 3 partes
ou seções: inicialização, principal e finalização:
C om andos
S eção
I n i c ia liz a ç ã o p r i n c ip a l F in a liz a ç ã o
Inicialização: Quase todos os programas têm algo a fazer quando iniciam. Pode ser simplesmente
mostrar na tela o que faz ou o nome do programador, e inicialização de algumas variáveis. Alguns, como
o Word ou o Windows, mostram uma tela de apresentação. Os mais elaborados fazem abertura de
arquivos e recuperação de dados da sessão anterior, gravados no disco. Se o programa exige senha, ler e
verificá-la será uma das primeiras coisas a fazer. Há programas que fazem tudo isso.
Seção principal: Aqui é feito o que deve ser efetivamente feito, e pode ser simples ou bem
complexo. Nos programas mais simples, aqui é feita a leitura de algum dado e realizado o que foi previsto
na especificação. Em outros casos, os programas entram em um estado de espera: mostram uma tela com
um menu, por exemplo, e o usuário deve comandar algo ou informar o que quer fazer, seja através de uma
tecla normal ou de função ou cliques de mouse. O programa executa o que foi comandado e volta para
esperar outro comando.
Finalização: Há coisas que precisam ser feitas antes que certos programas possam sair da
memória sem problemas: fechamento de arquivos, mensagens de término, gravação de dados da sessão
para uso posterior. Há um instalador de um programa comercial que, antes de terminar, mostra uma
mensagem baseada na hora e no dia da semana: se de manhã, "Bom dia!", se após meio-dia, "Tenha uma
boa tarde", e se sexta-feira, "Bom fim de semana!".
Nos programas maiores, podemos segmentar o produto final em telas, e cada tela em operações,
como mostrar um texto, ler algo do teclado ou efetuar um cálculo.
As notas de uma faculdade são atribuídas por bimestre, tendo o primeiro bimestre peso 2 e o
segundo peso 3. A nota semestral deve ser arredondada para o múltiplo de 0,5 mais próximo. Elabore
um programa que calcule a nota final.
3 - O PROCESSO DE PROGRAMAR 39
C á lc u l o d e
n o t a f in a l
C a lc u la r n o t a
I n i c ia liz a ç ã o f in a l F in a liz a ç ã o
O bloco principal ainda está muito genérico. Calcular a nota com base em quê? E o cálculo da
média ponderada? E o arredondamento? Serão necessários, portanto, outras etapas: ler as notas
bimestrais, calcular a média ponderada, arredondá-la e finalmente mostrar o resultado na tela. O diagrama
fica assim:
C á lc u lo d e
n o t a f in a l
C a lc u la r n o t a
I n ic ia liz a ç ã o F in a liz a ç ã o
f in a l
L e r n o ta s C a l c u la r m é d ia A rred o n d ar M o s tra r n o ta
b im e s t r a is p o n d erad a m é d ia f in a l
A segmentação até esse nível permitiu identificar os algoritmos que devem ser solucionados:
dadas as notas, como calcular a média ponderada, e dada uma nota, como arredondá-la para o múltiplo de
0,5 mais próximo. Estas são soluções que independem do programa, e podem ser desenvolvidas antes de
se iniciar o programa-fonte.
...
5 x 10 = 50
Ao fazer um projeto você está definindo a aparência que o programa terá para o usuário. Você
estará vendo o programa como uma caixa preta, já funcionando. Para isso, você identifica que operações
o programa vai realizar, combina essas operações em uma ou mais telas de saída e, se necessário, faz
diagramas de blocos, tudo isso de uma forma que atenda à especificação. Ao detalhar as situações, defina
dados variados de entrada, que provoquem o programa no máximo de situações possíveis (casos de teste).
Convém identificar também os algoritmos envolvidos no programa, e achar solução para eles antes de
iniciar a implementação propriamente dita.
“Elaborar um programa que lê uma lista de valores inteiros positivos e, quando lido zero,
informa qual foi o maior e o menor número lido”
Sentado em frente ao
computador, você executa o
programa. A tela é limpa, e
aparece uma mensagem: “Entre Cálculo de maior e menor números de uma lista.
um número inteiro”. Você digita Entre um número inteiro positivo
o número 54 (que aparece na 54
tela), e tecla Enter. De novo a Entre um número inteiro positivo
12
mensagem, abaixo do número Entre um número inteiro positivo
54, e você entra com 12. Isso se 234
repete algumas vezes, até que Entre um número inteiro positivo
você entra com zero e, após 0
O maior número foi 234
teclar Enter, aparecem as O menor número foi 12
mensagens (os números são
exemplos): “O maior número foi
234” e “O menor número foi 12”,
e o programa é encerrado. Para
registrar as informações obtidas,
você poderia esboçar a tela, que
ficaria mais ou menos como na figura.
Para este programa não há uma condição de terminação explícita; ele terminará após mostrar o
menor número.
3 - O PROCESSO DE PROGRAMAR 41
O programa acima envolve o algoritmo para achar, dentre uma lista de números, o maior e o
menor. O algoritmo será diferente, conforme o programa armazene na memória toda a lista, para depois
buscar a solução, ou se armazena o maior e o menor lidos até o momento.
Um esquema da tela (seqüencial) do programa poderia ser como a seguir. Observe que o
detalhamento da tela previu as três situações possíveis para o delta (e quando o programa entrar em testes,
você já terá dados para testá-lo).
Agora considere uma especificação que diz que o programa deve simular um 'O' se movendo pela
tela, da esquerda para a direita e de cima para baixo. Como você detalharia esta tela? Uma possibilidade é
visualizar mentalmente a tela. Se não conseguir, pode fazer um diagrama da tela com setas indicando
(como for possível) as direções do movimento.
O que é mesmo que este programa faz? - Vamos ver um exemplo de como o projeto que você
define para o programa afeta o usuário. Suponha que você executa um programa e se depara com a
seguinte tela:
42 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Para que serve cada opção? Se foi você quem fez o programa, e isto ocorreu recentemente, você
pode até saber, caso contrário ficará com um imenso ponto de interrogação na testa. Compare a tela acima
com esta:
Opções:
0 - Fim
1 - Fatorial
2 - Pi
3 - Tangente
Sua opção: _
"Lembre-se dos quebra-cabeças: são muito mais fáceis quando você pode ver toda a figura primeiro".
G. Dryden e Jeanette Vos
Com base no texto da seção, identifique o que fazer churrascos tem em comum com elaborar programas.
O programa-fonte vai ser um resultado direto do projeto: uma vez que você tenha definido as
operações que serão executadas, vai poder identificar as instruções e comandos da linguagem que vai
precisar. Em alguns casos, é imediato, a uma operação corresponde uma instrução. Em outros, serão
necessárias duas ou mais instruções.
As instruções em um programa são bem parecidas com as que você viu na história do robô. Por
exemplo, um programa para cadastro de programas, como o de demonstração desta apostila, tem
comandos na seqüência abaixo, representados na forma de pseudo-comandos (têm uma estrutura e
formato uniforme, mas não são comandos de nenhuma linguagem). Compare com a tela a seguir.
repita
"Limpe a tela"
"Mostre na tela o título do menu"
"Mostre a opção 0 do menu"
"Mostre a opção 1 do menu"
"Mostre a opção 2 do menu"
"Mostre a opção 3 do menu"
"Mostre a mensagem 'Tecle sua opção:' "
"Leia do teclado a opção do usuário"
Se a opção for 1, então ... (comandos para executar a opção)
3 - O PROCESSO DE PROGRAMAR 45
MENU PRINCIPAL
0 - Termina
1 - Cadastro de programas
2 - Programas por tipo
3 - Programas por categoria
Em algumas situações nem a tela nem o diagrama de blocos fornecem pistas para os comandos a
usar. Neste caso, deve-se elaborar um algoritmo, tema de um capítulo próximo.
Várias coisas que fazemos tem a característica de, a partir de um objetivo, ir ajustando as ações
até atingi-lo. Ao guiar um carro, por exemplo, fazemos todo o tempo pequenos ajustes no volante. Ao
apertar um parafuso, podemos tentar com uma chave de fenda pequena; se não der, pegamos uma maior
ou aplicamos mais força ou colocamos uma substância viscosa no parafuso, ou todas essas alternativas.
Programar computadores tem muito dessa característica de fazer ajustes, já que dificilmente somos
perfeitos ao elaborar mentalmente os programas.
Por isto, uma das etapas mais importantes da programação é a verificação de que o programa
atende aos objetivos, à especificação. Considerando que fazer produtos de qualidade é essencial para
qualquer pessoa que pretenda ganhar a vida, fazer um nome no mercado, realizar-se e tantas outras coisas
que constituem ideais, qualquer programador deve ter em mente um propósito firme e inabalável de testar
bem seus programas e aperfeiçoar-se cada vez mais nesta habilidade.
O custo da correção de um erro em um programa é tanto maior quanto mais adiantado se está no
desenvolvimento. Para corrigir um erro no papel basta reescrever; corrigir um erro de um programa já
46 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
compilado exige muito mais alterações e cuidados; e corrigir erros de um programa já em utilização por
seus usuários pode ser desastroso.
O que é testar - Há várias definições de teste, cada uma adequada a uma finalidade. De forma
geral, todas se referem a medidas de qualidade de programas. Para nossos propósitos introdutórios, a
seguinte definição de teste é satisfatória (Myers, 1979):
Isto implica que, ao testar um programa, você não estará buscando provar que ele está correto ou
que você é um ótimo programador. Você estará com um espírito "destrutivo", o contrário do que fez ao
elaborar o programa. Mas você só poderá saber o que está errado se tiver uma referência do que é certo, e
esta referência é a especificação e seu detalhamento.
Uma das vantagens da atividade de programar, em relação a outras, é que está dentro do controle
do programador assegurar que o seu produto está correto. Testar adequadamente seus produtos é a grande
garantia que um estudante pode ter de suas notas, e que um programador profissional pode ter de seu
emprego. Além disso, saber que seu produto final será adequadamente testado permite maior liberdade ao
programador, durante o desenvolvimento, de criar, experimentar e arriscar com tranqüilidade. Veja a si
mesmo como um programador profissional e com programas sendo usados por muitos usuários, e
imagine como poderia variar a qualidade do seu sono, por exemplo, em função de ter ou não segurança a
respeito da correção de seus produtos. Garanta a sua qualidade de vida: teste, teste e teste só mais uma
vez para se certificar, e depois peça a um colega para testar também.
Você pode melhorar ou piorar a qualidade do teste simplesmente em função do que pressupõe ao
fazê-lo. Já presenciei situações (e também as vivenciei!) em que um programa não funciona
adequadamente, e o programador responsável fica estático, dizendo algo como “mas não é possível” ou
“mas o programa está certo!”. A conseqüência de pressupor que o programa está correto normalmente é
o programador ficar sem pontos de partida para descobrir erros. E você pode ter uma certeza: se houver
algum erro no programa, ele aparecerá quando estiver em uso. Por isso:
Um comentário final sobre teste de programas: até que seja executado em um computador, um
programa pode conter problemas que, sem experiência, você dificilmente detectaria. Por exemplo,
suponha que você fez um programa, correto, que simula um caractere se movendo pela tela, da direita
para a esquerda e vice-versa. Ao executá-lo, descobre que o caractere se move tão rápido que mal pode
vê-lo! Precisa então incluir instruções que retardem o movimento para uma velocidade compatível com a
capacidade dos olhos humanos. Por isso, e na opinião deste autor, o conhecimento mais consistente que
3 - O PROCESSO DE PROGRAMAR 47
você poderá obter não virá somente de livros; virá da prática, dos erros, dos problemas e desafios que
você vencer.
Ao testar seus programas, não se esqueça de aplicar e praticar as diretrizes sugeridas. Produtos de
qualidade atraem valorização profissional e melhores oportunidades, e você pode imaginar o que isso
representa.
O que você procura ao testar programas? O programador é o que melhor conhece os caminhos
internos do programa, e potencialmente é o melhor testador. Alguém que está vendo o programa por fora
vai testar as operações que o programa executa. Veja uma lista genérica:
Se o programa tem menus, teste o acesso a cada opção e teste cada opção.
Teste todas as entradas com dados variados, procurando descobrir algo que o programa não
prevê.
Verifique se as mensagens de orientação estão adequadas.
Se o programa faz cálculos ou gera informações, confira tudo, confrontando com o resultado
feito de outra maneira: à mão, calculadora ou outro meio.
Se o programa pede números, entre com letras para ver o que acontece.
Se o programa indica o que deve ser digitado, digite algo diferente.
Se o programa repete algo, faça-o repetir muitas vezes mais do que o normal.
Se o programa grava no disco, elimine seus arquivos (faça um backup antes). Termine o
programa e execute-o novamente, e veja se preservou os dados como deveria.
Faça perguntas provocativas: "O que pode estar errado?", "Como posso furar este
programa?"
Lembre-se de que a referência principal é a especificação; se ela não prevê validações de entrada
de dados, por exemplo, o programa não estará errado se falhar nisto. E se o programa passar nos testes,
não se esqueça de cumprimentar o programador!
( ) Programas podem ser escritos sem erros, mas é mais provável que os contenham.
( ) Verificar manualmente os programas acelera a aprendizagem de uma linguagem de
programação.
Um caixa automático precisa calcular quais e quantas notas devem ser entregues ao cliente para efetuar
a retirada desejada. Faça um programa com opções para:
- Receber notas de 10 e 50 (a quantidade inicial é zero para ambas)
- Ler o valor da retirada e mostrar a quantidade de notas de 10 e de 50 a serem entregues. Se
alguma das quantidades não for suficiente, o programa cancela a operação, com uma
mensagem apropriada
- Apresentar relatório com as quantidades de notas e valor total disponível, e valor total de
retiradas efetuadas.
50 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Você viu no capítulo anterior que todo profissional deve dispor de várias ferramentas para gerar
produtos de boa qualidade, com boa produtividade. Além das ferramentas intelectuais e emocionais, na
caixa do programador deve haver um bom compilador; além disso, quanto melhor você conhecê-lo,
melhor vai produzir.
Neste capítulo você vai conhecer um pouco do Turbo Pascal 7.0, cuja linguagem e recursos de
programação constituem a base deste trabalho.
Veremos aqui, de forma resumida, um subconjunto apenas das opções do ambiente Turbo Pascal
para DOS, o suficiente para você fazer seus primeiros programas. Nos próximos capítulos serão
apresentados outros comandos e funcionalidades. Como em todo treinamento, é impossível passar todos
os detalhes. O melhor que você pode fazer é "fuçar" de vez em quando nos menus e na ajuda, aos poucos
descobrindo as possibilidades.
O Turbo Pascal 7.0 é apresentado em dois disquetes. Para instalá-lo, é necessário ter no mínimo
um computador 286 com DOS 3.0 (!) e 6 MB livres no disco, já incluído o espaço de trabalho da
instalação. Você não deve ter problemas se instalar e executá-lo sob Windows.
Para iniciar a instalação, insira o primeiro disquete e execute o programa Install.exe, a partir do
Windows ou do DOS. Se você aceitar o diretório padrão (recomendável), o instalador criará o diretório
(pasta) C:/TP e alguns subdiretórios. Após, selecione a opção Start Installation. Troque o disquete
quando solicitado.
Há três compiladores: TPC.EXE (compilador de linha de comando, para ser usado a partir do
prompt do DOS), TPX.EXE e TURBO.EXE, tendo os dois últimos interface de menus. O TPX contém
alguns recursos adicionais que não são necessários neste curso, cujos programas foram todos testados no
TURBO.EXE. Para informar-se melhor sobre o TPX, execute o arquivo README.COM no disquete de
instalação.
52
Para entrar no ambiente integrado, se estiver no DOS ou em uma sessão do DOS no Windows,
digite C:\TP\BIN\TURBO na linha de comando e tecle Enter. Se estiver no Windows, clique em
Iniciar/Executar e faça o mesmo ou, se houver um ícone, clique duas vezes no ícone. Caso contrário,
entre no Gerenciador de Arquivos ou no Windows Explorer, clique na pasta de executáveis do Turbo
Pascal (C:\TP\BIN) e clique duas vezes no arquivo turbo.exe. Você estará na tela do editor de textos. É
aqui que você edita, compila, executa e corrige seus programas, e também onde obtém ajuda através do
help on-line. Se estiver no modo tela cheia (full screen), tecle Alt-Enter para execução em janela.
A tela contém no alto a barra do menu principal. Se houver alguma janela de texto aberta, a tela
deve estar azul, caso contrário estará hachurada com pontos azuis em fundo branco. Você entra comandos
clicando na barra do menu com o mouse ou através da tecla Alt mais uma letra. Cada programa-fonte
ocupa uma janela de texto; você pode abrir vários programas ao mesmo tempo, um em cada janela, o que
não é recomendado, principalmente quando há mais de uma janela para o mesmo programa. Nas linhas
inferiores da tela você tem ajuda para as teclas de alguns comandos mais usados e eventualmente
mensagens ou orientações.
No centro da linha superior de uma janela de programa fica o nome dele no DOS, isto é, como foi
gravado no disco, mas sem a extensão (".PAS"). Se aparece o nome "NONAME00", a janela é de um
novo arquivo, em branco, criado pelo Turbo Pascal, que você pode usar. Ao salvá-lo pela primeira vez,
você dará o nome adequado.
Familiarize-se com a edição de textos no editor do Turbo Pascal executando as práticas a seguir.
A IBM, na década de 50, era a empresa mais bem administrada do mundo, graças, em
grande parte, ao modelo do lendário diretor-presidente, Thomas J. Watson.
Contaram-me um caso que mostra como Watson reagiu ao saber de um erro
multimilionário de um de seus gerentes regionais. Ele chamou o gerente de vendas
à sua sala para trocar algumas palavras. Quando terminou, o infeliz gerente
sentia-se surrado, mutilado.
3. Recuperando texto excluído por engano – Posicione o cursor em uma linha qualquer e exclua-a
teclando Ctrl-Y. Experimente teclar agora Alt-Backspace, para recuperar a linha. Se não funcionar,
verifique em Options/Environment/Editor se a opção "Group Undo" está marcada.
4. Salvando um novo arquivo - Quando for salvar pela primeira vez um programa, você tem que dar
um nome a ele. Clique em File/Save as. Na janela que aparece, digite o nome do arquivo onde será
gravado, que tem um nome-base de até 8 letras e um tipo (extensão) de até 3, separados por um
ponto. Para o nome-base, use até oito letras, números e símbolos, sem espaços (regras do DOS); por
exemplo: WATSON (maiúsculas ou minúsculas, dá no mesmo). Não use asterisco (*), ponto (.),
aspas ("), colchetes ([ e ]), barra vertical (|), contrabarra (\) dois-pontos (:), igual (=), ponto-e-vírgula
(;), soma (+), menor e maior que (< e >), circunflexo (^) e interrogação (?). Já os tipos de arquivos
serão sempre .PAS, e o Turbo Pascal o colocará para você.
Clique em OK para gravar o arquivo.
5. Fechando - Para encerrar a edição de um programa, clique no botão situado acima e à esquerda da
janela ou tecle Alt-F3. Sempre feche as janelas de programas que não estiver usando, para evitar
possíveis confusões. Faça isto para o programa que digitou.
lista dos últimos arquivos abertos; se o que você quer aparece na lista, basta clicar no nome para abri-
lo.
Para abrir um arquivo, clique em File/Open ou F3. Na janela que aparece, no campo "Name", digite
o nome do programa que quer abrir, neste caso WATSON. Opcionalmente você pode clicar no nome
do arquivo desejado, na lista de arquivos. Neste, o símbolo "..\" quer dizer "o diretório acima". Uma
vez selecionado o arquivo, clique em Open para abrir. Outros arquivos abertos permanecem à
disposição; basta selecionar o desejado no menu Window, opção List. Ou clique na janela desejada
para ativá-la.
Para não ter que localizar o diretório correto todas as vezes em que for
abrir um arquivo, no início de uma sessão clique em File/Change Dir e
configure o diretório desejado.
2. Após abrir o arquivo, complete a digitação iniciada anteriormente, de forma que o texto fique assim:
A IBM, na década de 50, era a empresa mais bem administrada do mundo, graças,
em grande parte, ao modelo do lendário diretor-presidente, Thomas J. Watson.
Contaram-me um caso que mostra como Watson reagiu ao saber de um erro
multimilionário de um de seus gerentes regionais. Ele chamou o gerente de vendas
à sua sala para trocar algumas palavras. Quando terminou, o infeliz gerente
sentia-se surrado, mutilado.
O senhor está me dizendo que quer que eu vá embora? – o gerente perguntou.
- Ir embora? – Watson retrucou, atônito: - De maneira alguma! Imagine, gastei
mais de um milhão de dólares para treiná-lo!
(Charles Wang)
3. Salvando um arquivo existente - Após fazer as alterações, e como o arquivo já tem nome, clique em
File/Save para gravar no disco as alterações. Alternativamente, tecle F2. Se for um arquivo novo
("NONAMEnn"), o editor abrirá a janela do salvar como e você deverá dar um nome ao arquivo.
Se tiver problemas na impressão através do Turbo Pascal (como um monte de folhas saindo da
impressora), tente alterar a configuração, em File/Printer Setup, para /HP ou desmarcando o
opção de enviar os caracteres de formatação.
b) A partir do Bloco de Notas – Abra o programa-fonte e imprima-o, lembrando que o Bloco de
Notas usa a impressora padrão do Windows.
c) A partir do Word ou do WordPad – Abra o fonte e imprima-o normalmente. Para preservar a
formatação original, selecione todo o texto e altere a fonte para um não proporcional, como
Courier.
d) No DOS Shell – Entre no DOS Shell (veja à frente neste capítulo) no menu Arquivo e digite
Print <nome do arquivo>. Isto só funciona se o DOS foi instalado. Alternativamente, tente
comandar copy <nome do arquivo> prn.
Você pode acessar a ajuda on-line de várias formas. Com F1 você tem ajuda sobre a janela de
edição. No menu Help, há várias alternativas: Contents (estruturado), Index (alfabético) e até ajuda para
a ajuda. Um dos mais usados é a ajuda sensível ao contexto. Execute as práticas desta seção e veja como
funciona cada tipo.
executá-lo antes.
56
Localizar texto
Ctrl-L
Inserir uma linha em branco no modo de inserção
Inserir uma linha em branco no modo de sobreposição
Se você tem menos que vinte e poucos anos, talvez tenha apenas uma idéia vaga do que é o DOS.
Antes do Windows, ele foi o sistema operacional padrão para os PCs. Executa apenas um programa de
cada vez e não possui interface gráfica. Os comandos são digitados na linha de comando, na qual são
indicados (normalmente) o drive e o diretório atualmente selecionados, como por exemplo:
C:\WINDOWS>_
A contrabarra indica o diretório raiz, e este texto é chamado de prompt do MS-DOS, daí o nome
da opção de abrir uma sessão DOS a partir do Windows.
Os comandos são constituídos de uma palavra seguida de parâmetros. Por exemplo, para alterar o
diretório corrente, você deve digitar CD (de change dir) seguido do nome do diretório, e depois teclar
Enter:
C:\WINDOWS>CD \TP
Se o diretório desejado está abaixo ou é filho do corrente, basta digitar seu nome:
C:\TP> CD BIN
Cada comando do DOS tem sua própria sintaxe. Se o seu computador tem o DOS instalado, você
pode obter ajuda digitando HELP seguido do nome de comando.
A partir do Turbo Pascal, você pode acessar a tela do DOS a qualquer momento através da opção
File/Dos shell do menu. Ao clicar essa opção, você vê a tela DOS normal, com o prompt esperando um
comando. O Turbo Pascal continua na memória. Para confirmar isso, digite exit seguido da tecla Enter:
você volta para o Turbo Pascal, do mesmo jeito que estava quando você saiu.
Vá ao DOS shell, e tecle DIR, seguido de Enter. Você verá uma listagem dos arquivos gravados
no diretório atual. Entre outras coisas, e com algumas diferenças (mais ainda se estiver no Windows),
você deve ver:
WATSON PAS 200 07-31-97
WATSON BAK 37 07-31-97
O primeiro arquivo é um arquivo editado normalmente pelo Turbo Pascal: nome, tamanho em
bytes e data da última gravação. O segundo é a versão anterior do primeiro. Quando você salva um
programa, o Turbo Pascal renomeia a cópia que está no disco para .BAK, e grava a que está na memória
com a extensão .PAS. Se você perder algum programa, a primeira coisa a tentar é ir ao DOS shell,
renomear o .BAK para .PAS (após excluir o antigo) e recuperar o que puder.
Veja exemplos de outros comandos do DOS e suas opções, que você pode precisar:
dir *.pas (listar todos os arquivos com extensão .pas)
dir meu*.* (listar todos os arquivos começados com "meu")
dir meu*.pas (listar todos os arquivos começados com "meu" e
57
Lembre-se: para voltar ao Turbo Pascal, digite exit. Se digitar novamente turbo, você pode ter
problemas.
4. PRIMEIROS PROGRAMAS
uses CRT;
begin
ClrScr;
Writeln('Este programa simples desenha uma careta na tela.');
Writeln('Pressione qualquer tecla para ver a careta');
Readkey;
Writeln(' ____');
Writeln(' / \');
Writeln('/ O O \');
Writeln('\ ^ /');
Writeln(' \ ~ /');
Writeln(' ----');
Writeln;
Writeln('Pressione qualquer tecla para terminar o programa');
Readkey;
end.
b) Como o computador não entende Pascal, é preciso converter o texto para linguagem de máquina,
ou seja compilá-lo. Após salvar o arquivo, clique em Compile/Compile ou tecle Alt-F9. Deve
aparecer uma janela parecida com a abaixo. Se aparecer alguma mensagem no alto da tela,
verifique se digitou o programa exatamente como está.
60
c) Instruções são inertes se não forem executadas. Dê vida ao programa clicando em Run/Run ou
tecle Ctrl-F9 para executá-lo. Siga as instruções na tela.
Seção de Comentário
cabeçalho (ignorado na
PROGRAM CARETA; compilação)
{Feito por Virgílio V. Vilela}
Seção de
declarações uses CRT; Limpa a tela e posiciona o
cursor no canto superior
begin
esquerdo (vem de "Clear
Início da ClrScr; Screen)
seção de
comandos
executáveis Writeln('Este programa desenha uma careta na tela.');
Writeln('Pressione qualquer tecla para ver a careta');
Readkey;
Writeln(' ____'); ponto-e-vírgula: fim
Writeln(' / \'); de um comando
Writeln('/ O O \');
Writeln('\ ^ /');
Writeln(' \ ~ /');
Writeln(' ----');
Fim dos
Writeln; Espera uma tecla
Writeln('Pressione qualquer tecla para terminar o programa');
ser pressionada
comandos
executáveis para prosseguir
Readkey;
(ponto: fim end.
do programa)
- a partir do segundo caractere, pode conter letras, dígitos ou barra de sublinhado (_), ou seja, não
pode conter espaços
- não há distinção entre maiúsculas e minúsculas (MeuPrimeiro é o mesmo que mEUpRIMEIRO que
é o mesmo que mEupRImeIRo)
- não são permitidas letras acentuadas
Exemplos de nomes válidos de programas: CalculaFatorial, Calc_Dobro_versao_2, emite_som.
Nomes inválidos que impedem a compilação: Calcula Fatorial, 2_Calc_Dobro, EmiteSom!
Alt-Backspace). A cada erro, indique o código de erro de compilação e tecle F1 para ver mais
informações sobre a causa.
a) Troque PROGRAM por PROGRAMA
b) Insira um espaço no meio do nome do programa: CAR ETA
c) Tire o ponto-e-vírgula após CARETA
d) Tire o begin
e) Tire o primeiro apóstrofo de um Writeln
f) Tire o último apóstrofo de um Writeln
g) Tire o end
h) Tire o ponto final
i) Coloque um ponto no meio do programa
Se você estiver em uma rede, pode ser que necessariamente tenha que
informar em Options/Directories, campo EXE & TPU Files, uma pasta
onde tenha autorização para gravar. Você deve informar o nome DOS; o
Turbo Pascal não vai reconhecer o nome do Windows. Para saber qual é o
nome DOS, vá no Windows Explorer, clique com o botão direito na pasta
e selecione Propriedades.
c) Compile o programa. Note que na janela que informa o sucesso da compilação consta o destino.
d) Acesse o DOS Shell (no menu File), altere o diretório corrente para o que você especificou na
letra c) e peça a listagem do conteúdo ("DIR"). Verifique que foi criado um arquivo executável
com o mesmo nome do programa-fonte. Execute o programa digitando seu nome e Enter.
Se o cursor estiver na última linha da tela, e uma instrução Writeln for executada, seu parâmetro será
mostrado nessa linha e todo o conteúdo da tela será movido uma linha para cima e uma linha em
branco será inserida na parte inferior da tela, sendo portanto perdida a linha no alto.
Posição do cursor
após Write
Posição do cursor
após Writeln
uses CRT;
begin
ClrScr;
Writeln('texto em minúsculas');
Writeln('TEXTO EM MAIÚSCULAS');
Writeln('tExTo VaRiAdO');
ReadKey;
end;
5 - PRIMEIROS PROGRAMAS 65
Apóstrofos
A função dos apóstrofos é indicar ao compilador que o parâmetro é uma cadeia de caracteres e deve
ser mostrada exatamente como está escrita. Ou seja, ao contrário das palavras reservadas e
identificadores padrão, no caso de cadeias de caracteres o compilador distingue maiúsculas e
minúsculas; ele não vai criticar o que estiver delimitado pelos apóstrofos.
uses CRT;
begin
ClrScr; Writeln; Write('X X' ); Writeln('X X' ); Write('XXXXX' );
Write('X X' ); Writeln('X X' );
end.
PROGRAM DesenhaAlgo;
uses CRT;
begin
ClrScr; Writeln; Writeln ('#####'); Writeln('..#..');
Writeln('..#..'); Writeln('..#..'); Writeln('..#..');
end.
begin
Writeln('Isto está em uma linha');
Writeln;
Writeln('Há uma linha em branco acima desta');
end.
PROGRAM DemoNumeros;
uses CRT;
begin
ClrScr;
Writeln('1234'); 1234
Writeln( 1234 ); 1234
Writeln( 1234.0 ); 1.2340000000E+03
Writeln( 1234.0:30 ); 1.2340000000E+03
Writeln( 1234.0:30:2 ); 1234.00
Writeln( 1234.0: 0:2 ); 1234.00
ReadKey
end.
uses CRT;
begin
ClrScr;
Writeln('1234'); {cadeia de caracteres}
Writeln( 1234 ); {número inteiro}
Writeln( 1234.0 ); {o ponto torna o número real, que é mostrado em
notação científica}
Writeln( 1234.0:30); {indica que é para usar 30 colunas da tela. O
número é alinhado à direita dentro das 30 colunas}
Writeln( 1234.0:30:2 ); {usar 30 colunas como acima, e 2 casas decimais.
Evita a notação científica}
Writeln( 1234.0: 0:2 ); {o zero quer dizer que a quantidade de colunas não
está definida, e o número é mostrado a partir da
posição do cursor}
ReadKey
end.
EEEEE
E
EEE
E
EEEEE
ALUNO(A) NOTA
======== =====
ALINE 9.0
MÁRIO DEZ
SÉRGIO 4.5
SHIRLEY 7.0
******** ******** *
* * * *
* * * *
******** * * *
* * * *
* * * *
******** ******** ********
depois do cérebro. O Turbo Debugger acompanha o Turbo Pascal, e permite que um programa seja
executado uma linha de cada vez.
uses CRT;
begin
ClrScr;
Writeln( 'XXXXX' );
Writeln( 'X X' );
Writeln( 'X X' );
Writeln( 'X X' );
Writeln( 'XXXXX' );
end.
b) Agora digite, compile e execute o programa, comparando a tela obtida com a prevista.
c) Agora vamos executar o programa usando o debugger. Com a janela do programa-fonte ativa,
tecle F7. Isto inicia o debugger e a execução linha-a-linha. Uma barra horizontal surge na tela,
posicionada sobre o begin. Essa barra indica qual será a próxima linha de instruções que será
executada. Tecle F7 novamente. A barra estará sobre o ClrScr. A próxima operação a ser efetuada
é limpar a tela. Qual tela? Bem, a tela do seu programa não está aparecendo; você está no editor.
Para ver a tela de saída do seu programa, tecle Alt-F5. Tudo que o seu programa fizer vai
aparecer aí. O que você vê agora, antes da execução da primeira instrução, é a tela DOS,
contendo o que aconteceu antes de você entrar no Turbo Pascal ou o resultado do último
programa executado. Tecle qualquer coisa para voltar ao programa-fonte.
d) Tecle de novo F7, para executar o primeiro Writeln, e novamente Alt-F5. Veja o que houve na
tela DOS e tecle algo para retornar.
e) Novamente F7, para executar o próximo Writeln. Veja o que apareceu na tela.
f) Continue teclando F7, até chegar ao end.
Observe que a figura foi construída na tela uma linha de cada vez na seguinte seqüência:
XXXXX XXXXX XXXXX XXXXX XXXXX
X X X X X X X X
X X X X X X
X X X X
XXXXX
Usar o debugger não é útil somente para encontrar erros, mas também
para você ver as instruções funcionando e assim aprender mais
rapidamente.
PROGRAM DemoExpressoes;
uses CRT;
begin
ClrScr;
Writeln( 1234 + 1000 ); {expressão aritmética com adição}
Writeln('1234 + 1000'); {não é expressão, é uma cadeia }
Writeln('1234 + 1000 = ', 1234 + 1000);
Writeln( 1234 - 1000 ); {subtração}
Writeln( 1234 * 1000 ); {multiplicação}
Writeln( 1234 / 1000 ); {divisão - resultado é real}
Writeln( 54*13 - 37/11 + 23/5); {expressões aritméticas combinadas -
primeiro * e /, depois, + e - }
Writeln( -43/5 + 12*34 ); { o - inverte o sinal}
Writeln( (1290 + 155) * (980 - 32) ); {primeiro é calculado o que
está entre parênteses}
Writeln( -43/5:10:2); {formatando o resultado real}
ReadKey
end.
Pascal e matemática
No Pascal você pode efetuar operações matemáticas de forma semelhante à matemática, montando
expressões com números e operações. Mas para que você veja o resultado, deve mostrá-lo na tela
através de uma instrução Write ou Writeln, sendo a expressão aritmética avaliada, isto é, calculada, e
o resultado mostrado na tela. Você pode usar parênteses para determinar a precedência de execução
das operações.
Você indica que deseja que uma operação seja efetuada usando um operador. Por exemplo, o
símbolo + é o operador de soma, e indica que se deve somar os dois números ao seu lado (os
operandos). O conjunto operador e operandos forma uma expressão aritmética. No Pascal, o
operador de subtração também é o mesmo da matemática; já a multiplicação e a divisão são
representados respectivamente por * e /. quatro operações para dois números.
O tipo do resultado de uma expressão aritmética depende do tipo dos operandos e dos operadores: o
operador de divisão real / faz com que a expressão que o contém seja do tipo real. Já as expressões
com os operadores +, - e * serão reais se houver algum operando real, caso contrário serão inteiras.
Resultados de operações:
2100 + 541 = 2641
7.82 + 2.04 = 9.86
77/3 + 49/12 = 29.75
13 MOD 5
13532
dá o resto 13 DIV 5 dá
o divisor
PROGRAM CalcTempoEstudo;
uses CRT;
begin
ClrScr;
Writeln('Programa para cálculo de tempo de estudo');
Writeln('Dedique ', 100 div 6 , ' minutos para cada disciplina');
Writeln('Aproveite bem os ', 100 mod 6 , ' minutos restantes.')
end.
matemática, podemos usar parênteses ou a precedência dos operadores, que indicam a seqüência em que
devem ser efetuadas as operações:
PRIORIDADE OPERADOR
1 - unário
2 * / div mod
3 +-
A ordem de precedência acima indica que primeiro são aplicados todos os - unários, em seguida são
efetuadas todas as operações de multiplicação, divisão, resto e quociente de divisão inteiro, e só após
estas são efetuadas as adições e subtrações. Se a expressão contém parênteses, estes têm precedência
superior a todos os operadores, isto é, qualquer expressão entre parênteses é executada primeiro. Se não
há parênteses, e os operadores tem a mesma prioridade, as operações são efetuadas da esquerda para a
direita.
Digite o programa abaixo e confira os resultados:
begin
Writeln(51 div 16 + 48 - 8 mod 5); {Resultado: 3 + 48 - 3 = 48 }
Writeln( (51 div 16) + ((48 - 8) mod 5) ); {Resultado: 3 + 0 = 3}
Writeln( -3*(43/(52 div 3))); {Resultado: -3*(43/17) = -7.588}
Writeln( 6/3*2 ); {Resultado: 4 (real)}
end.
PROGRAM CalcContaTelefone;
uses CRT;
begin
ClrScr;
Write('Cálculo de conta telefônica');
Write('Assinatura: ', 17.90);
Write('Impulsos: ', 254, ' a R$0,04 por impulso');
Write('Interurbanos: ', 34.29);
Write('Celular: ', 23 , 'chamadas');
Write('Valor da conta: ', 17.90 + 254*0.04 + 34.29 + 23*0.2:10:2);
end.
Embora não haja erros de sintaxe, o programa não foi testado adequadamente. Há um erro no cálculo e a
formatação da tela está horrível. Faça os acertos e melhoramentos necessários.
4.5. Units
Talvez você já tenha se perguntado o que é aquele "uses CRT;" dos programas que vimos. O
Turbo Pascal guarda as definições de alguns comandos em um arquivo, chamado biblioteca padrão, que é
carregado para a memória junto com o restante do ambiente. Mas outras instruções não estão nesta
biblioteca, e sim em arquivos com extensão (tipo) .tpu chamados units. A extensão .tpu refere-se a Turbo
Pascal Unit.
O Turbo Pascal traz várias outras units: uma para imprimir, outra para acessar recursos do DOS,
outra ainda com instruções gráficas (círculos, preenchimentos e texto em modo gráfico). Além disso,
você pode criar suas próprias instruções e guardá-las em units, para usá-las de qualquer programa, como
será visto mais tarde.
Quando você quer usar uma instrução de uma unit, precisa informar ao compilador onde procurar
sua definição, através da palavra reservada uses. Sem a declaração uses, o compilador não reconhecerá as
instruções. Essa declaração deve vir logo após PROGRAM, e você pode indicar várias units, sem a
extensão:
PROGRAM ...
uses CRT;
begin
ClrScr;
Writeln('Este programa desenha uma careta na tela na linha 10, coluna 40.');
Writeln('Pressione qualquer tecla para ver a careta');
Readkey;
GotoXY(40, 10); Write(' ____');
GotoXY(40, 11); Write(' / \');
GotoXY(40, 12); Write('/ O O \');
GotoXY(40, 13); Write('\ ^ /');
GotoXY(40, 14); Write(' \ ~ /');
GotoXY(40, 15); Write(' ----');
Writeln;
Writeln('Pressione qualquer tecla para terminar o programa');
Readkey;
end.
usar CRT;
begin
ClearScreen;
Goto XY(20, 7); Write( XXXXX );
Goto XY(20, 8) Write( 'X X' );
Goto XY(20, 9); Write( 'X X' );
Goto XY(20, 10); Write( 'X X' );
Goto XY(20, 11); Writel( XXXXX );
End;
Menu Relatórios
1 - Por nome
2 - Por código
3 - Por data
4 - Fim
Opção: _
uses CRT;
begin
Sound(440);
Delay(30);
NoSound;
end.
begin
TextBackground(Yellow);
TextColor(Red);
Write('Texto em vermelho com fundo amarelo');
end.
PROGRAM {...}
uses Printer;
begin
Write(LST, 'Seu nome');
end.
Escolha um programa anterior que tenha implementado e que faça algum desenho na tela e altere-o para
que imprima o desenho.
4.6. Funções
Na matemática, quando se quer indicar o seno de 3,14 radianos, por exemplo, escreve-se
Seno(3,14), sendo 3,14 o parâmetro. Seno é uma função, e você calcula o resultado de uma expressão que
a contém primeiramente calculando o valor do seno, depois trocando a função pelo resultado e depois
continua o cálculo. Por exemplo, na expressão
x = 2 x Seno(3,14) = 2 x 0 = 0,
a função Seno(3,14) foi substituída pelo seu valor (0) antes que se pudesse prosseguir o cálculo.
No Turbo Pascal estão disponíveis funções variadas, incluindo as matemáticas. Todas são usadas
de forma semelhante: o nome da função, e seus parâmetros, no momento da execução, são substituídos
pelo respectivo resultado.
é calculado o seno;
é efetuada a multiplicação por 2;
é mostrado na tela o resultado.
Você tem que usar o nome da função reconhecido pelo compilador; tente,
por exemplo, incluir em um programa chamadas do tipo Raiz(20) ou
Seno(5) e veja o que acontece.
Como parâmetros de funções você pode usar expressões e até outras funções. No próximo
exemplo, o parâmetro da função Sin é uma expressão, que contém outra expressão combinando
multiplicação com uma chamada de função:
begin
Writeln( Sin(3.14*2 + SqRt(3) ) );
end.
Neste caso, antes do cálculo da função Sin deve ser avaliada a expressão dentro dos parênteses;
antes que esta possa ser avaliada, deve ser calculada a chamada à função SqRt.
A tela é bem simples, vamos mostrar apenas algumas mensagens informativas e o resultado. Para
apresentar a quantidade em centímetros, precisamos de 2 casas decimais, e no total 6 colunas bastam.
Para efetuar o cálculo precisamos elevar ao quadrado e extrair a raiz quadrada. O programa fica assim:
PROGRAM CalcComprimentoFio;
begin
Writeln('Cálculo de comprimento de fio');
Writeln('para paredes de 11,5 por 6,3 m');
Writeln( 'O comprimento mínimo é ', ( SqRt( Sqr(11.5) +
Sqr(6.3) ) ):6:2, ' metros. ' )
end.
Note a ordem de execução das operações matemáticas, quando o programa for executado:
primeiro Sqr(11.5), depois Sqr(6.3), em seguida a soma e só depois é calculada SqRt.
e 3 1.13 2
sen 3
cos 6
Para as duas primeiras você poderá achar o padrão, uma relação entre os números. A primeira
consiste nos quadrados de 1 a 7, e a segunda é a série de Fibonacci, em que cada termo é a soma dos dois
anteriores. Já para a terceira seqüência não se pode determinar que tipo de regra os produziu.
Instruções que produzam números variados sem qualquer padrão, regra ou relação entre si, os
chamados números aleatórios, são importantes para a implementação de jogos ou para gerar grande
quantidade de dados para testar programas. Por exemplo, isto será necessário se um programa sorteia um
número que deve ser adivinhado pelo usuário. E ninguém vai querer um programa de bingo que tem uma
regra para achar os números!
No Turbo Pascal, você pode gerar números inteiros aleatórios através da função Random. Antes
de poder usar Random, você chama Randomize para inicializar o gerador interno de números aleatórios.
Random recebe um parâmetro inteiro N, e o número gerado estará entre 0 e N - 1. Por exemplo, para
gerar e mostrar na tela um número aleatório entre 0 e 100, e depois outro entre 1 e 9, escreva:
82 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
PROGRAM TesteNumAleatorio;
begin
Randomize;
Writeln( Random(101) );
Writeln( 1 + Random(9) );
end.
PROGRAM ParabensComConstantes;
{Toca o início do Parabéns usando constantes declaradas para as notas musicais}
uses crt;
begin
Sound(DO1); Delay(200); NoSound;
Sound(DO1); Delay(200); NoSound;
Sound(RE); Delay(800); NoSound;
Sound(DO1); Delay(400); NoSound;
Sound(FA); Delay(400); NoSound;
Sound(MI); Delay(400); NoSound;
end.
Constantes
O Pascal nos permite definir nomes para valores, de forma a tornar os programas mais fáceis de
serem entendidos e para facilitar certas modificações. Isso é feito na seção CONST (de constantes).
Em um programa Pascal podem ser declaradas constantes numéricas, constantes para cadeias de
caracteres e várias outras. Quando o compilador encontra um nome declarado na seção de
constantes, ele simplesmente troca o nome pelo respectivo valor. Sempre que você estiver repetindo
algum valor em um programa, pense em declarar uma constante para ele. Para facilitar a
identificação de uma constante em um programa, pode-se adotar padrões, como começar cada
constante com um "c". Exemplos:
const
MeuNome = 'Fulano';
cVersaoPrograma = '2.1';
cPI = 3.1415;
cTurma = 'A';
Você já deve ter observado, pelos exercícios dos capítulos anteriores que, com comandos
simples, já se pode fazer várias coisas num computador, através de uma linguagem de alto nível
como o Pascal. Mas para elaborar programas mais úteis é necessário tirar proveito da memória do
computador.
Quando o usuário de um programa digita dados do teclado, onde são guardados esses
dados? E como? Pode-se guardar dados na memória a qualquer momento? E como recuperá-los?
Que problemas podem ocorrer? É preciso conhecer a fundo a memória do computador? Neste
capítulo você verá como podemos tornar os programas muito mais flexíveis, usando variáveis.
uses CRT;
begin
ClrScr;
Writeln('Entre coeficiente a: ');
Readln(a);
Writeln('Entre coeficiente b: ');
Readln(b);
Writeln('Entre coeficiente c: ');
Readln(c);
Delta := Sqr(b) - 4*a*c;
Raiz1 := (-b + SqRt(Delta) )/(2*a);
Raiz2 := (-b - SqRt(Delta) )/(2*a);
Writeln('Primeira raiz é ', Raiz1:0:2);
Writeln('Segunda raiz é ', Raiz2:0:2);
ReadKey;
end.
b) Execute o programa para cada equação do segundo grau descrita pelos conjuntos de coeficientes
(1, 0, -1), (1, -1, -6) e (1, 4, 4).
c) O programa não está preparado para tratar deltas negativos. Verifique o que acontece neste caso
executando-o para os coeficientes (1, 2, 5).
d) Prepare outras equações e experimente submetê-las ao programa. Uma forma simples é calcular
(x - R1)(x - R2), onde R1 e R2 são as raízes.
e) Execute o programa novamente, e quando for solicitado o coeficiente a, digite uma letra ou algo
não numérico, e veja o que acontece.
88
Variáveis
Variáveis armazenam valores, e são o mecanismo de uso da memória. Você só precisa informar o
nome de cada uma e o tipo de dado; o compilador cuida do gerenciamento da memória. Pode-se
fazer o seguinte com variáveis:
Declarar: na seção var informe o nome das variáveis que o programa vai precisar e o tipo de dado
que cada uma vai armazenar. O nome de uma variável deve seguir as mesmas regras que você viu
para nomes de programas: começar com uma letra, seguida de letras, dígitos ou barra de sublinhado.
Não podem, da mesma forma, ser usadas palavras reservadas como begin. No Pascal, toda variável
usada em um programa deve ser declarada. Omitir a declaração provoca um erro de compilação, com
a mensagem “unknown identifier” (identificador desconhecido).
Atribuir: com o sinal := você guarda um valor diretamente na variável. O nome da variável sempre
aparece à esquerda, e a direita pode ter qualquer expressão cujo resultado possa ser armazenado na
variável.
Recuperar o valor: onde for preciso usar o valor da variável, basta inserir o nome dela.
Ler um valor do teclado: com a instrução Readln pode-se ler algo digitado do teclado, sendo o valor
lido guardado na variável indicada entre parênteses.
Variáveis armazenam somente um valor de cada vez. A cada atribuição ou leitura, o valor anterior é
perdido.
Lendo atribuições
Quando você vai usar este recurso de executar uma linha de cada vez?
Tipicamente quando, ao testar um programa, você achar erros e precisa
de informação sobre o que o programa está fazendo. Use-o também para
aprender e fixar o funcionamento de uma instrução nova.
Quando declara uma variável, você tem que informar também o tipo de dado, que indica ao
compilador a natureza dos valores que a variável pode conter. Porque isto? Você já sabe que a memória
do computador não é como um pedaço de papel ou um quadro de giz, em que você pode escrever e
registrar vários tipos de símbolos: números, letras, rabiscos e qualquer desenho de que você seja capaz.
Ela é muito mais limitada: cada byte pode armazenar apenas um número de 0 a 255, e isto é tudo o que
temos para registrar informação. Se o que temos a registrar são números de 0 a 255, ótimo, usamos uma
variável de 1 byte. Mas e se for um número maior do que 255? E se for negativo? E se tiver casas
decimais? Como faço para representar uma letra? Como armazenar uma figura?
De maneira geral, os tipos de dado de uma linguagem de programação são variações dos tipos
inteiro, real, lógico (verdadeiro ou falso) e texto.
Veja na tabela a seguir os principais tipos de dado não estruturados, o respectivo domínio e a
quantidade de byte ocupadas na memória.
6 - MEMÓRIA E ENTRADA DE DADOS 91
Portanto, se você precisa armazenar um valor numérico com casas decimais, deve declarar uma
variável do tipo real. Se o dado a representar é um número inteiro, você deve escolher entre os cinco tipos
disponíveis: byte, integer, word, smallint e longint, cujas diferenças são basicamente a faixa de
números suportada.
Para armazenar um único caractere (letra, dígito, sinal, caractere de controle) no Pascal, use o
tipo char. Por exemplo, se você quer registrar se algum dado se refere a uma pessoa física ou jurídica,
referidas como 'F' ou 'J', pode declarar uma variável do tipo char. O mesmo tipo se aplica se quisermos
armazenar um caractere correspondente a uma tecla, como retornado pela função ReadKey.
Já para representar dados como o nome de uma pessoa, seu endereço ou uma frase qualquer, é
preciso declarar variáveis do tipo string, que permite declarar cadeias de até 255 caracteres. Você pode
indicar o comprimento desejado entre colchetes: string[30], string[100]. Se não indicado, será assumido o
máximo. O tamanho máximo de uma variável string é diferente do seu tamanho dinâmico: uma variável
pode ter um máximo de 50 caracteres e num determinado ponto da execução do programa estar
armazenando 19 caracteres.
Para distinguir cadeias de caracteres de outros nomes do programa, como nomes de variáveis,
representamos uma cadeia entre apóstrofos, como em 'Texto'. Se não o fizermos, o compilador tentará
interpretar o nome ou seqüência de caracteres como identificador (de variável, função ou outro elemento)
ou como número, conforme comece com letra ou dígito. Assim, em um programa, ' Idade' representa uma
cadeia de caracteres, enquanto Idade representa uma variável. O caractere apóstrofo, quando necessário, é
representado duplicado, como em 'caixa d''água'. A expressão '''' representa uma cadeia com um único
caractere apóstrofo.
Já variáveis do tipo boolean (lógico) podem assumir somente dois valores: True e False
(verdadeiro e falso). Normalmente são usadas para armazenar resultados da avaliação de expressões
lógicas, usadas para verificações: “o contador já atingiu 100?”, “o aluno tirou nota maior do que 5”?
O tipo de dado de uma variável determina e limita o conjunto de valores que ela pode assumir e
as operações que podem ser executadas com a variável. Mas sempre a especificação do programa é que
esclarecerá, em várias situações, qual será o tipo de dado mais adequado. Se a especificação pede que
você calcule valores inteiros para áreas, usar o tipo real pode ser inadequado.
92 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Uma variável real pode armazenar um valor inteiro, mas não o contrário.
uses CRT;
begin
Randomize;
ClrScr;
Lin := 1 + Random(21); {sorteia linha de 1 a 21}
Col := 1 + Random(76); {sorteia coluna de 1 a 76}
GotoXY(Col, Lin); Writeln( 'XXXXX' );
GotoXY(Col, Lin+1); Writeln( 'X X' );
GotoXY(Col, Lin+2); Writeln( 'X X' );
GotoXY(Col, Lin+3); Writeln( 'X X' );
GotoXY(Col, Lin+4); Writeln( 'XXXXX' );
ReadKey;
end.
+++++
+ +
+ +
+ +
+++++
Tecle Enter para terminar.
uses CRT;
begin
ClrScr;
Writeln('Este programa desenha um quadrado com um caractere.');
Write('Digite o caractere: '); Readln(Ch);
Write('Digite a linha: '); Readln(Lin);
Write('Digite a coluna: '); Readln(Col);
GotoXY(Col, Lin); Write(Ch, Ch, Ch, Ch, Ch);
GotoXY(Col, Lin + 1); Write(Ch, ' ', Ch);
GotoXY(Col, Lin + 2); Write(Ch, ' ', Ch);
GotoXY(Col, Lin + 3); Write(Ch, ' ', Ch);
GotoXY(Col, Lin + 4); Write(Ch, Ch, Ch, Ch, Ch);
Writeln; Write(Tecle Enter para terminar.');
Readln;
end.
begin
Numero := 3.1415;
Numero := 'X';
Nome := 1215;
Nome := '1215';
Ch := 'Texto';
Ch := 0;
N := 32000;
end.
f) Data de nascimento
g) Placa de um carro
h) Área de um círculo
c) Calcular o resto da divisão inteira da variável N por 13 e atribuir o resultado à variável Resto
d) Calcular o seno do conteúdo da variável N, extrair a parte inteira e mostrar o resultado na tela
e) Atribuir à variável Delta o resultado do cálculo b 2 - 4ac.
PROGRAM CalcNotaSemestral;
uses CRT;
begin
ClrScr;
Writeln('Cálculo da nota final a partir das notas bimestrais, pesos 2 e 3.');
Write('Entre nota do 1o. bimestre: ');
Readln(Nota1);
Write('Entre nota do 2o. bimestre: ');
Readln(Nota2);
Write('Nota final: ',(Nota1*2 + Nota2*3/5):0:1);
Readkey;
end.
uses CRT;
begin
ClrScr;
Write('Digite um valor para o caractere 1: '); Readln(Ch1);
Writeln('Veja o que pode ser feito com variáveis do tipo char.');
Writeln('Pressione uma tecla após conferir um resultado.'); Writeln;
Ch2 := 'x';
Writeln('A variável Ch2 não foi inicializada. O comando Ch2 := ''x'' atribui');
Writeln('o caractere x a Ch2. Confira, o valor dela agora é: ', Ch2);
ReadKey;
Writeln('Transforme o valor da variável em maiúscula.' );
Ch2 := UpCase(Ch2);
Writeln('Após o comando Ch2 := UpCase(Ch2), essa variável agora contém: ', Ch2);
ReadKey;;
Write('Concatenação (junção), usando o operador +: Ch1 + Ch2 = ');
Writeln(Ch1 + Ch2); ReadKey;
Write('A mesma operação, usando a função Concat(Ch1, Ch2): ');
Writeln(Concat(Ch1, Ch2)); ReadKey;
Writeln('Entre com um caractere na leitura a seguir, usando o teclado numérico.');
Writeln('Pressione Alt e tecle 178, solte Alt e tecle Enter.');
Readln(Ch1);
Writeln('Ch1 agora contém: ', Ch1); ReadKey;
Writeln('A instrução FillChar preenche uma string com caracteres.');
Writeln('Vamos preencher a string S com 70 vezes Ch1. O comando é FillChar(S, 70, Ch1)');
Writeln('Veja como ficou S (tecle algo):'); ReadKey;
FillChar(S, 70, Ch1); Writeln(S); ReadKey;
end.
PROGRAM MostraTecla;
{demonstra uso de ReadKey como função e procedimento}
uses CRT;
var Ch : char;
begin
Writeln('Pressione uma tecla');
Ch := ReadKey;
Writeln('Você pressionou a tecla ', Ch);
Writeln('Pressione outra tecla para terminar');
ReadKey;
end.
Vimos usando ReadKey como um procedimento, mas ela é na verdade uma função, que retorna o
caractere correspondente à tecla pressionada. Uma vantagem de usar ReadKey para ler um caractere é que
o usuário não precisa teclar Enter, como no Readln. Sendo uma função, podemos chamar ReadKey dentro
de um Write ou atribuir seu resultado a uma variável. Veja o exemplo:
O programa acima funcionará para teclas de caracteres normais, como alfabéticos e numéricos. Para
teclas de função ou normais alteradas por uma tecla de controle, como Shift, Alt e Control, ReadKey
retornará zero e será necessário chamá-la novamente parar obter um segundo código. Para tratar essa
situação, precisamos de instruções que veremos no próximo capítulo.
uses CRT;
begin
ClrScr;
Write('Digite um valor para a string 1 (até 255 caracteres): ');
Readln(S1);
Write('Digite um valor para a string 2 (até 30 caracteres): ');
Readln(S2);
Writeln('Digite um valor para a string 3 (até 3 caracteres; ');
Write('O que passar disso será desprezado na leitura: ');
Readln(S3);
Writeln('Veja o que pode ser feito com variáveis do tipo string.');
Writeln('Pressione uma tecla após conferir um resultado.');
Write('Concatenação (junção), usando o operador +: S1 + S2 = ');
Writeln(S1 + S2); ReadKey;
Writeln('A mesma operação, usando a função Concat: ');
Writeln(Concat(S1, S2)); ReadKey;
Writeln('Para calcular o tamanho atual de uma variável string, use a função Length.');
Writeln('Por exemplo, S1 tem atualmente ', Length(S1), ' caracteres.');
Writeln('Para obter um caractere de uma string, use colchetes após o nome da variável.');
Writeln('O primeiro caractere de S1 é S1[1]: ', S1[1]); ReadKey;
Writeln('O terceiro de S2 é S2[3], que é ', S2[3]); ReadKey;
Writeln('O último caractere de S2 é obtido com S2[ Length(S2) ]: ',
S2[ Length(S2) ]);
ReadKey;
Writeln('Você pode mudar somente um caractere de uma variável string,');
Writeln('basta indicar o número dele entre colchetes na atribuição.');
S3 [1] := '!';
Writeln('Apos o comando S3[1] := ''!'', S3 ficou assim: ', S3); ReadKey;
Writeln('Para extrair uma subcadeia, use a função Copy(VarString, PosInicial,
Qtde).');
100 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
begin
Nome := 'Fulano de Tal';
Ch := ''''
end.
será atribuído à variável Nome o conteúdo 'Fulano de Tal', e à variável Ch um apóstrofo. Digite o
programa acima e comprove, usando o debugger.
Até que tenha sido armazenado um valor pela primeira vez em uma
variável, seu conteúdo é indefinido, e pode ser qualquer coisa; você é que
deve cuidar disso.
Exercício 5.28
Represente cada descrição como uma única instrução Pascal:
a) Converter a variável Ch para maiúscula e armazenar o resultado na própria variável Ch.
6 - MEMÓRIA E ENTRADA DE DADOS 101
ax2 + bx + c,
que representa genericamente todas as equações dessa ordem. O que muda de uma para outra?
Exatamente os coeficientes a, b e c. Portanto, um programa que resolva equações do segundo grau precisa
ter variáveis para os três coeficientes (no mínimo).
Considere agora que um programa que inverte uma cadeia de caracteres lida pelo teclado. Isto é,
se o usuário entrar com 'cadeia a inverter', o programa mostrará na tela a cadeia 'retrevni a aiedac'. Quais
as variáveis? Pelo menos uma será necessária, para armazenar a cadeia digitada no teclado. Dependendo
da implementação, pode ou não ser necessária uma outra variável para armazenar a cadeia invertida,
conforme o programa mostre-a diretamente na tela ou armazene-a em uma variável para mostrar depois.
Se o programa simula um 'X' se movendo pela tela, da esquerda para a direita e de cima para
baixo, não são necessárias variáveis para armazenar dados fornecidos pelo teclado. Mas internamente o
programa seguidamente posiciona o X em linhas e colunas diferentes, portanto haverá pelo menos duas
variáveis.
Solução: O valor nominal deve ser lido, bem como a quantidade de horas extras. Todos os demais
valores serão calculados pelo programa.
valor de interurbanos
chamadas p/ celular: R$0,20 por impulso
Elabore um programa que lê os impulsos excedentes, valor de interurbanos e quantidade de
chamadas para celular e calcula o valor da conta.
Menu de Consultas
0 - Fim
1 - Clientes
2 - Produtos
3 - Faturas
4 - Estoque
Opção: _
Portanto, os saldos devem ser iguais, e quem tiver o saldo negativo deve pagar o valor para o outro. Faça
um programa que leia os valores adequados e efetue os cálculos. O total é a soma das despesas
individuais; um percentual é o gasto individual dividido pelo total, multiplicado por 100; o valor devido
por cada um é o mesmo e igual à metade do total; finalmente, cada saldo corresponde ao valor devido
menos o valor pago.
Uma tela para o programa pode ser, com os mesmos dados da tabela acima:
6 - MEMÓRIA E ENTRADA DE DADOS 105
2) Uma nota de prova de 0 a 10, com uma casa decimal e peso de 80% na nota final.
Elabore um programa que lê as notas de um aluno, calcula e mostra na tela sua nota final, formatada com
uma cada decimal e devidamente ponderada pelos pesos (uma média ponderada é calculada somando-se
os produtos de cada valor pelo seu peso e dividindo-se a soma resultante pela soma dos pesos). Exemplo:
Um aluno tirou 5 e 6 de exercícios e 8,5 na prova. Sua nota de exercícios é (5*1 + 6*2)/3 = 5,667. Sua
nota final é (5,667*2 + 8,5*8)/10 = 7,9.
Declaramos um tipo de dado através da palavra reservada type, normalmente antes da seção var,
embora possa vir também depois. Para o tipo subfaixa, informamos o nome do tipo, o limite inferior e o
limite superior (que deve ser maior ou igual ao limite inferior), separados por dois pontos. Para a idade e
para as letras maiúsculas, podemos declarar tipos da seguinte forma:
6 - MEMÓRIA E ENTRADA DE DADOS 107
type
tIdade = 1..120;
tMaiusc = 'A'..'Z';
Uma boa aplicação para a definição de tipos é para cadeias de caracteres. Em um programa típico,
costuma-se declarar várias variáveis de um mesmo tipo, como você verá no capítulo sobre criação de
instruções. Se você declarar um nome como string[30], por exemplo, se tiver que mudá-lo deve percorrer
todo o programa para substituir o tamanho onde quer que ele ocorra. Alternativamente, pode-se declarar
um tipo para o nome:
Type tNome : string[30];
Agora, basta mudar a declaração do tipo para alterar todas as declarações de variáveis desse tipo.
Muitas vezes precisamos efetuar conversões entre tipos de dados: de inteiro ou real para string ou
vice-versa, um caractere para o código ASCII correspondente e vice-versa. Por exemplo, para evitar erros
na entrada, podemos ler um número como texto e depois convertê-lo para número para efetuar operações
matemáticas.
Códigos ASCII
Para converter um código numérico no respectivo caractere da tabela ASCII, você pode usar a
função padrão Chr ou o símbolo #. Os primeiros dois comandos abaixo fornecem a mesma saída, ou
seja, o caractere 'J'. O terceiro emite um bip no alto-falante:
Writeln( Chr(74) );{Mostra 'J'}
Writeln( #74 ); {idem}
Writeln( #7 ); {emite bip}
A função inversa é Ord, que recebe um caractere e retorna o código ASCII correspondente. Assim, a
instrução abaixo mostrará na tela o número 74.
Writeln( Ord('J') );
Responda: o que será mostrado na tela pela instrução abaixo?
Write (Chr(Ord('H')));
108 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Precisamos de três variáveis inteiras para os números. Como os códigos ASCII vão de 0 a 255, o tipo byte
é apropriado. Para converter cada código para o respectivo caractere, usamos a função Chr, e para
concatená-las usamos o operador +. O programa fica assim:
PROGRAM Concat3CodAscii;
uses CRT;
begin
ClrScr;
Write('Entre três números de 0 a 255: ');
Readln(N1, N2, N3);
Writeln(Chr(N1) + Chr(N2) + Chr(N3));
end.
Precisamos de variáveis para o nome (string), para a letra inicial e para a última (Char). O programa:
6 - MEMÓRIA E ENTRADA DE DADOS 109
PROGRAM InicialEUltimaLetra;
uses CRT;
begin
ClrScr;
Write('Entre um nome: ');
Readln(Nome);
Inicial := Nome[1];
Writeln('Inicial: ',Inicial, ', cujo código ASCII é ',
Ord(Inicial));
Ultima := Nome[Length(Nome)];
Writeln('Ultima: ', Ultima, ', cujo código ASCII é ', Ord(Ultima));
ReadKey;
end.
6. ALTERNATIVAS E DECISÃO
Imagine um programa que calcula raiz quadrada de um número qualquer, lido do teclado. Se o
usuário digitar um número negativo, ocorre um erro e o programa termina. Para que isso não ocorra, é
preciso que o programa verifique se o número é negativo e somente calcule a raiz se isso não ocorrer. Ou
inversamente, somente calcular a raiz se o número lido for maior ou igual a zero.
Assim como pessoas, programas que fazem verificações e tomam boas decisões são mais
produtivos. Veja neste capítulo como os programas podem fazer essas verificações e, com base no
resultado destas, executar ou não um bloco de instruções.
Prática 6.1 – IF 1
a) Digite o programa abaixo, cuja especificação é a seguinte:
Elaborar um programa que lê um número qualquer e calcula sua raiz quadrada. O cálculo
somente é efetuado se o número for maior ou igual a zero. Se não for, é mostrada uma mensagem
de erro.
PROGRAM CalculaRaiz;
uses CRT;
begin
ClrScr;
Writeln('Cálculo de raiz quadrada');
Write('Digite o número: ');
Readln(Num);
if Num >= 0 then
Write('A raiz de ', Num:0:2, ' é ', SqRt(Num):0:2 )
else
Write('Número inválido');
Write('Pressione qualquer tecla');
ReadKey;
end.
IF
O comando Pascal que permite execução condicional de instruções é o IF..THEN..ELSE, cuja
sintaxe é:
if <expressão lógica> then
<comando 1>
else
<comando 2>
Uma expressão lógica constitui uma comparação cujo valor pode ser somente Verdadeiro ou Falso
(True ou False, para o Turbo Pascal). Para a comparação usamos os operadores:
= (igual)
< (menor que)
> (maior que)
<= (menor ou igual)
>= (maior ou igual)
<> (diferente)
O comando if funciona assim: se a <expressão lógica> for verdadeira, é executado o comando após o
then, caso contrário (expressão é falsa), é executado o comando após o else. Veja um exemplo
simples:
if N >= 0 then
Write('N é positivo')
else
Write('N é negativo');
O comando acima será executado assim:
- O valor de N é recuperado da memória (suponhamos que foi 121);
- A expressão lógica 121 >= 0 é avaliada, sendo o resultado True (verdadeira);
- Como a expressão lógica após o if é verdadeira, será executado o comando que estiver após o then,
no caso é o primeiro Write;
- O fluxo de execução segue para o comando que estiver após a última instrução do else (o comando
após ou dentro deste é ignorado).
- Quando a expressão lógica após o if é avaliada como falsa (por exemplo, quando o valor de N for
-77), será executado o que estiver após o else, e o que estiver após o then é ignorado.
O comando if determina que ou serão executadas as instruções após o then ou as após o else, mas
nunca ambas as possibilidades, em uma mesma passagem do fluxo de execução.
Prática 6.2 – IF 2
a) Digite o programa abaixo, cuja especificação é a seguinte:
"O critério de notas de uma faculdade consiste de uma nota de 0 a 10 em cada bimestre, sendo a
primeira nota peso 2 e a segunda peso 3. Elabore um programa que lê as notas bimestrais e
7 - ALTERNATIVAS E DECISÃO 115
calcula a nota do semestre. Se alguma nota lida estiver fora da faixa válida, é mostrada uma
mensagem de erro"
PROGRAM CalcNotaSemestral;
uses CRT;
begin
ClrScr;
Writeln('Cálculo da nota final a partir das notas bimestrais, pesos 2 e 3.');
Write('Entre nota do 1o. bimestre: ');
Readln(Nota1);
if (Nota1 >=0) and (Nota1 <=10) then
begin
Write('Entre nota do 2o. bimestre: ');
Readln(Nota2);
if (Nota2 >=0) and (Nota2 <=10) then
Write('Nota final: ',((Nota1*2 + Nota2*3)/5):0:1)
else
Write('Nota inválida');
end
else
Write('Nota inválida');
Readkey;
end.
a) Execute o programa para as notas (7, 8), (11, ?), (8, 12).
b) Repita o passo anterior, desta vez usando o debugger.
begin e end
Se houver mais de um comando após then ou else, será necessário delimitar todos eles com
begin..end, que indicam um comando composto:
if N >= 0 then
begin
Write('N é positivo');
ReadKey;
end
else begin
Write('N é negativo');
ReadKey;
end;
uses CRT;
begin
ClrScr;
Write('Digite a nota:');
Readln(Nota);
if Nota > 100 then
Writeln('Nota inválida')
else
begin
if Nota >= 90 then
Conceito := 'A'
else if Nota >= 75 then
Conceito := 'B'
else if Nota >= 50 then
Conceito := 'C'
else if Nota >= 40 then
Conceito := 'D'
else
Conceito := 'E';
Writeln('O conceito é ', Conceito);
end;
Readkey
end.
Exercício 6.7 - In
Altere o comando abaixo para que aceite também as letras minúsculas correspondentes:
if TipoPessoa in [ 'F', 'J' ] then ...
begin
Terminou := False;
Nota := 10;
Passou := Nota > 5;
Passou := Nota – 9 > 5;
Passou := Terminou;
End.
a) N <= 10
b) N >< 0
c) N = 3.1415
d) N => -1
e) 0 =< N <= 9
PRECEDÊNCIA OPERADORES
1
2
3
4
5
6
120 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
uses CRT;
var a, b, c : integer;
Delta, Raiz1, Raiz2 : real;
begin
ClrScr;
Writeln('Cálculo de raízes da equação do segundo grau');
Writeln('Entre coeficientes inteiros a, b e c,');
Writeln('teclando Enter a cada um');
Readln(a); Readln(c); Readln(b);
Delta := b*b - 4*a*c;
Raiz1 := ( b + SqRt(Delta) )/2;
Raiz2 := ( b - SqRt(Delta) )/2;
Writeln('Primeira raiz é ', Raiz1:0:2);
Writeln('Segunda raiz é ', Raiz2:0:2);
end.
PROGRAM TipoCaractere;
{Lê um caractere e informa se é letra, dígito, operador aritmético ou nenhum deles}
uses CRT;
var Ch : char;
begin
ClrScr;
GotoXY(10, 8);
Writeln('Entre um caractere qualquer: ');
Readln(Ch);
case Ch of
'A'..'Z', 'a'..'z' : begin
GotoXY(10,10);
Writeln('Letra');
end;
'0'..'9' : begin
GotoXY(10,10);
Writeln('Dígito');
end;
'+', '-', '*', '/' : begin
GotoXY(10,10);
Writeln('Operador');
end;
else begin
GotoXY(10,10);
Writeln('Caractere especial');
end;
end;
Writeln('Pressione qualquer tecla');
ReadKey
end.
Case
Considere um trecho de programa que deve oferecer um menu de opções na tela. Se o usuário digitar
1, o programa faz algo; se 2, outra coisa, e assim por diante. Com base na opção do usuário, o
programa deve decidir o que fazer. Mas agora não são meramente dois caminhos; podem ser 3, 7 ou
dez alternativas.
Para esses casos, ao invés de usar o comando if, é melhor usar o comando case, que tem o seguinte
formato:
case <expressão> of
<caso 1> : <comando 1>;
<caso 2> : <comando 2>;
<caso 3> : begin
<comando 4>;
<comando 5>
end;
...
else
<comando 6>
end;
Em cada caso, você pode por uma constante (1, 'A'), várias constantes separadas por vírgulas ('A',
'B') ou subfaixas: 'a'..'z', 0..10; não pode por expressões ou variáveis. Os valores em cada caso devem
ser compatíveis com o tipo da expressão, que não pode ser real nem string. Se houver mais de um
comando em um caso, ele deve ter o seu próprio par begin..end.
122 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Quando um comando case é executado, o valor da expressão é avaliado. Se seu valor for igual ao
caso 1, é executado o comando 1; se igual ao caso 2, é executado o comando 2, etc. Se não houver
igualdade, é executado o comando após o else. Este é opcional.
Se mais de um comando precisa ser executado em algum caso, você deve usar o comando composto
begin..end, um para cada caso e também um par para o else.
Múltiplas instruções if podem ficar melhor codificadas através de um comando case, quando o tipo
da expressão lógica permitir.
O próximo passo é identificar as variáveis. Para a entrada precisamos de duas variáveis inteiras para
armazenar os números e uma do tipo char para armazenar a operação. Para a saída não precisaremos de
variáveis, já que podemos calcular e mostrar o resultado diretamente na tela. Observando a tela de saída,
verificamos que o programa está estruturado da seguinte forma:
"Ler números"
"Ler operação"
"Decidir qual operação será efetuada e mostrar o resultado na tela ou uma mensagem de erro"
Veja o programa a seguir. Como exercício, execute-o manualmente para as entradas usadas no
detalhamento da tela e verifique se a tela de saída produzida está correta.
7 - ALTERNATIVAS E DECISÃO 123
PROGRAM Calc4Operacoes;
{Lê dois números reais e uma operação, e efetua a operação indicada}
uses CRT;
begin
ClrScr;
Writeln('Entre dois números inteiros:');
Readln(N1, N2);
Writeln('Entre operação (+, -, * ou /):');
Readln(Op);
case Op of
'+' : Writeln(N1, ' + ', N2, ' = ', N1 + N2);
'-' : Writeln(N1, ' - ', N2, ' = ', N1 - N2);
'*' : Writeln(N1, ' x ', N2, ' = ', N1 * N2);
'/' : if N2 <> 0 then
Writeln(N1, ' / ', N2, ' = ', N1 / N2)
else
Writeln('Erro: divisor inválido')
else
Writeln('Erro: operação inválida');
end;
ReadKey;
end.
uses CRT;
begin
ClrScr;
Writeln('1 – Ação 1');
Writeln('2 – Ação 2');
Writeln('3 – Fim');
Write('Entre opção: ');
Readln(Opcao);
case Opcao of
'1' : {Ação 1};
'2' : {Ação 2};
else begin
Writeln("Opção inválida");
ReadKey
end
end;
end.
Comandos de decisão são necessários quando há alternativas para o fluxo de execução. É como
uma estrada: se não há encruzilhadas ou trevos, você vai seguindo sem precisar decidir nada sobre o rumo
a tomar, mas se há opções, uma decisão deve ser tomada.
- A especificação normalmente contém indicações: "se o número for inválido...", "um menu...".
- Cada entrada de dados cria alternativas. Criticá-las ou não pode depender da especificação.
- Posso usar o comando CASE? Se sim, qual é o mais simples de usar, IF ou CASE? Qual deles
organiza melhor o código? Qual fica mais elegante?
7 - ALTERNATIVAS E DECISÃO 125
Quando várias decisões têm que ser tomadas, pode ocorrer que não consigamos organizar
mentalmente todas elas; nesses casos, uma ótima ferramenta é uma árvore de decisão, descrita no
exemplo abaixo.
Ou seja, com duas bolas brancas o jogador perde tudo, com uma branca e uma preta recebe 2/3 do que
apostou, com um preta e uma branca recebe seu dinheiro de volta e com duas pretas recebe o dobro.
Elaborar um programa que lê as cores das duas bolas e calcula o rateio.
O passo principal do programa é, a partir das cores das duas bolas (variáveis Cor1, Cor2), deduzir o valor
do rateio (variável Rateio). Definimos que as cores serão representadas por 'P' ou 'B', conforme cada bola
seja preta ou branca, respectivamente. Podemos escrever um if para cada linha da tabela acima, como:
if (Cor1 = 'B') and (Cor2 = 'B') then
Rateio := 0
else if (Cor1 = 'B') and (Cor2 = 'P')
Rateio := 2/3
{...}
Codificar expressões complexas dessa maneira pode ser trabalhoso e sujeito a erros. A forma de tratar
gradualmente a solução é montar uma árvore de decisão, na qual organizamos as várias possibilidades.
Escrevemos a primeira decisão, com as opções Sim e Não. Depois, para a opção Sim, escrevemos a
próxima decisão e suas opções Sim e Não. Assim vamos detalhando cada possibilidade, até que cada
ramo tenha uma ação associada:
128 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
nada
Sim
Cor2 é branca?
Sim
Não 2/3
Cor1 é branca?
Sim 1
Não
Cor2 é branca?
Não 2
Para converter para Pascal, basta traduzir a árvore em comandos if..then..else: cada pergunta
resultará em um comando if; a cada 'sim' corresponde um then e cada 'não' estará associado a uma
cláusula else. Teremos o seguinte trecho de programa:
if Cor1 = 'B' then
if Cor2 = 'B' then
Rateio := 0 {branca, branca}
else
Rateio := 2/3 {branca, preta}
else
if Cor2 = 'B' then
Rateio := 1 {preta, branca}
else
Rateio := 2; {preta, preta}
Elaborar um trecho de programa para criticar se o valor da variável Op está correta. Os valores
permitidos são '+',' '-',' *' e '/'.
130 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Solução:
if Pos(Op, '+-/*') = 0 then
Write('Operação inválida')
else
{...}
Elabore um programa para testar o trecho do exemplo acima. O programa efetua as operações
matemáticas indicadas.
PROGRAM VerificaData;
{lê uma data no formato 'dd/mm/aaaa' e verifica se o dia está entre 1 e 31 e o
mês está entre 1 e 12}
uses CRT;
begin
Write('Entre data no formato dd/mm/aaaa: '); Readln(Data);
Val(Copy(Data,1,2), Dia, Erro); {Converte dia para numérico}
if Erro = 0 then
begin
Val(Copy(Data,4,2), Mes, Erro); {Converte mês para numérico}
if Erro = 0 then
begin
if (Dia >= 1) and (Dia <= 31) then
{verifica validade do dia e do mês}
if (Mes >= 1) and (Mes <= 12) then
Writeln('Data válida')
else Writeln('Mês inválido')
else Writeln('Dia inválido')
end
else Writeln('Erro no mês')
end
else Writeln('Erro no dia');
end.
var S : string;
I, P, N : byte;
C : integer;
begin
S := 'Questao 1';
Insert(' ',S, Length(S)+1);
S := S + '999';
for I := 2 to 5 do S[I] := Upcase(S[I]);
Delete(S, Length(S)- 1, 2);
P := Pos('1', S);
if P > 0 then
begin
Val(Copy(S, P+2, 1), N, C);
if (C = 0) and (N <> 0) then
Delete(S, N, 1);
end;
end.
7. REPETIÇÃO
Todo programa realmente útil precisa repetir uma ou mais instruções. Veja neste capítulo as três
opções do Turbo Pascal para repetição controlada de um bloco de comandos.
Veremos o while primeiro. Ele serve para todas as situações, os outros são maneiras melhores
para situações particulares.
7.1. While
PROGRAM CalculaRaiz;
{repetidamente calcula raiz quadrada, terminando quando lido zero}
uses CRT;
begin
ClrScr;
Writeln('Cálculo de raiz quadrada');
Num := 1;
while Num <> 0 do
begin
Write('Digite o número: ');
Readln(Num);
if Num >= 0 then
Writeln('A raiz de ', Num:0:2, ' é ', SqRt(Num):0:2 )
else
Writeln('Número inválido');
end;
end.
uses CRT;
begin
ClrScr;
Writeln('Entre um nome completo:');
Readln(Nome);
Ap := 1;
{procura posição do primeiro espaço}
while (Nome[Ap] <> ' ') and (Ap < Length(Nome)) do
Ap := Ap + 1;
{obtém subcadeia do primeiro caractere até
a posição encontrada e mostra-a na tela}
Writeln('O prenome: ', Copy(Nome, 1, Ap - 1));
end.
O primeiro nome é formado pelas primeiras letras do nome, até o primeiro espaço. Uma variável
armazenar o nome lido. Para localizar a posição do primeiro espaço do nome, é usando um apontador
(inteiro). Iniciando em 1, variamos o apontador até a posição do primeiro espaço, através de um comando
while. Sabendo onde o espaço está, usamos a função Copy para obter os caracteres do nome até o espaço
(sem incluí-lo).
Observe que o apontador Ap foi limitado também pelo tamanho máximo do nome, para o caso em que
não houver sobrenome.
While
O while (enquanto) é o comando de controle de repetição que serve para qualquer situação. Sintaxe:
while <expressão lógica> do
begin
<comandos>;
end;
O comando funciona assim: quando no fluxo de execução é encontrado um while, a <expressão
lógica> é avaliada; se for verdadeira, os <comandos> após o do são executados e o fluxo retorna
para reavaliar a expressão lógica; se for falsa, é executado o que estiver após o end. Ou seja,
enquanto a expressão lógica for verdadeira, os comandos internos vão ser repetidos.
Na expressão lógica que vem depois do while pode-se usar os mesmos operadores descritos para o
comando if: =, <, <=, >, >= e <>, além dos conectivos lógicos and, or e not e do operador in.
a) N := 0;
while N < 10 do
begin
N := N + 1
Write(N, ' ');
end;
a) N := 1;
while N < 10 do
begin
Write(N, ' ');
N := N + 1
end;
a) N := 1;
while N <= 10 do
Write(N, ' ');
PROGRAM EqSegundoGrau;
uses CRT;
var a, b, c : integer;
Delta, Raiz1, Raiz2 : real;
begin
ClrScr;
Writeln('Cálculo de raízes da equação do segundo grau');
Writeln('Entre coeficientes inteiros a, b e c,');
Readln(a, b, c);
Delta := b*b - 4*a*c;
Raiz1 := ( -b + SqRt(Delta) )/2*a;
Raiz2 := ( -b - SqRt(Delta) )/2*a;
Writeln('Primeira raiz é ', Raiz1:0:2);
Writeln('Segunda raiz é ', Raiz2:0:2);
end.
7.2. Repeat
uses CRT;
begin
ClrScr;
Writeln('Cálculo de raiz quadrada');
repeat
Write('Digite o n£mero: ');
Readln(Num);
if Num > 0 then
Writeln('A raiz de ', Num:0:2, ' é ', SqRt(Num):0:2 )
else
Writeln('Número inválido');
until N = 0;
end.
Repeat
A diferença do comando repeat para o while é que no primeiro as instruções internas serão
executadas pelo menos uma vez. O comando repeat tem a forma
repeat
<comando 1>;
<comando 2>;
...
until <expressão lógica>;
Quando é encontrado um comando repeat, são executados os comandos até o until. A expressão
lógica deste é então avaliada; se for falsa, o fluxo de execução retorna para a instrução após o
repeat; se for verdadeira, o comando de repetição é encerrado e é executada a instrução após o
until, se houver alguma.
Aspectos a destacar no comando repeat:
- as instruções internas ao comando são executadas pelo menos uma vez;
- a decisão de repetir ou parar é tomada após a execução das instruções dentro do comando;
- o comando é encerrado quando a expressão for verdadeira;
- não é preciso inserir o comando composto begin..end quando houver mais de uma instrução a
repetir.
begin
repeat
Write('Digite o primeiro número: '); Readln(Numero1);
Write('Digite o segundo número: '); Readln(Numero2);
if numero1 <> 0 then
begin
Writeln (Numero1+Numero2);
Writeln (Numero1-Numero2);
Writeln (Numero1* Numero2);
Writeln (Numero1/Numero2)
end
until Numero1=0
end.
138 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
7.3. For
Quando sabemos a quantidade de repetições, seja uma constante, o valor de uma variável ou um
valor calculado, é mais simples usar o comando FOR. A sintaxe deste comando inclui uma variável de
controle, que é incrementada ou decrementada automaticamente, conforme usemos FOR..TO ou
FOR..DOWNTO.
uses CRT;
begin
ClrScr;
Write('Entre números inicial e final: ');
Readln(NumIni, NumFim);
if NumIni < NumFim then
for N := NumIni to NumFim do
Write(N, ' ')
else
Writeln('O número final deve ser maior que o inicial');
end.
os números são lidos e armazenados nas variáveis NumIni e NumFim; suponha que foram
digitados os valores 100 e 200;
em seguida, o valor de N é comparado com o conteúdo da variável NumFim, que é 200. Como
é menor, o fluxo de execução segue para o comando após o do;
8 - REPETIÇÃO 139
novamente é avaliado se N <= NumFim. Como N contém 101 e NumFim contém 200,
novamente é executado o Write;
isto se repete (incrementa, mostra) até N = 201; como agora N é maior do que o valor final, o
comando após o do não é executado e o fluxo de execução segue para a instrução após o fim
do comando for, que é o fim do programa.
FOR
Neste comando de repetição escolhemos uma variável de controle e informamos o seu valor inicial e
seu valor final. O compilador se incumbe de atualizar o valor da variável de controle (de 1 em 1 ou
de -1 em -1) a cada iteração, e compara seu valor com o valor final indicado. Tipicamente este
comando será usado quando soubermos a quantidade de iterações (constante ou uma variável) ou ela
puder ser calculada. A sintaxe:
for <variável> := <valor inicial> to {ou downto} <valor final> do
begin
<comando 1>;
<comando 2>;
...
end;
A variável do for (variável de controle) deve ter sido declarada e normalmente é de um tipo inteiro
(há outras possibilidades, que não nos interessam aqui). No caso de ser usado to, quando um
comando for é encontrado no fluxo de execução:
- à variável de controle é atribuído o resultado da expressão correspondente ao valor inicial
e seu valor é comparado com o resultado da avaliação da expressão que indica o valor final;
- se o valor inicial é menor ou igual ao valor final, as instruções após o do são executadas, e
automaticamente a variável de controle é incrementada de uma unidade, e novamente o valor da
variável é comparado com o valor final.
- se o valor inicial é maior que o valor final, nenhuma instrução após o do é executada, e o fluxo
segue para a próxima instrução.
- se houver só um comando após o do, não é necessário o par begin..end. Exemplos:
for GrauCelsius := 0 to 100 do
Write (GrauCelsius, ' ');
for X := -10 to 10 do
begin
Writeln(X);
Writeln
end;
Quando usado downto, as diferenças são: o valor final deve ser menor que o inicial, a variável de
controle é decrementada de uma unidade, e o teste verifica se o valor da variável é menor que o
valor final.
140 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
10 9 8 7 6 5 4 3 2 1
PROGRAM ContaDe10Ate1;
{Mostra os números inteiros de 10 até 1}
uses CRT;
var N : byte;
begin
ClrScr;
for N := 10 downto 1 do
Write(N, ' ')
end.
Uso do FOR
PROGRAM PreencheTela;
{Preenche 24 linhas da tela com um caractere lido, enquanto emite sons com
freqüência crescente de 1 em 1, a partir de 100 e uma duração de 20
milissegundos. Não execute se houver alguém dormindo, é insuportável...}
uses CRT;
var Ch : char;
Freq : word;
L, C : byte;
begin
ClrScr;
Writeln('Entre um caractere:');
Readln(Ch);
ClrScr;
Freq := 100;
for L := 1 to 24 do
for C := 1 to 80 do
begin
GotoXY(C,L); Write(Ch);
Sound(Freq); Delay(Tempo); NoSound;
Freq := Freq + 1;
end;
ReadKey;
end.
Explicações: para este programa precisamos de dois comandos de repetição, uma para apontar cada linha
e outra para cada coluna. Para cada linha percorremos todas as colunas. Como sabemos quantas iterações
ocorrerão (24x80), usamos dois comandos for. A cada vez que mostramos um caractere na tela, também
incrementamos a freqüência. Note que o comando for de dentro é executado completamente para cada
iteração do primeiro for.
PROGRAM SeguindoFor;
begin
Anterior := 1; Atual := 1;
for I := 3 to 5 do
begin
Seguinte := Atual + Anterior;
Anterior := Atual;
Atual := Seguinte
end
end.
PROGRAM CaracteresProgressivos;
uses CRT;
var N, I, J : integer;
Ch : Char;
begin
ClrScr;
Writeln('Entre número de linhas: '); Readln(N);
Writeln('Entre caractere: '); Readln(Ch);
I := 1;
while I <= N do
begin
for J := 1 to I*2 do
Write(Ch);
Writeln; {move cursor para início da próxima linha}
I := I + 1
end
end.
a) Smai := '' ;
for Ap := 1 to Length(S) do
Smai := Smai + Upcase(S[Ap]);
a) S := Smai;
for Ap := Length(S) downto 1 do
S[Ap] := Upcase(S[Ap]);
Pausas - Se você quiser fazer o programa esperar o usuário pressionar uma tecla antes de
continuar, pode usar a função KeyPressed (da unit CRT), que retorna True se uma tecla foi acionada e
False caso contrário. Com esta função, podemos escrever
repeat until KeyPressed;
ou
8 - REPETIÇÃO 143
A função KeyPressed apenas consulta o buffer do teclado; o código da tecla digitada continua lá.
Se tiver que ler posteriormente do teclado e não precisar da tecla, limpe o buffer com a instrução
ReadKey.
"Loops" - Você pode observar que, no comando acima, se nenhuma tecla for pressionada, o
comando nunca terminará, exceto se o computador for desligado ou houver uma condição de erro. Isso
sempre ocorrerá quando a condição de terminação nunca for atingida (dizemos que o programa “entrou
em loop”). Observe o seguinte trecho de programa:
X := 1;
repeat
Writeln(X);
X := X + 2
until X = 100;
Outro erro de conseqüências por vezes desagradáveis é esquecer o par begin..end. Suponha que o
programador, ao corrigir o erro acima, faça assim:
X := 1;
while X <= 100 do
Write (X, ' ');
X := X + 1;
O desavisado programador, iludido pelas aparências, acha que corrigiu o problema, mas nada
mudará: o incremento do X está fora do comando de repetição e jamais será executado.
Impedindo entradas erradas - Uma outra aplicação de comandos de repetição é quando você
quer ler um valor e só continuar o programa após o valor lido estar correto. Por exemplo, para ler um
número na faixa de 1 a 6, você pode escrever:
Repeat
Write('Digite o número: ');
Readln(Num)
until (Num >= 1) and (Num <= 6);
Nesse caso é bom prever uma mensagem de erro para o usuário, para ele não ficar sem saber o
que fazer. Como você faria isso?
Blocos de controle - Comandos de repetição são muito usados para repetir a seção principal de
um programa, permitindo o usuário usar o programa e só parar quando for informada uma condição de
saída.
No caso mais simples, já visto aqui, o programa executa apenas uma ação básica. Esse é o caso
144 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
É claro que uma estrutura while..do também pode ser usada (faça como exercício). Já se o
programa implementa duas ou mais ações distintas, o usuário deve informar qual quer executar, e a
estrutura típica de controle é um comando case:
PROGRAM ExemploMenuIncompleto;
uses CRT;
Begin
ClrScr;
repeat
Writeln('1 – Ação 1');
Writeln('2 – Ação 2');
Writeln('3 – Fim');
Write('Entre opção: ');
Readln(Opcao);
case Opcao of
'1' : {Ação 1};
'2' : {Ação 2};
'3' : {fim}
else begin
Writeln("Opção inválida");
ReadKey
end
end;
until Opcao = '3'
end.
Veja nesta seção algumas perguntas que você pode fazer se precisar, divididas em dois blocos. O
primeiro para repetições simples, como a de menus, e o segundo para algoritmos. Nem sempre será
preciso fazer todas, use-as quando achar necessário. Independentemente da qualidade das perguntas, fazer
a verificação manual antes da digitação pode lhe economizar muito tempo.
Elaborar programa que lê uma disciplina e respectiva nota (de 0 a 10, com uma casa decimal), e
informa se o aluno passou na disciplina, repetindo o ciclo até que a nota lida seja zero. O aluno
passa quando tira 7 ou mais.
Há repetição?
Sim. O programa deve processar tantas notas quanto o usuário queira.
Quais os comandos que serão repetidos?
Ler a nota e a disciplina
Verificar se o aluno passou.
Mostrar o resultado na tela.
Quantas vezes ocorrerá a repetição ou, se não se sabe, qual é a condição de terminação?
Quantidade indefinida de vezes (o usuário é que determina). Termina quando a nota lida
for zero.
Depois de obtidas essas respostas, basta decidir qual o comando de repetição a ser usado. Note
que você poderia ter feito um projeto e a partir deste obter as respostas.
uses CRT;
begin
ClrScr;
Writeln('Cálculo de média de idades');
Idade := 999;
while Idade <> 0 do
begin
Write('Digite a idade: '); Readln(Idade);
if Idade <> 0 then
begin
Quant := Quant + 1;
SomaIdade := SomaIdade + Idade;
end;
end;
Writeln('A média das idades é : ', SomaIdade/Quant:0:2);
ReadKey;
end.
1 2 3 N 1 N
S ...
N N 1 N 2 2 1
Após efetuar um cálculo, o programa pede novo número, parando quando N for zero.
Antes de trabalhar na repetição, vamos fazer um projeto. Uma tela de saída pode ser (após fazer
cálculos manuais da série):
8 - REPETIÇÃO 147
O único passo da segmentação acima que não pode ser diretamente implementado em Pascal é
"Calcule o valor da série". Este pode ser segmentado informalmente em:
Repita N vezes
"Calcule o valor de um termo da série"
"Acumule o valor do termo calculado"
fim
Quais são as variáveis que se alteram a cada passagem, seus valores inicial e final e instruções
que as modificam? A cada iteração, mudam o numerador (de 1 em 1), o denominador (de –1 em –1) e o
próprio valor de S (Numer/Denom). Representando através de uma tabela:
Variável Val. Inicial Val. Final Instrução
Numer 1 N Numer := Numer + 1
Denom N 1 Denom := Denom –1
S 0 S S := S + Numer/Denom
Quantas vezes ocorrerá a repetição? Teremos N iterações, uma para cada fator da série.
ALGORITMO CalculaSérie;
Denom N;
S 0;
For Numer := 1 to N do
begin
S S + Numer/Denom;
Denom := Denom – 1;
end
Antes de completar o programa, vamos efetuar a verificação manual para N = 3. Montamos uma
tabela de variáveis e executamos o algoritmo instrução a instrução, atualizando a tabela a cada alteração
no valor de uma variável. Ao final, a tabela ficará assim:
Iteração N S Numer Denom
início 3 ? ? ?
Inicialização 0 1 3
1 0.333 2 2
2 1.333 3 1
3 4.333 4 0
A execução produziu o resultado previsto no projeto (faça o mesmo para N = 5). Veja o programa
completo:
PROGRAM CalculaS;
{calcula o valor de uma série matemática}
uses CRT;
begin
ClrScr;
N := 999;
while N <> 0 do
begin
Writeln('Entre valor de N:');
Readln(N);
if N > 0 then
begin
S := 0;
Denom := N;
for Numer := 1 to N do
begin
S := S + Numer/Denom;
Denom := Denom - 1;
end;
end;
Writeln('S(', N, ') = ', S:10:2)
end
end.
Note que você tem várias alternativas para chegar a um algoritmo: a especificação, o projeto,
segmentação, experiência anterior, tentativa-e-erro. Por onde você passa não importa, se chegar a um
resultado correto.
Nunca se esqueça: suas idéias são seu principal recurso. Não as mate
impiedosamente!
8 - REPETIÇÃO 149
PROGRAM Fotossintese;
{Apresentacao de texto sobre fotossintese, com titulo e tres paginas.
Atencao: nao roda em Turbo Pascal for Windows}
uses CRT;
const {codigos ASCII (estendidos, exceto o 27) das teclas usadas no programa}
ESCAPE = #27;
SetaAcima = #72;
SetaAbaixo = #80;
var
PagAtual : byte;
Tecla : char;
150 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
begin
ClrScr;
GotoXY(34,12); Write('F O T O S S I N T E S E');
Readln;
PagAtual := 1;
repeat
ClrScr;
{mostra a pagina atual; algumas linhas foram separadas apenas para o
fonte caber nas 80 colunas da tela e do papel}
Case PagAtual of
1 : begin
GotoXY(12,12); Write('A agua e os sais minerais absorvidos'
+ ' pelas raizes');
GotoXY(12,13); Write('sobem atraves dos vasos lenhosos do'
+ ' caule e chegam as folhas');
end;
2 : begin
GotoXY(12,12); Write('Nas folhas, existe uma substancia verde,'
+ ' a clorofila,');
GotoXY(12,13); Write('que absorve a energia luminosa do Sol.'
+ ' Ao mesmo tempo,');
GotoXY(12,14); Write('por meio dos estomatos presentes nas'
+ ' folhas, a planta');
GotoXY(12,15); Write('absorve gas carbonico do ar.');
end;
3 : begin
GotoXY(12,12); Write('Usando a energia solar, o gas carbonico'
+ ' e o hidrogenio');
GotoXY(12,13); Write('contido na agua retirada do solo,'
+ ' apos complicadas reacoes');
GotoXY(12,14); Write('quimicas, a planta produz acucares'
+ '(glicose)');
end;
end;
Tecla := ReadKey;
{Algumas teclas (de controle) retornam dois caracteres, sendo o
primeiro #0; testamos so o segundo. As setas tem dois}
if Tecla = chr(0) then
Tecla := ReadKey;
Case Tecla of
SetaAcima :
if PagAtual > 1 then PagAtual := PagAtual - 1;
SetaAbaixo :
if PagAtual < 3 then PagAtual := PagAtual + 1;
end;
until Tecla = ESCAPE;
end.
- quantidade de palavras
- quantidade de ocorrências da letra 'A'
a) Elabore uma tela-exemplo para o programa, mostrando como a tela ficará quando o usuário informar
um dia inválido, depois um dia válido e em seguida uma resposta 'S'.
b) Elabore uma árvore de decisão tendo como entrada um número de 1 a 7 e como resultado o
respectivo nome do dia da semana.
c) Escreva um programa Turbo Pascal para a especificação descrita.
8 - REPETIÇÃO 155
Apresentar relatório com as quantidades de notas e valor total disponível, e valor total de retiradas
efetuadas.
157
À medida em que nossos programas vão se tornando maiores e mais complexos, a quantidade de
detalhes pode se tornar intratável, e o risco de haver erros é maior. Além disso, muitas vezes executamos
um mesmo conjunto de instruções em dois ou mais pontos do programa. Seria ótimo se pudéssemos
programar em nível mais alto do que as instruções das linguagens de programação, e também podermos
reexecutar uma ação sem precisar reescrever as instruções que a implementam.
Neste capítulo veremos como podemos estruturar melhor nossos programas, criando novas
instruções na forma de procedimentos e funções reutilizáveis.
Suponha que você conhece três receitas de cozinha, sendo que todas usam um mesmo molho à
bolonhesa, e você quer escrever estas receitas. Como você faria: descreveria as instruções do molho em
meio às instruções de cada receita (ou seja, 3 vezes)? Ou descreveria a receita do molho em separado, e
ao descrever as outras receitas forneceria uma instrução do tipo “faça o molho à bolonhesa da pág. 2”?
A segunda alternativa certamente é mais econômica: você escreveria menos. Outra vantagem é
que, quando você tiver uma idéia brilhante para melhorar o molho, para registrá-la você fará alterações
em apenas um lugar, ao invés de 3. Além disso, uma pessoa que já conheça a receita do molho nem
precisa ir à página 2, e a descrição da receita fica mais simples.
Esses princípios se aplicam à programação. Suponha que você deve escrever um programa que
desenha 3 quadrados na tela, em locais variados do programa, e você dispõe de instruções que desenham
um quadrado. Seria suficiente escrever 3 vezes a seqüência de instruções que desenha um quadrado.
Porém essa redundância cria alguns inconvenientes:
O teste é triplicado;
Se alguma alteração for feita, ela terá que ser feita em 3 lugares;
Se for necessário desenhar o quadrado em outro programa, as respectivas instruções deverão
ser redigitadas e retestadas.
Para entender melhor a criação de instruções, é bom revisar como elas podem ser. Por exemplo,
observe a instrução abaixo:
Writeln('Numero = ', 1);
A instrução Writeln possui, além de um nome único para identificá-la, uma finalidade bem
definida e específica, que é apresentar dados na tela.
Uma outra característica é que Writeln precisa receber dados para cumprir sua finalidade, os
chamados dados de entrada. Devemos indicar o que queremos que apareça na tela. Acima, os parâmetros
'Numero = ' e 1 são os dados de entrada. Mas não há informação alguma que se precise conhecer
(internamente ao programa) após a execução da instrução, ou dados de saída. Cuidado para não
confundir: a saída de Writeln é na tela, mas essa instrução não retorna qualquer informação que vá ser
usada dentro do próprio programa.
Associadas à instrução Writeln há outras características não visíveis para nós. Sendo uma
instrução de alto nível, também possui instruções em linguagem de máquina que a implementam. Essas
instruções constituem um bloco de código, que realizam sua finalidade. Além disso, Writeln deve possuir
variáveis internas, necessárias para algum cálculo intermediário, como por exemplo, linha e coluna da
tela.
Já a função Sin(X) tem a finalidade de calcular o seno de um número real. Tem como dado de
entrada o número, e como saída (resultado) o seno do número. Seu bloco de código e suas variáveis
internas também ficam escondidas. Observe como o resultado aparece no programa: no lugar da chamada
da função..
A instrução Writeln é um comando direto, imperativo, que representa uma ação a ser executada: é
chamado procedimento. A instrução Sin é uma função: retorna um valor como resultado de sua
execução, podendo portanto ser usada em expressões. Writeln e Sin são, respectivamente, procedimento-
padrão e função-padrão do Pascal, porque são predefinidas na linguagem.
As instruções que podemos criar podem ter a forma de procedimento ou de função. Suas
estruturas são bem semelhantes, exceto que para uma função devemos dizer o tipo de valor que ela
retornará e em pelo menos um ponto do seu bloco de código devemos atribuir um valor a ser retornado.
Uma grande vantagem de criar uma nova instrução é esconder seu bloco de código e suas
variáveis internas do resto do programa. Uma vez testada, podemos usá-la como uma instrução qualquer
da linguagem, conhecendo apenas seu nome e seus dados de entrada e saída, ou seja, sua interface.
Assim, evitamos a repetição de instruções e, encapsulando os detalhes de implementação de cada uma,
permitimos que possam ser implementadas e testadas uma de cada vez.
uses CRT;
Note que no programa ocorre várias vezes a seqüência GotoXY/Write. Nestes casos, ao invés de
ficar repetindo instruções várias vezes, podemos declarar uma nova instrução que faça o que queremos.
Basta então chamar a instrução quando necessário.
Para o caso GotoXY/Write, podemos declarar um procedimento, já que apenas uma ação é
executada e nenhum valor é produzido. Veja a estrutura de um procedimento no quadro. PROCEDURE
é uma palavra reservada que indica que você está declarando um procedimento.
160 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
9 - CRIAÇÃO DE INSTRUÇÕES E MODULARIZAÇÃO 161
162 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Você pode notar que, assim como o programa tem um bloco de código, cada procedimento
também tem o seu. O primeiro é chamado principal para distinguí-lo dos outros. A declaração do
procedimento deve vir antes do bloco de código principal.
Uma vez declarado o procedimento, para que seja executado deve-se chamá-lo, isto é, escrever
seu nome no ponto adequado do programa, informando entre parênteses os valores a serem passados aos
parâmetros. Estes podem ser constantes, variáveis ou ainda expressões. Neste caso a expressão é avaliada
antes da chamada; sempre chegam valores constantes ao procedimento.
uses {...}
begin
GotoXY (Col, Lin);
Write(Texto);
end;
var {...}
Uma vez declarada a nova instrução, podemos substituir todas as chamadas a GotoXY/Write por
uma chamada ao procedimento WriteXY, sendo que a cada chamada passamos valores diferentes
conforme a necessidade. Assim, ao invés de escrevermos
begin
...
GotoXY(C, L); Write(Texto);
...
end.
escrevemos
begin
...
WriteXY(C, L, Texto);
...
end.
Também variáveis e expressões podem ser usadas como parâmetros efetivos. Se o argumento for
uma variável, seu valor é buscado na memória para ser passado; se for uma expressão, esta primeiro é
avaliada e o valor resultante é que é passado ao procedimento. Sempre chegará ao parâmetro um valor;
por isso esse tipo de parâmetro é chamado parâmetro por valor.
Variáveis locais podem ter o mesmo nome que variáveis globais; neste caso estas não estarão
visíveis, isto é, não podem ser referenciadas no bloco de código do procedimento, enquanto este estiver
ativo.
Veja no exemplo a seguir uma segunda versão do programa do quadrado, modificada para usar a
nova instrução:
164 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
PROGRAM QuadradoEmXY_v2;
{Desenha um quadrado usando procedimento}
uses CRT;
begin
GotoXY (Col, Lin);
Write(Texto);
end;
valores. Note que o debugger só vai reconhecer os parâmetros do procedimento enquanto este estiver
ativo. Preste atenção em particular ao fato de que os parâmetros assumem os valores passados a cada
chamada. Se nesta houver uma variável ou expressão, o valor é buscado ou calculado antes da ativação do
procedimento.
uses CRT;
begin
GotoXY (Col, Lin);
Write(Texto);
end;
begin
WriteXY(C, L, 'XXXXX');
for I := 1 to 3 do
WriteXY(C, L+I, 'X X');
WriteXY(C, L+4,'XXXXX');
end;
var L, C : byte;
Continua : char;
begin
repeat
ClrScr;
Write('Digite a coluna: '); Readln(C);
Write('Digite a linha: '); Readln(L);
QuadradoXY(C, L);
WriteXY(1, L+6, 'Deseja ver outro quadrado?');
Continua := Upcase(Readkey)
until Continua = 'N';
end.
Sobre procedimentos:
- Você pode declarar quantos procedimentos quiser;
- Procedimentos podem ter variáveis internas (locais), que, como os parâmetros, só existem
enquanto o procedimento está ativo. Também podem ter suas próprias constantes e types.
- Um procedimento pode chamar outro procedimento;
- Procedimentos podem ter nomes de parâmetros iguais aos de outros procedimentos ou a
variáveis globais;
- Veja como o programa principal acima ficou mais simples e como você poderá usar o
procedimento do quadrado em outro programa rapidamente, sem necessidade de testá-lo
novamente.
uses CRT;
begin
ClrScr;
repeat
Write ('Entre duração: ');
Readln(Dur);
Freq := 100;
repeat
Sound(Freq);
Delay(Dur);
NoSound;
{incrementa em 10% a freqüência}
Freq := Trunc(Freq * 1.1)
until Freq > 8000;
until Dur = 0;
end.
b) Faça um procedimento que emite um som em uma freqüência e duração informadas como
parâmetros. O seu bloco de código deverá portanto conter as instruções Sound/Delay/NoSound.
Faça uma nova versão do programa SomVariavel, trocando a chamada a essas instruções pela
chamada ao novo procedimento.
c) Agora crie um procedimento que recebe freqüências inicial e final e duração, e emita os sons da
mesma forma que o programa SomVariavel. Na chamada, passe os mesmos valores atuais: 100,
8000 e a variável da duração. O novo procedimento chama o anterior para emitir cada som.
d) Finalmente, faça o programa ler do teclado também os valores das freqüências e passar as
respectivas variáveis como parâmetros. Acrescente um IF para que o procedimento principal não
seja chamado se a duração lida for zero.
Os parâmetros que vimos acima representam dados de entrada para os procedimentos. Qualquer
que seja o parâmetro efetivo passado na chamada (variável, constante ou expressão), o procedimento
receberá um valor na chamada.
É possível, entretanto, declararmos parâmetros que sirvam tanto para entrada quanto para saída de
dados (resultados). Para isso, inserimos na declaração, antes do identificador do parâmetro, a palavra var.
Se o parâmetro é precedido por var, dizemos que ele é um parâmetro por referência. O argumento, ou
parâmetro efetivo, de um parâmetro por referência não pode ser um valor; obrigatoriamente deverá ser
uma variável. No início da execução do procedimento, o valor desta variável é passado para o parâmetro;
ao final, o valor do parâmetro é atribuído à variável. Desta forma, temos um mecanismo em que o
procedimento poderá retornar dados e resultados que produza internamente.
Chamadas possíveis:
NomeProc(3);
NomeProc(N);
NomeProc(N+5);
No programa a seguir, o procedimento possui três parâmetros por valor e dois por referência.
Vejamos como é a execução.
begin
Delta := b*b - 4*a*c;
Raiz1 := (-b + SqRt(Delta) )/2*a;
Raiz2 := (-b - SqRt(Delta) )/2*a;
end;
begin
Write('Entre coeficiente inteiro a: '); Readln(C1);
Write('Entre coeficiente inteiro b: '); Readln(C2);
Write('Entre coeficiente inteiro c: '); Readln(C3);
EqSegGrau(C1, C2, C3, R1, R2);
Writeln('Primeira raiz é ', R1:0:2);
Writeln('Segunda raiz é ', R2:0:2);
end.
a=1
b=3
c=2
Raiz1 = ?
Raiz2 = ?
Note que, como as variáveis R1 e R2 não foram inicializadas, não podemos ter certeza de seu
valor, o mesmo ocorrendo com os parâmetros correspondentes Raiz1 e Raiz2, que receberam
os valores de R1 e R2.
É executado o bloco de código do procedimento, após o que temos:
Raiz1 = -1
Raiz2 = -2
O valor do parâmetro Raiz1 é atribuído à variável R1, e o valor de Raiz2 é atribuído a R2. Isto
é automático através de instruções colocadas pelo compilador.
As variáveis dos parâmetros são eliminadas, liberando a memória que usavam
O fluxo de execução retorna para a instrução que segue a chamada ao procedimento,
aparecendo na tela os valores de R1 e R2, respectivamente -1 e -2.
Você deve ter percebido que, quando o procedimento é ativado, é estabelecida uma ligação da
variável que representa o parâmetro efetivo (o da chamada) com o respectivo parâmetro formal (o
declarado). Na prática, é um mesmo endereço de memória referenciado através de dois nomes distintos:
um nome para o programa principal, outro para o procedimento. Cada alteração efetuada no parâmetro
formal provocará uma alteração na variável passada que, ao final do procedimento, terá o mesmo valor
final que o parâmetro formal correspondente.
PROGRAM Troca;
{Exemplo de parâmetros por referência}
var X, Y : integer;
begin
Aux := V1;
V1 := V2;
V2 := Aux;
end;
begin
X := 1; Y := 99;
TrocaVar (X, Y);
Writeln('X = ', X, 'e Y = ', Y);
end.
Resumindo parâmetros
Parâmetros por valor são declarados sem a palavra var, e representam dados de entrada de um
procedimento. Para estes podem ser usados como parâmetros efetivos: variáveis, constantes e
expressões. O procedimento chamado recebe valores. Se o argumento é uma variável, recebe o valor
desta no momento da execução; se expressão, o valor resultante da avaliação da expressão.
Parâmetros por referência são precedidos da palavra var e constituem dados de entrada e saída, ou
somente de saída. Na chamada somente variáveis podem constituir-se nos parâmetros efetivos
correspondentes. Ao final da execução do procedimento, o parâmetro efetivo conterá o mesmo valor
que o parâmetro formal correspondente.
Assim como procedimentos, podemos criar funções, segundo uma estrutura similar. Funções
definidas pelo programador são semelhantes aos procedimentos nos seguintes aspectos:
constituem-se em um bloco de instruções com um nome que as identifica;
podem possuir seção local de dados;
podem receber parâmetros por valor ou por referência;
são executadas somente quando chamadas.
As diferenças:
retornam um valor ou resultado, cujo tipo deve ser especificado na declaração da função;
no bloco de código da função, devemos atribuir um valor a ser retornado;
somente podem ser chamadas em expressões.
var N : byte;
begin
F := 1;
for I := 2 to Num do Atribuição do
F := F*I valor de retorno
Fatorial := F; Chamada (o
end; valor retornado
aparecerá aqui)
begin
Writeln('Entre um número inteiro:');
Readln(N);
Writeln('O fatorial de ', N, ' é ', Fatorial(N) );
end.
begin
AlunoPassou := (Nota >=5)
end;
begin
Dia := Copy(Data, 1, 2);
end;
var I : byte;
begin
for I := 1 to Length(S) do
S[I] := Upcase(S[I]);
Maiusc := S;
end;
var Ap : byte;
CadInv : string;
begin
CadInv := '';
Ap := Length(Cad);
while Ap > 1 do
begin
CadInv := CadInv + Cad[Ap];
Ap := Ap + 1
end;
InverteCadeia := CadInv;
end;
A forma que você dá às instruções que cria afeta profundamente o seu rendimento como
programador. Por exemplo, você poderia programar uma função que calcula o fatorial da forma abaixo,
declarando todas as variáveis como globais:
174 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
PROGRAM CalculaFatorial_Dependente;
var N, I : byte;
F : longint;
begin
F := 1;
for I := 2 to N do
F := F*I
Fatorial := F;
end;
begin
{...}
end.
Se você quiser usar essa função em outro programa, terá que declarar as variáveis I e F que a
função necessita. Imagine que um programa maior utilize 10, 20 ou mais funções e procedimentos, todos
estruturados dessa forma. Além de ter que se lembrar de todas as variáveis de que todos necessitam,
algumas das variáveis terão o mesmo nome, e pode ocorrer que uma instrução modifique uma variável
que está sendo usada por outra. Você ia ficar louco para administrar essa complexidade.
Usando parâmetros adequados e variáveis locais, você torna as novas instruções independentes, e
assim sendo, elas se tornam imediatamente reutilizáveis. Além disso, variáveis locais só ocupam memória
quando sua instrução está ativa. E uma outra imensa vantagem é que você pode escrever e testar as
instruções em separado uma da outra.
Quando uma instrução produz dados, se bem estruturada ela não apresenta seus resultados na tela;
simplesmente retorna o valor, o que a torna mais genérica. A parte do programa que a chamou é que
decidirá o que fazer com o valor. Se uma instrução mostra um resultado na tela, e você precisar imprimir
o valor, terá que alterá-la, ou escrever outra instrução. Esse tipo de independência das instruções
proporciona reusabilidade imediata, que por sua vez incrementa a produtividade do programador.
begin
GotoXY(X,Y);
FillChar(Regs, SizeOf(Regs),0);
Regs.AH := 8;
Regs.BH := 0; (* página de vídeo *)
Intr($10,Regs);
ScreenChar := Regs.AL;
end;
Para criar uma nova instrução, você pode seguir alguns passos bem definidos:
Identificação da possibilidade - Quando é que você decide que vai declarar uma instrução?
Tipicamente é quando faz a segmentação, na forma de diagrama de blocos ou refinamentos, e estrutura o
programa. Um ponto importante é estar procurando uma operação ou ação que possa ser implementada
através de uma nova instrução. Um pouco de experiência já faz com que você perceba logo essas
possibilidades.
Entrada - Identificação dos dados necessários para a instrução atender à sua finalidade.
Saída/resposta - Definição dos dados de saída ou da resposta que a instrução deve produzir.
Tipo da instrução - A instrução pode um procedimento ou uma função. Tipicamente será uma
função quando houver apenas um valor de retorno, e procedimento nos demais casos.
176 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Teste - Se outras partes do programa estão avançadas e habilitam o teste da nova instrução, teste-
a lá mesmo. Outra possibilidade é fazer um pequeno programa para efetuar o teste. Se o procedimento foi
bem estruturado, isso será muito fácil; veja à frente as considerações sobre independência e reusabilidade
de instruções.
Podemos criar uma instrução para a segunda ação: ela receberá a cadeia e retornará a quantidade
de palavras. Seguindo a seqüência de passos sugerida acima para a declaração de uma instrução, temos:
Tipo da instrução: havendo um só valor retornado, podemos declarar uma função, cujo uso é
mais prático que o procedimento.
Em cada caso é tomado o cuidado de não ir além do final da cadeia, verificando se o apontador
Ap não ultrapassou seu tamanho. Veja o programa a seguir..
9 - CRIAÇÃO DE INSTRUÇÕES E MODULARIZAÇÃO 177
PROGRAM ContaPalavras;
uses CRT;
begin
CtPalavras := 0;
Ap := 1;
while Ap < Length(Cadeia) do
begin
{pula os espaços}
while (Cadeia[Ap] = Espaco) and (Ap <= Length(Cadeia)) do
Ap := Ap + 1;
if Ap <= Length(Cadeia) then
begin
{achou palavra}
CtPalavras := CtPalavras + 1;
{pula os caracteres da palavra encontrada}
while (Cadeia[Ap] <> Espaco) and (Ap < Length(Cadeia)) do
Ap := Ap + 1
end
end;
CalcQtPal := CtPalavras
end;
begin
ClrScr;
Writeln('Contador de palavras');
repeat
Write('Digite cadeia de até 255 caracteres: ');
Readln(CadLida);
if CadLida <> '' then
Writeln( CalcQtPal(CadLida), ' palavras.'); Writeln;
until CadLida = ''
end.
Modelo:
Verifica se aluno passou em disciplina.
FUNCTION AlunoPassou( Nota : real ) : boolean;
Chamada: if AlunoPassou (7.5) then ...
a) Calcula média aritmética de 3 números.
b) Calcula um inteiro elevado a outro inteiro.
c) Mostra na tela uma linha de texto.
d) Calcula dígito verificador de CPF.
e) Imprime um cabeçalho com número de página.
Se você quiser reutilizar os procedimentos WriteXY, Som ou qualquer outro, terá que copiar as
instruções da declaração de um programa para outro e recompilar. Um jeito melhor é colocar as novas
instruções em uma unit. Uma unit é um arquivo texto, como um programa-fonte, mas começa com a
palavra reservada unit, é compilada em separado dos programas e quando é compilada é gerado um
180 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
arquivo com código objeto e extensão .TPU. Um unit não é executável diretamente mas pode ser usada
por qualquer programa.
O princípio básico de uma unit é que para que um programa referencie uma instrução, não é
necessário expor as declarações internas ou o bloco de código da instrução; é preciso somente conhecer o
cabeçalho: o nome da instrução e o tipo dos parâmetros. Por isso uma unit possui duas seções: a parte
pública (interface) e a parte privada (implementation). Na parte pública ficam somente os cabeçalhos
das instruções e na parte privada ficam os nomes e blocos de código, ou seja, a implementação das
instruções. Quando usa uma unit, um programa só pode referenciar as instruções cujo cabeçalho foi
declarado na parte pública. De fato, pode haver também declarações de tipos de dado, constantes e
variáveis, em ambas as seções. Novamente só as declarações públicas podem ser referenciadas no
programa que usa a unit.
São palavras reservadas, além das já conhecidas: unit, interface, implementation. No bloco de
código no final da unit podem ser incluídos comandos (opcionais) para a inicialização de variáveis ou
algo que precise ser feito para que as instruções da unit funcionem corretamente.
UNIT Nome;
Interface
Na seção Interface ficam
PROCEDURE Proc1 (parâmetros); apenas os cabeçalhos das
{descrição do procedimento 2} instruções públicas, isto é, que
podem ser chamadas por
FUNCTION Func1 (parâmetros): tipo; programas.
{descrição da função 1}
Implementation
Uses lista de units usadas na implementação;
PROCEDURE Proc1;
Var variáveis locais; Na seção Implementation
begin ficam os nomes das instruções
(não é preciso repetir os
Comandos do procedimento 1 parâmetros) e o restante da
end; implementação de cada uma.
FUNCTION Func1;
var variáveis locais;
begin
Comandos da função 1 Este procedimento não aparece
end. na Interface; é de uso interno da
unit e não pode ser chamado por
PROCEDURE Proc2(parâmetros); programas.
var variáveis locais;
begin
Comandos do procedimento 2
Comandos colocados
end.
nesta seção serão
begin executados no início
de cada programa que
{comandos de inicialização da unit} usa a unit.
end.
9 - CRIAÇÃO DE INSTRUÇÕES E MODULARIZAÇÃO 181
Tanto na interface quanto na implementação, você pode declarar também variáveis, tipos e
constantes. Se estes forem declarados na interface, serão visíveis para os programas. Veja a seguir uma
unit que contém uma única instrução, WriteXY.
unit CRT2;
Parte pública:
interface para usar só é
preciso conhecer
PROCEDURE WriteXY (Col, Lin : byte; Texto : string); os cabeçalhos.
{mostra texto na tela, na coluna e linha recebidas}
implementation
begin
end.
interface
implementation
PROCEDURE EqSegGrau;
begin
Delta := b*b - 4*a*c;
Raiz1 := (-b + SqRt(Delta) )/2*a;
Raiz1 := (-b - SqRt(Delta) )/2*a;
end;
FUNCTION Fatorial;
var I : byte;
F : longint;
begin
F := 1;
for I := 2 to N do
F := F*I;
Fatorial := F;
end;
begin
end.
PROGRAM CalculaFatorial;
var N : byte;
begin
ClrScr;
Writeln('Entre um número inteiro:');
Readln(N);
Writeln('O fatorial de ', N, ' é ', Fatorial(N) );
end.
unit RXY;
interface
implementation
uses CRT;
PROCEDURE ReadXY;
begin
GotoXY (X, Y); Write(Prompt);
X := X + Length(Prompt) + 1;
Pos := 1; Insere := True;
repeat
{mostra valor atual}
GotoXY(X,Y); Write(S);
{posiciona cursor no ponto de edicao}
GotoXY(X + Pos - 1, Y);
{le a tecla e processa (caractere válido ou de controle)}
Tecla := ReadKey;
case Tecla of
' ','0'..'9','A'..'Z','a'..'z' :
begin
if not Insere then
begin
S[Pos] := Tecla;
if Pos < Tam then Pos := Pos + 1;
end
else if Length(S) < Tam then
begin
Insert(Tecla, S, Pos);
if Pos < Tam then Pos := Pos + 1;
end;
end;
#0 : begin
{trata teclas especiais, que tem dois códigos, sendo zero o primeiro}
Tecla := ReadKey;
case Tecla of
kSeta_Esq : if Pos > 1 then Pos := Pos - 1;
kSeta_Dir : if Pos < Tam then Pos := Pos + 1;
kHome : Pos := 1;
kEnd : Pos := Length(S);
KInsert : If Insere then Insere := False
else Insere := True;
end
end;
end
until (Tecla = kEscape) or (Tecla = kEnter);
end;
begin
end.
Para a unit e o procedimento ReadXY, faça o seguinte:
184 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
*
* *
b) Escrever um procedimento que lê e retorna, por referência, dois números de 1 a 6 lidos do teclado.
Caso um dos números esteja fora da faixa válida, o procedimento retorna zero para ambos.
c) Elaborar um procedimento que recebe como parâmetros (não leia do teclado) dois números
correspondentes à pontuação de dois dados e faz o seguinte:
Sorteia e armazena a pontuação de dois dados (para isso chame a função da unit declarada
acima).
Mostra na tela a pontuação sorteada de ambos os dados (use o procedimento declarado
acima).
Compara os pontos sorteados com os pontos recebidos e mostra mensagem na tela
informando se os dados são iguais (em qualquer ordem), se a soma é igual ou se nada disso
ocorreu.
d) Implementar um programa de sorteio de dados, que repetidamente oferece um menu com as seguintes
opções:
Terminar.
Leitura do palpite do usuário para dois dados. Use o procedimento declarado acima, e espere
uma tecla após a chamada do procedimento.
Sortear e verificar o resultado. Use o procedimento declarado acima, mas somente se a
leitura já foi efetuada. Se não, é mostrada uma mensagem apropriada. Espere também uma
tecla antes de retornar.
b) Mostrar submenu com duas opções: informações do programador, da disciplina, etc. ou ajuda
para o programa. Usar procedimento para este submenu.
c) Ler uma cadeia qualquer.
d) Inverter a cadeia, que ficará como lida de trás para a frente. Usar função para a inversão.
e) Converter a cadeia para maiúsculas, usando função
f) Converter a cadeia para minúsculas, usando função.
g) Restaurar o último valor lido para a cadeia.
b) Escreva um programa que calcula as freqüências de notas acima do Lá (La#, Si, Dó, Dó#, Ré,
Ré#, Mi, Fá, Sol, Sol#, Lá, Lá #, Si, Dó. Anote as freqüências.
c) Em outro programa, declare constantes para as freqüências das notas (por ex., DO) e escreva
instruções que toquem o Parabéns pra você. [Dica: declare uma constante para a duração e use
múltiplos desta; as primeiras notas, com a respectiva duração, do Parabéns ficariam assim:
(DO, Dur), (DO, Dur), (RE, 4*Dur), (DO, 2*Dur). Tente Dur = 100 e 200.]
191
Em várias situações o programador deve trabalhar com listas de nomes, números e várias outras.
Para facilitar a sua vida, as linguagens de programação permitem a declaração de muitas variáveis em
uma só instrução, na forma de uma lista com vários elementos, e para atribuir ou recuperar valores você
faz referência a um elemento de cada vez, através de sua posição na lista.
Essas listas são chamadas de vetores, quando de uma dimensão, ou matrizes, quando com duas ou
mais dimensões. Você verá neste capítulo como declarar e usar esse tipo de variáveis em Pascal.
9.1. Vetores
"Implementar um programa que lê uma série de pares freqüência/duração até que seja lida uma
freqüência zero. Após, o programa "toca" a seqüência lida, emitindo sons em cada freqüência, com a
respectiva duração."
Para efetuar a leitura, você vai precisar de variáveis para a freqüência e a duração. Mas onde
guardar os valores lidos anteriormente? Mesmo que fossem declaradas variáveis para cada par (o que
daria muito trabalho), não se sabe a quantidade de pares.
Vamos ver como atender à necessidade da especificação acima e depois como efetuar a
declaração no Pascal. Para essa especificação, precisamos de duas listas, uma para as freqüências e outro
para as durações. Como exemplo, vamos usar as seis primeiras notas do "Parabéns pra você"; as listas
devem ficar assim (assumindo um máximo de 10 notas em uma “música”):
Freqüências (Hertz)
440 440 500 440 600 560
1 2 3 4 5 6 7 8 9 10
Durações (milissegundos)
200 200 800 400 400 800
1 2 3 4 5 6 7 8 9 10
No Pascal, e como qualquer outra variável, para se usar um vetor é preciso declará-lo; sua
declaração deve fornecer os seguintes elementos:
nome: o identificador do vetor
limite inferior: inteiro que aponta para o menor posição do vetor2
limite superior: inteiro que aponta para a maior posição do vetor
tipo de dado de cada elemento.
Sintaxe da declaração:
var nome : array [Limite inferior..limite superior] of tipo;
array e of são palavras reservadas. O primeiro número dentro dos colchetes indica o número ou
posição do primeiro elemento (limite inferior), e o segundo (10) indica o número do último (limite
superior). As declarações acima, portanto, criam dois vetores com 10 elementos cada um, numerados de 1
a 10, sendo que em cada elemento ou posição podemos armazenar um dado do tipo word. Veja que desta
forma criamos 10 variáveis de uma só vez, a cada declaração.
Como as duas estruturas são iguais, podemos simplificar a declaração usando type:
type tNotas = array [1..10] of word;
Um vetor é dito ser um tipo estruturado e homogêneo de dados, porque é composto de várias
variáveis, todas de um mesmo tipo.
O limite inferior de um vetor não precisa ser necessariamente 1. Você pode utilizar um valor
relacionado ao contexto dos seus dados. Por exemplo, se você quer armazenar uma tabela de
correspondência de graus Fahrenheit/Celsius na faixa de 32 a 212, você poderia declarar um vetor assim:
2
Na verdade, os limites inferior e superior podem ser de outros tipos de dado (como char e boolean); para
nós é suficiente assumirmos que são números.
10 - LISTAS NUMERADAS: VETORES E MATRIZES 193
O vetor acima possui 212 - 32 + 1 = 181 elementos. Veja outros exemplos de declaração de
vetores:
Exemplos:
vFreq[4] := 100; {atribui o valor 100 ao elemento na posição 4 do vetor vFreq}
uses CRT;
begin
ClrScr;
Writeln('Programa para identificar o maior dentre três'
+ ' números inteiros diferentes');
Write('Entre o primeiro número: '); Readln(vNum[1]);
Write('Entre o segundo número: '); Readln(vNum[2]);
Write('Entre o terceiro número: '); Readln(vNum[3]);
if (vNum[1] > vNum[2]) and (vNum[1] > vNum[3]) then
PosMaior := 1
else if vNum[2] > vNum[3] then
PosMaior := 2
else
PosMaior := 3;
Writeln('O maior número foi ', vNum[PosMaior], ' na posição ',
PosMaior);
ReadKey;
end.
b) Execute-o com o debugger até o primeiro Readln. Entre na janela Watches a expressão vNum[1],
para ver o primeiro elemento do vetor. Execute o Readln e observe a janela Watches. Faça o
mesmo para os demais elementos.
c) Para ver todo o vetor, entre na janela Watches apenas o nome dele, vNum.
d) Teste o programa para as seguintes situações:
- maior é o primeiro número lido.
- maior é o segundo.
- maior é o terceiro.
10 - LISTAS NUMERADAS: VETORES E MATRIZES 195
var V : tVet;
X : real;
I : byte;
begin
V[1] := 2; V[2] := 4; V[3] := 1; V[4] := 3; V[5] := 5;
X := V[1] + V[5]; Writeln(X);
X := V[2] - V[5]; Writeln(X);
X := V[4] * V[1] - X; Writeln(X);
I := 4;
X := V[ V[I] ]; Writeln(X);
X := V[ V[I] - 1] / V[ V[3] ]; Writeln(X);
end.
PROGRAM ExemploVetor;
begin
vFreq[1] := 400;
vDur[1] := 200;
Sound(vFreq[1]); {recupera}
Delay(vDur[1]);
NoSound;
end.
b) Altere o programa, incluindo atribuições de valores variados aos elementos 2 e 3 de cada vetor.
Inclua também as instruções para tocar os sons. Teste.
c) Agora altere o programa de forma que ele continue atribuindo os mesmos valores aos elementos
1, 2 e 3 mas execute a nota de uma posição informada pelo teclado. Se for informado 2, por
exemplo, o programa faz soar a freqüência de vFreq[2] com a duração vDur[2].
d) No programa acima, a referência vFreq[11] seria inválida, porque o tamanho máximo do vetor é
10 e a numeração é de 1 a 10. Pelo mesmo motivo, vFreq[0] também seria inválida. Para conferir
isso, inclua no programa ExemploVetor atribuições para posições abaixo do limite inferior e
acima do limite superior e tente compilar.
Quando você precisa processar todos os elementos de um vetor, e não sabe quantos elementos de
um vetor serão usados, deve então usar repeat ou while. No trecho abaixo, a leitura deve parar quando
for digitado zero, mas também devemos evitar que o limite do vetor seja ultrapassado:
Pos := 1;
repeat
Readln(vFreq[I]);
Pos := Pos + 1
until (I > MaxNota) or (vFreq[I] := 0)
Se você sabe qual é a última posição, o comando for é o ideal. Veja alguns exemplos para o
vetor de freqüências, supondo que a posição do último elemento é indicada pela variável Pos:
for I := 1 to Pos do {escolha um}
vfreq[I] := 0; {para inicializar}
Dessa forma você mantém a quantidade de elementos do vetor em um só lugar do programa, e pode
modificá-la, para correção ou otimização, sem ter que procurar cada comando que faça referência ao
tamanho.
for I := 1 to MaxNotas do
begin
Write ('Entre nota ', I, ' ');
Readln(Nota[I]);
end;
for I := 1 to MaxNotas do
Writeln(Notas[I]);
Para preencher um vetor de 100 elementos com inteiros aleatórios, na faixa de 0 a 999:
Randomize; {inicializa gerador de números aleatórios}
for I := 1 to 100 do
Vet[I] := Random(1000);
Para pesquisar uma determinada nota (neste caso, sem o uso do for):
Readln(NotaDesejada);
I := 0;
repeat
I := I + 1
until (Notas[I] = NotaDesejada) or (I > MaxNotas);
if I <=MaxNotas then
Writeln('Encontrada na posição ', I)
else
Writeln('Nota não encontrada');
Faça um programa que leia cadeias (qualquer quantidade, limitada a 20) de até 39 caracteres e
mostre-as espelhadas no centro da tela, como no exemplo:
198 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Primeira ariemirP
Segunda adnugeS
Terceira ariecreT
...
A lista é um vetor com 20 elementos, sendo string o tipo de dado de cada elemento. Uma variável
armazenará a quantidade de cadeias digitadas, já que o vetor pode não ser completamente preenchido.
Precisaremos também de uma variável para a linha, já que cada cadeia será mostrada em uma linha
diferente. Para inverter uma cadeia usamos uma função já vista. Estude os demais detalhes no programa:
PROGRAM EspelhaCadeias;
uses CRT;
var Ap : byte;
CadInv : string;
begin
CadInv := '';
for Ap := Length(Cad) downto 1 do
CadInv := CadInv + Cad[Ap];
InverteCad := CadInv;
end;
begin
{lê e armazena as cadeias}
ClrScr;
Writeln('Mostra cadeias espelhadas na tela'); Writeln;
I := 0;
repeat
I := I + 1;
Write('Cadeia ', I, ' : ');
Readln(vCad[I]);
until (vCad[I] = '') or (I = MaxQtCad);
{Lembra a quantidade de cadeias digitadas}
if vCad[I] = '' then QtCad := I - 1 else QtCad := I;
{limpa a tela e mostra as cadeias normais e espelhadas}
ClrScr;
Linha := 1;
for I := 1 to QtCad do
begin
{Posiciona cursor para mostrar a cadeia normal, de forma
que o último caractere esteja na coluna 39}
GotoXY(39 - Length(vCad[I]), Linha);
Write(vCad[I]);
{Inverte e mostra a cadeia invertida a partir da coluna 41}
GotoXY(41, Linha);
Write(InverteCad(vCad[I]));
Linha := Linha + 1
end;
end.
O programa tem duas telas de saída distintas: a primeira, de digitação das cadeias, e a segunda,
em que são mostradas as cadeias espelhadas. Veja a seguir uma amostra da execução.
PROGRAM TocaVetor;
{lê várias freqüências e durações para um vetor
e depois "toca" as notas na seqüência}
uses CRT;
begin
ClrScr;
{leitura das notas}
Pos := 0;
repeat
Pos := Pos + 1;
Write('Freqüência ', Pos, ': ');
Readln(vFreq[Pos]);
Write('Duraçao ', Pos, ': ');
Readln(vDur[Pos]);
until (vFreq[Pos] = 0) or (vDur[Pos] = 0)
or(Pos > cMaxNotas);
{toca notas no vetor}
for I := 1 to Pos - 1 do
begin
Sound(vFreq[I]);
Delay(vDur[I]);
NoSound;
end;
end.
*
* *
* *
* *
* * * * *
* *
* *
9.5. Registros
Como vimos, um elemento de um vetor pode ser apenas de um tipo de dado. Em algumas
situações, isto pode ser inconveniente. Suponha que uma especificação pede para armazenar nomes de
disciplinas e respectivas notas. Sem algum outro recurso, precisaríamos declarar um vetor de cadeias para
as disciplinas e outro, de reais, para as notas.
O Pascal permite uma solução elegante para este inconveniente, por meio da declaração de vários
dados em um único tipo de dado: o registro. Um registro é um agregado de variáveis, de tipos de dados
distintos, em um único tipo de dado, que por isto é chamado de estruturado. Podemos usar registros
isoladamente, combinados com vetores e também para usar em arquivos.
Um registro é declarado através da palavra reservada record, seguida das declarações das
variáveis que o compõem, e terminando com end. Tipicamente efetua-se a declaração em uma seção
10 - LISTAS NUMERADAS: VETORES E MATRIZES 203
type, embora ela possa ocorrer diretamente na seção de variáveis. Veja os exemplos de declaração de
registros e de variáveis:
tNota = record
NomeDisciplina : string[15];
ValorNota : real;
end;
tCoordenadas = record
X, Y : byte
end;
tPessoa = record
Nome : string[30];
Endereco : string[50];
DataNasc : tData;
Fone : string[10];
E-mail : string[30];
end;
Observe na última declaração da seção type como um registro pode ser composto de outros
registros: o tipo tPessoa contém o campo DataNasc, que por sua vez é também um registro, composto dos
campos Dia, Mes e Ano.
Referências a campos - Para atribuir a ou recuperar valores de campos, é preciso indicar tudo o
que for preciso para o compilador identificar o campo sem ambigüidade: o nome da variável e o nome do
campo, separados por um ponto. Para simplificar as referências a campos, podemos usar a declaração
With...do, na qual indicamos o nome do registro que será referenciado. Dentro do escopo do With,
podemos escrever somente o nome dos campos.
Para exemplificar, primeiro declaramos um registro com nome de disciplina e valor da respectiva
nota. Depois definimos um vetor com capacidade de armazenar até 20 registros de notas. Finalmente,
declaramos um registro para armazenar informações sobre alunos, contendo um nome e uma lista de
notas. Observe no bloco de código abaixo as várias possibilidades de referência a campos, incluindo
declarações With.
PROGRAM ExemplosReferenciasACampos;
begin
{referências normais a campos de registros}
vAlunos[1].Nome := 'Adalberto';
vAlunos[1].Notas[1].NomeDisciplina := 'Português';
vAlunos[1].Notas[1].ValorNota := 7.5;
vAlunos[1].Notas[2].NomeDisciplina := 'Inglês';
vAlunos[1].Notas[2].ValorNota := 8;
Podemos aplicar o recurso de declarar registros no programa que toca músicas. Ao invés de
declarar dois vetores, precisamos de apenas um:
type tNota = record
Freq, Dur : word;
end;
tMusica = array [1..10] of tNota;
uses CRT;
begin
ClrScr;
Pos := 0;
repeat {leitura das notas}
Pos := Pos + 1;
Write('Freqüência ', Pos, ': '); Readln(vMusica[Pos].Freq);
Write('Duração ', Pos, ': '); Readln(vMusica[Pos].Dur);
until (vMusica[Pos].Freq = 0) or (vMusica[Pos].Dur = 0)
or (Pos > cMaxNotas);
{toca notas no vetor}
for I := 1 to Pos - 1 do
begin
with vMusica[I] do
begin
Sound(Freq);
Delay(Dur);
NoSound;
end;
end;
end.
10 - LISTAS NUMERADAS: VETORES E MATRIZES 205
9.6. Matrizes
Um professor quer fazer um programa que armazene notas de alunos para cada disciplina que
leciona e mostre algumas informações. O que ele deseja é uma tabela com a forma:
206 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
Patrícia 4 4.5 6
Simone 8 10 9.5
Qual será a melhor estrutura de dados para armazenar esta tabela? O que o professor precisa é de
uma extensão do conceito de vetores, chamada matriz. Ao invés de apenas uma dimensão, como os
vetores, matrizes são listas multidimensionais; no exemplo acima, a estrutura adequada é uma matriz de
duas dimensões.
Ao acessar um elemento de uma matriz, devemos informar o subscrito para cada dimensão:
Mat[1, 11, 2] := 77;
Readln( Mat[9, 7, 1] );
Writeln( Mat[2, 5, 5] );
++²Éâ+¼åñ+¿ª_+É
¬+£+ä__ö_☺ò+Ö_+
úè-_ö+«ÖäÇéó-++
+û+¦+¦++ÜÆ_â-+·
¦++_¿-Ñ_+ú+¦á+_
_+-äẻÖæ¦-àß_+
¦n+_++«_•¦+éú½_
à•ÅÇü¬É·-¦£+_-»
û¼°ªÖ-__+_•+__¦
•_+__ùÉ¥±_¦á+ó¦
¡²¦+û_½_¦_+ê_²+
»___Å+°____ú¦Ö_
â«¥æâúÄÿ__Ç__++
+_¦+¿__-_++·---
ºn_+±¦_½+ü___¦ß
Ache o ☺!
PROGRAM AcheNaTela;
{Esconde uma careta na tela preenchida com caracteres aleatórios, para
a pessoa descobrir onde está}
uses CRT;
begin
{Preenche a matriz com caracteres aleatórios na faixa ASCII superior a 127}
Randomize;
for L := 1 to cMaxLin do
for C := 1 to cMaxCol do
vTela[L,C] := 128 + Random(126);
segundos dígitos, e assim por diante. Por exemplo, suponha que os números da Loteria Federal
são:
1 - 45.698
2 - 65.788
3 - 01.214
4 - 37.840
5 - 77.430
Os prêmios da rifa serão 46.037, 55.177, etc.
A estrutura do programa é simples: ler os números sorteados na loteria, identificar os números premiados
na rifa, mostrar os números premiados na tela. Portanto, vamos nos concentrar no passo "identificar os
números premiados" e elaborar um algoritmo. A escolha da estrutura de dados aqui é a chave: apesar de
os dados serem números, representá-los como strings torna mais fácil a solução; teremos um vetor de
strings para os prêmios da loteria e outro para a rifa. E como strings são um tipo de vetor, estamos
tratando com uma matriz 5x5. O algoritmo equivale a inverter uma matriz: o que é linha vira coluna e
vice-versa.
PROGRAM CalculaNumerosRifa;
begin
for Premio := 1 to 5 do
begin
vLoteria[Premio] := '';
for Posicao := 1 to 5 do
vRif[Premio] := vRif[Premio] + vLoteria[Posicao,Premio]
end;
end;
begin
{leitura dos números sorteados na loteria}
For Premio := 1 to 5 do begin
Write('Numero ', Premio, ': ');
Readln(vLot[Premio]);
end;
CalcNumRifa(vLot, vRifa);
Writeln('Números da rifa:'); {mostra resultados}
For Premio := 1 to 5 do
Writeln(Premio, ': ',vRifa[Premio]);
end.
c) jogo-da-velha
d) um tabuleiro de damas (casas, posição e cor da pedra)
e) um tabuleiro de batalha naval
f) um tabuleiro de xadrez
g) todas as posições de uma tela de computador em modo texto padrão (25x80)
h) as 25 linhas da tela
i) O jogo Campo Minado, do Windows.
j) um labirinto (paredes, localização do tesouro e do monstro, ou outra coisa que você inventar).
Elabore um programa que identifica e mostra na tela todos os quadrados mágicos com as características
acima. Analise os quadrados mostrados e verifique se há alguma diferença básica entre eles ou se podem
ser considerados os mesmo sob algum aspecto. [Dica: produza todas as combinações possíveis e
210 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
verifique a soma quando completar cada quadrado. Usar um vetor de 1 a 9 (a estrutura que usei) parece
ser mais simples que usar uma matriz 3x3]
Uma das melhores formas de aprender a programar é lidando com situações novas, para as quais
você acha uma solução onde antes pouco sabia. Fazer um programa maior é uma forma de fazer isto, ao
mesmo tempo em que os novos conhecimento são integrados. Por isto, você deve fazer pelo menos um
dos trabalhos indicados neste capítulo. Use como inspiração a implementação descrita. E envie-me o
programa para que seja incluído como demonstração nesta apostila!
Não imagine que um programa é implementado linearmente, etapa por etapa. É mais provável
que você vá e volte várias vezes nas várias fases, à medida em que amadurece sua compreensão da
especificação e do resultado final.
10.1. Especificação
Escrever um programa para fazer estatísticas de notas de um aluno. O programa oferece opções
de: entrar com nomes de disciplinas e respectivas notas, achar a maior nota, achar a menor nota e
calcular a média das notas. Quando mostra algum resultado, o programa espera ser teclado algo para
oferecer novamente o menu.
O primeiro passo é ler a especificação algumas vezes, e deixar que sejam formadas as primeiras
impressões. Neste ponto descobrimos muitas coisas que não sabemos.
10.2. Projeto
O programa tem um menu inicial, mencionado na especificação. Assim, a tela inicial conterá as
quatro opções previstas na especificação e uma outra para terminar o programa. Ela fica definida como
abaixo. Note que nosso objetivo é ilustrar as etapas de programação e por isto evitamos "enfeites", do tipo
formatação de tela. Fique à vontade para embelezar seus programas, se tiver tempo para isso.
ESTATÍSTICA DE NOTAS
0 - Fim
1 - Entra valores
2 - Maior nota
3 - Menor nota
4 - Media
Opção: _
Quando o usuário escolher, o programa fará o que for pedido abaixo do menu. Por exemplo, a
entrada de valores pode ocorrer assim:
212
ESTATÍSTICA DE NOTAS
0 - Fim
1 - Entra valores
2 - Maior nota
3 - Menor nota
4 - Media
Opção: 1
Tecle Enter na disciplina para terminar
Nome da disciplina: Calculo
Nota de Calculo : 8
Nome da disciplina: Pascal
Nota de Pascal : 9.5
Nome da disciplina: TGA
Nota de TGA : 7.5
Nome da disciplina: _
0 - Fim
1 - Entra valores
2 - Maior nota
3 - Menor nota
4 - Media
Opção: 4
Media das notas: 8.33
Assim que o usuário teclar Enter no nome da disciplina, limpamos a tela e reapresentamos o
menu. Para as demais opções simplesmente é mostrado o que foi pedido e espera-se uma tecla antes de
limpar a tela e mostrar novamente o menu. Ao elaborar seus projetos, recomendo detalhar todo o
programa.
10.3. Programa-fonte
Podemos começar o programa-fonte pela sua estrutura, representada por um diagrama de blocos.
Poderíamos fazer refinamentos sucessivos, se quiséssemos. Veja a seguir; por questões de espaço, não
está representada a opção de cálculo da menor nota.
Precisamos de uma estrutura de dados que guarde as notas: um vetor de notas e disciplinas,
numerado de 1 até a quantidade máxima de notas que se espera. Para facilitar as declarações e eventuais
alterações, declaramos a quantidade de elementos como uma constante e o tipo do vetor em uma
declaração type. Cada elemento do vetor de notas irá armazenar uma nota e uma disciplina, portanto o
tipo de dado será um registro com um campo real e outro string. As declarações serão:
const MaxNotas = 50;
Uma questão surge: quando o usuário for usar o programa, ele sempre digitará 50 disciplinas?
Dificilmente. Precisamos então controlar quantas disciplinas (e portanto notas) o usuário digitou: uma
variável, que chamaremos MaxAtual. Esta variável servirá de referência para acessos ao vetor, ao invés
da constante que indica o tamanho do vetor.
11 - TRABALHO FINAL 213
E s t a t í s t ic a d e
n o t a s d e a lu n o
B lo c o d e
I n i c ia liz a ç ã o c o n t r o le F i n a li z a ç ã o
M enu S e le ç ã o
L e it u r a d a s C á l c u lo d a C á lc u l o d a
n o ta s m a io r n o t a m é d ia
C a lc u la r M o s t r a r m a io r C a lc u l a r m é d i a
E n tra d a V a l id a ç ã o M o s t r a r m é d ia
m a io r n o t a n o ta d e n o ta s
A partir do diagrama de blocos, identificamos as instruções que podemos declarar. Para as ações
de achar a maior nota, a menor e a média, como cada uma retorna apenas um valor inteiro ou real, serão
três funções. Para que sejam independentes das variáveis globais, os dados de entrada são declarados
como parâmetros, e a saída é o valor de retorno da função. Podemos inicialmente definir somente os
cabeçalhos:
FUNCTION PosMenor (vNotas : tVetNotas; Max : byte ) : byte;
{retorna subscrito da menor nota}
Podemos escrever cada uma conhecendo apenas o que devem fazer e as estruturas de dados
escolhidas; veja a seguir. Não há trabalho significativo relacionado aos algoritmos, todos foram baseados
no conteúdo do capítulo sobre vetores. Mas se fosse necessário, desenvolveríamos cada um em separado
dos demais, facilitando bastante o processo.
214 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
var P, S : byte;
begin
P := 1;
for S := 2 to Max do
if vNotas[S].Nota < vNotas[P].Nota then P := S;
PosMenor := P
end;
var P, S : byte;
begin
P := 1;
for S := 2 to Max do
if vNotas[S].Nota > vNotas[P].Nota then P := S;
PosMaior := P
end;
begin
Soma := 0;
for S := 1 to Max do Soma := Soma + vNotas[S].Nota;
Media := Soma/Max
end;
.As variáveis globais que precisam ser declaradas são as mesmas que devem ser passadas para as
funções, mais o vetor das disciplinas e a opção. Para estrutura melhor o programa, decidimos declarar
instruções também para a leitura da opção e entrada de notas:
- Mostrar o menu, ler e retornar a opção (função)
- Ler e retornar valores das notas, disciplinas e a quantidade de notas lidas (procedimento)
PROGRAM EstatisticaDeNotas;
uses CRT;
var N : tvetNotas;
Opcao, MaxAtual, Pos : byte;
var Op : byte;
begin
Writeln('0 - Fim');
Writeln('1 - Entra valores');
Writeln('2 - Maior nota');
Writeln('3 - Menor nota');
Writeln('4 - Media');
Write('Op: '); Readln(Op);
Menu := Op;
end;
var S : byte;
begin
S := 0;
Writeln('Tecle Enter na disciplina para terminar');
Repeat
S := S + 1;
With vNotas[S] do
begin
Write('Nome da disciplina: ');
Readln(Disc);
if Disc <> '' then
begin
Write('Nota de ',Disc , ' : ');
Readln(Nota);
end
end;
Until (vNotas[S].Disc = '') or (S = cTamVet);
if S < cTamVet then Max := S - 1 else Max := S;
end;
216 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
var P, S : byte;
begin
P := 1;
for S := 2 to Max do
if vNotas[S].Nota < vNotas[P].Nota then P := S;
PosMenor := P
end;
var P, S : byte;
begin
P := 1;
for S := 2 to Max do
if vNotas[S].Nota > vNotas[P].Nota then P := S;
PosMaior := P
end;
begin
Soma := 0;
for S := 1 to Max do Soma := Soma + vNotas[S].Nota;
Media := Soma/Max
end;
Uma opção adicional para este programa seria declarar as instruções relativas a notas em uma
unit.
Como exercício, inclua opções no programa para:
10.4. Teste
Uma vez compilado o programa, deve-se testá-lo, comparando os resultados obtidos com a
especificação. Vamos vê-la outra vez:
Escrever um programa para fazer estatísticas de notas de um aluno. O programa oferece opções
de: entrar com nomes de disciplinas e respectivas notas, achar a maior nota, achar a menor nota e
calcular a média das notas. Quando mostra algum resultado, o programa espera ser teclado algo para
oferecer novamente o menu.
O programa pode ter erros de lógica, de controle e outros. No mínimo, o teste deve responder
favoravelmente às seguintes perguntas, elaboradas com base na especificação, no projeto e no programa-
fonte:
1) O menu contém as opções corretas?
2) O programa termina normalmente quando selecionada a respectiva opção do menu?
3) Todas as opções do menu estão sendo selecionadas?
4) A leitura das notas é efetuada corretamente? As notas e disciplinas estão sendo
armazenadas corretamente no vetor?
5) A maior nota é encontrada e mostrada corretamente?
6) A menor nota é encontrada e mostrada corretamente?
7) A média das notas é calculada e mostrada corretamente?
8) O programa espera uma tecla após mostrar um resultado?
9) O menu é mostrado novamente após um ciclo de seleção?
Ao escolher alguma das idéias desta seção, certifique-se de definir uma especificação completa,
adequada ao prazo disponível, e fazer o projeto, antes da decisão final.
10.1 – AcheNaTela
Inclua os seguintes recursos no programa AcheNaTela (pág. 207):
a) Crie um menu com as opções Configurar, Jogar, Terminar. Na opção de configuração, permita ao
usuário indicar o grau de dificuldade, determinado pela área da tela usada, e o caractere que deve ser
escondido.
218 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
b) Ao jogar, ofereça opções para imprimir o jogo, para mostrar onde está o caractere escondido e para
jogar novamente.
10.2 – Forca
Implementar um programa que jogue o jogo da forca. Na tela é mostrado o alfabeto, destacando as letras
já tentadas. Um banco de palavras pode ser implementado em vetor ou em arquivos, permitindo ao
programa sortear uma palavra. Extensões: armazenar histórico do jogador: nome, jogadas ganhas e
perdidas, etc.
CONTROLE DE SENHAS
10.6 – Robô
Faça um programa que entende alguns comandos simples do robô, como Ande e Vire. Algo que
representa o robô se move na tela em resposta aos comandos.
10.9 – Bingo
Elabore um programa que faz sorteios de bingo. O programa deverá oferecer opções de iniciar um sorteio,
sortear um número e apresentar os números sorteados até um determinado momento. Note que o
programa não poderá repetir um número já sorteado.
10.11 – Ping-Pong
Talvez você não conheça, mas um dos primeiros videogames era um Philco monocromático, e um dos
jogos, chamado de Ping-Pong, tinha duas "raquetes" que se moviam na vertical das laterais da tela e uma
"bolinha", cuja velocidade aumentava depois de algumas "raquetadas" dos jogadores. Um jogador fazia
um ponto quando o adversário deixava a bolinha passar; quem fizesse 15 pontos primeiro ganhava.
Implemente esse jogo. Uma alternativa mais simples é uma só raquete com um paredão.
10.15 – Tabuada
Implementar um programa para crianças que apóia o aprendizado de tabuada. Entre outras coisas, o
programa pode propor à criança seqüências de um mesmo número ou aleatórias. Pode também mostrar
números em tamanho maior. Se quiser sofisticar mesmo, armazene estatísticas de erros e acertos, e faça o
programa reforçar os pontos fracos.
10.17 – Provas V ou F
Elabore um programa que corrija provas contendo somente questões com respostas Verdadeiro ou Falso.
O programa deve armazenar as respostas corretas para cada questão e até 50 provas com até 20 questões.
Quando solicitado, o programa calcula e mostra as notas para cada aluno. Opcionalmente, o usuário pode
definir um fator de correção, de forma que para cada 2 ou 3 questões erradas, uma certa seja anulada.
Melhor implementar usando arquivos.
.
221
1) Compilei e executei o meu programa no Turbo Pascal e nada aconteceu. Ele não funciona?
Tecle Alt-F5 para ver a tela de saída.
2) Ao compilar, dá a mensagem “; expected”.
Está faltando um ponto-e-vírgula no final do comando anterior à posição do cursor.
3) Meu programa está em loop!
Tente teclar Ctrl-Break ou Ctrl-Break-Break para interromper sua execução.
4) Estou com um problema de compilação que não consigo solucionar.
Faça as práticas. Muitas delas foram feitas para lhe preparar para esses momentos.
5) O GotoXY não funcionou.
a) Você inverteu o X e o Y.
b) O X ou o Y estão fora da faixa válida de linhas e colunas (1 a 25 e 1 a 80, em modo
texto normal).
6) Ao compilar recebo uma mensagem de que não é possível gravar o arquivo.
Se você está em uma rede, é possível que não tenha autorização para a gravação.
Configure em Options/Directories o diretório dos executáveis (.exe e .tpu) para o nome DOS da
sua pasta na rede ou uma pasta na qual você possa gravar.
7) Não estou conseguindo elaborar algoritmos.
A apostila apresenta várias ferramentas de pensamento para esses momentos, use-as.
Procure também digitar e seguir programas mais complexos, para alimentar seus neurônios. E
acima de tudo, não fique ansioso, se dê mais tempo.
(envie sua contribuição para este apêndice para [email protected])
223
Abaixo são listados os principais procedimentos e funções padrão da Linguagem Turbo Pascal, e suas
finalidades. Detalhes sobre a sintaxe, os parâmetros e uso destes procedimentos/funções podem ser encontrados no
help do sistema: digite o nome da instrução e tecle Ctrl-F1. As instruções assinaladas com um asterisco existem
somente no Turbo Pascal para DOS.
Aritméticas
Abs Func Retorna o valor absoluto do argumento.
ArcTan Func Retorna o arco tangente do argumento.
Cos Func Retorna o do argumento (argumento é um ângulo em radianos).
Exp Func Retorna o exponencial do argumento.
Frac Func Retorna a parte fracionária do argumento (argumento é real).
Int Func Retorna a parte inteira do argumento (argumento é real).
Ln Func Retorna o logaritmo natural do argumento.
Pi Func Retorna o valor da constante Pi.
Sin Func Retorna o seno do argumento (argumento é um ângulo em radianos).
Sqr Func Retorna o quadrado do argumento.
SqRt Func Retorna a raiz quadrada do argumento.
Conversão de Dados
Chr Func Retorna o caractere da tabela ASCII correspondente a um número especificado.
Ord Func Retorna o número de ordem na tabela ASCII de um caractere especificado.
Round Func Arredonda um número real para o inteiro mais próximo.
Trunc Func Retorna a parte inteiro de um número real.
Str Proc Converte um valor numérico em uma cadeia de caracteres.
Upcase Func Converte um caractere para a Maiúscula correspondente.
Val Proc Converte uma cadeira de caracteres em um valor numérico.
*
Cortesia do Prof. Vicente P. Teixeira.
224
Manipulação de Arquivos
Assign Proc Atribui um nome externo para uma variável do tipo file.
BlockRead Proc Lê um ou mais registro de um arquivo para uma variável.
BlockWrite Proc Escreve em um arquivo um ou mais registros a partir de uma variável.
ChDir Proc Muda o diretório corrente.
Close Proc Fecha um arquivo aberto.
Eof Func Retorna o status de fim de arquivo.
Erase Proc Elimina um arquivo.
FilePos Func Retorna a posição corrente do apontador de arquivo.
FileSize Func Retorna o tamanho (quantidade de registros) de um arquivo.
GetDir Proc Retorna o diretório corrente de um drive especificado.
IOResult Func Retorna o status da última operação de I/O efetuada.
MkDir Proc Cria um subdiretório.
Read Proc Lê o registro corrente de um arquivo para uma variável.
Rename Proc Renomeia um arquivo.
Reset Proc Abre um arquivo.
Rewrite Proc Cria e abre um arquivo.
RmDir Proc Remove um subdiretório vazio.
Seek Proc Move o apontador de um arquivo para uma posição especificada.
Truncate Proc Trunca o arquivo na posição corrente.
Write Proc Escreve o conteúdo de uma variável em um arquivo.
Diversas
Delay Func Faz o processador gastar uma quantidade de milissegundos especificada.
GetDate Proc Retorna a data corrente do Sistema Operacional.
GetTime Proc Retorna a hora corrente do Sistema Operacional
NoSound* Proc Desliga o alto-falante interno do processador.
Random Func Retorna um número aleatório entre 0 e o argumento..
Randomize Proc Inicializa o gerador interno com um número aleatório (obtido do relógio do
sistema).
Sound* Proc Liga o alto-falante interno com a freqüência (em Hz) passada como argumento.
225
Quem está aprendendo normalmente não está propriamente na “zona de conforto”, e sim muito
perto de seus limites. E até que as novas habilidades se tornem naturais, espontâneas e fluentes, há uma
fase de transição, na qual pode haver momentos em que não se sabe precisamente o que é o melhor a
fazer. Dispor de boas alternativas para esses momentos pode acelerar o aprendizado, reduzir tempos e
mesmo tornar mais prazeroso o aprendizado. Este apêndice descreve algumas dessas alternativas, para
você usar quando for preciso ou simplesmente para fazer algo melhor.
Perguntar
"O olho dorme até que a mente o acorde com uma pergunta"
(Provérbio árabe)
Uma ferramenta muito poderosa para direcionar a mente é simplesmente elaborar perguntas a
respeito do assunto ou objetivo em questão. Por exemplo, por meio de perguntas podemos obrigar uma
pessoa a pensar no passado ou no futuro, mais genericamente ou mais especificamente. Note como posso
afetar o que você está pensando:
"O que você comeu hoje no café da manhã?"
"Qual foi a experiência mais agradável que você vivenciou?"
"Você se ama?" ou "Quanto você se ama, de 0 a 100"?
"Você gostou do último filme que assistiu?" ou "Qual parte do último filme que viu você mais
gostou?"
"Como você poderia melhorar seu rendimento escolar?"
"O que você realmente quer da vida neste momento?"
Perguntar é uma forma de manter a iniciativa. Se você enviar um e-mail e quiser uma resposta,
faça uma pergunta. Observe também como certos vendedores mantém o controle de uma conversa usando
esse recurso!
“Será que vai dar certo?” ou “O que eu posso fazer para dar certo?”
“Será que eu consigo?” ou “Qual é o próximo pequeno passo que posso dar para conseguir?”
“Sou capaz?” ou “O que posso aprender para facilitar atingir meu objetivo?”
“Será que eu nunca aprendo?” ou “O que já aprendi que posso aplicar neste caso?”
Aplicações – Antes de ler um livro, assistir uma aula ou iniciar uma sessão de estudos, pergunte:
o que quero com isto? Qual é o meu objetivo? Qual é a melhor atitude para aprender mais rapidamente?
O que eu já sei deste assunto? Qual é a melhor postura (física) para obter melhor rendimento?
"Temos notado este traço peculiar aos seres humanos. Se estes descobrem alguma coisa que
fazem e que não funciona, eles a repetem. Skinner tinha um grupo de alunos que havia realizado diversas
pesquisas com ratos e labirintos. E alguém, um dia, perguntou-lhes: "qual é realmente a diferença entre
um rato e um ser humano?" Bom, os comportamentistas, uma vez que não eram pessoas terrivelmente
observadoras, decidiram que precisavam experimentar para descobrir. Construíram um labirinto
enorme em escala adequada para um humano. Pegaram um grupo controle de ratos e ensinaram-no a
percorrer um labirinto pequeno atrás de queijo. Depois pegaram pessoas e ensinaram-nas a percorrer o
labirinto grande atrás de notas de cinco dólares. Houve pequenas variações nos dados e – ao nível de
probabilidade de 95% - descobriram algumas diferenças significativas no número de tentativas ao
critério ou algo parecido. Os humanos conseguiram aprender a percorrer o labirinto um pouco melhor,
um pouquinho mais depressa do que os ratos.
De fato, já fazemos isto com freqüência: ao torcer um parafuso, por exemplo, se algo que
fazemos não funciona, fazemos algo diferente: uma chave de fenda maior ou menor, mais força, outra
posição da mão, as duas mãos, algo para colocar no parafuso e diminuir o atrito. Ao dirigir automóveis,
fazemos ajustes todo o tempo no volante (e nem notamos).
A abordagem blitz
“O ser humano é muito melhor aperfeiçoando algo existente do que criando algo do nada”
Paul T. Ward
Da descrição teórica para a execução prática várias coisas podem mudar. O processo de
desenvolver um programa ou algoritmo não é, na grande maioria das vezes, uma linha reta, em que se
passa de uma etapa à outra em seqüência. Isso não ocorre devido somente a limitações do programador,
mas basicamente a causa principal é a falta de informações; nas fases iniciais normalmente não se dispõe
de todas as informações necessárias para elaborar um produto completo. E quanto menos informações,
maior a possibilidade de serem tomadas decisões que depois se revelam inadequadas. Por exemplo,
descobrir que o programa está estruturado incorretamente na etapa de teste normalmente impacta
significativamente o prazo previsto de implementação. O mesmo ocorre quando, já no final da
codificação, se percebe que falta uma solução importante para um aspecto importante ou algoritmo.
Imagine se isso ocorrer na véspera da entrega de um trabalho! Por isso, tão importante quanto uma boa
descrição das etapas a serem seguidas, é dispor de um bom roteiro para executá-las.
Em procedimentos ou atividades executadas em etapas, você pode aplicar a abordagem blitz. Ela
consiste em se fazer uma rápida passagem inicial pelas várias etapas, na qual o objetivo maior é obter
uma visão geral e preliminar, incompleta e não totalmente verificada da questão ou problema. Após, você
faz uma segunda passagem, desta vez em direção ao produto final. Benefícios desta abordagem:
Com uma visão do todo, você identifica mais facilmente as partes cujos detalhes vão requerer
maior atenção
Você tem melhor noção das conseqüências que suas decisões numa etapa vão provocar em
etapas posteriores
Você não perde tempo tentando fazer um produto final desde o início, sendo que talvez não
tenha todas as informações necessárias para isso.
Você não precisa se limitar a duas passagens; de fato você pode fazer quantas forem necessárias.
Uma situação curiosa pode surgir, se em algum momento você perceber que o desenvolvimento não está
avançando: você pode tanto voltar a uma etapa anterior quanto avançar a uma etapa posterior, para obter
informações e amadurecer o seu produto. Por exemplo: ao produzir a primeira ou segunda versão do
algoritmo ou programa, passe logo para a verificação manual.
Uma das melhores fontes de inspiração para elaborar certos algoritmos é seu próprio cérebro:
como você faria? Talvez isso não tenha lhe ocorrido, mas seu cérebro tem algoritmos. Normalmente não
228 APRENDENDO A PROGRAMAR NA PRÁTICA VIRGÍLIO V. VILELA
estamos conscientes deles, e nem precisamos, mas muitas vezes podemos ter algum acesso. Por exemplo,
soletre uma palavra qualquer, digamos, "IMAGEM", enquanto procura observar como faz. Em geral o
algoritmo usado para isso é:
"Produza uma imagem interna da palavra"
"Focalize a primeira letra da palavra"
enquanto "não for o fim da palavra"
"pronuncie a letra focalizada"
"Focalize próxima letra"
fim
Se não conseguir perceber, peça a alguém para soletrar uma palavra e observe seus olhos.
Por exemplo, suponha que você deve elaborar um algoritmo para ordenar um conjunto de
números em ordem crescente. Você pode pegar alguns palitos de tamanho variado, ordená-los enquanto
observa o que faz e daí extrair pistas para o algoritmo. Pode ser que você percorra todos os palitos à
procura do maior e tire-o do conjunto para um outro. Para os que sobraram, repete o procedimento, até
que não haja mais palitos. Essas ações são pistas excelentes para a elaboração do algoritmo.
Considere agora o problema de inverter uma cadeia de caracteres. Por exemplo, dada a cadeia “A
mente é terra”, torná-la “arret é etnem A”. Pegue uma cadeia qualquer e inverta manualmente. Como
você fez? Provavelmente, seguiu os seguintes passos:
"Escolha um local para escrever a cadeia invertida"
"Focalize o último caractere da cadeia"
"Escreva o caractere"
enquanto "houver caracteres não copiados"
"Focalize na cadeia o próximo caractere à esquerda"
"Escreva o caractere focalizado à direita do último escrito"
fim
O algoritmo acima já permite obter algumas pistas: uma variável inteira para apontar cada
caractere da cadeia, uma instrução para obter um caractere apontado, outra para concatenar caracteres (no
Pascal, o +), as instruções que serão repetidas.
Note que pesquisar no próprio cérebro nem sempre irá fornecer o algoritmo com precisão; o que
buscamos são pontos de partida para idéias que serão adaptadas às nossas necessidades.
229
Na tabela estão representados os códigos dos caracteres mais usados (de 32 a 126). Para calcular
cada código, some o número da coluna do caractere com o número da respectiva linha. Por exemplo, o
código da letra T é 80 + 4.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
48 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
64 @ A B C D E F G H I J K L M N O
80 P Q R S T U V W X Y Z [ \ ] ^ _
96 ` a b c d e f g h i j k l m n o
112 p q r s t u v w x y z { | } ~
231
BIBLIOGRAFIA
FORBELLONE, André Luiz V. & EBERSPÄCHER, Henri F. Lógica de Programação. Makron, 1993.
GUIMARÃES, Ângelo M. & LAGES, Newton A. C. Algoritmos e Estruturas de Dados. LTC, 1985.
McMENAMIN, Stephen M. & PALMER, John F. Análise Essencial de Sistemas. Makron, 1991.
MECLER, Ian & Maia, Luiz Paulo. Programação e Lógica com Turbo Pascal. Campus, 1989.
MYERS, Glenford J. The Art of Software Testing. John Wiley & Sons, 1979.
SCHMITZ, Eber Assis & TELES, Antonio A. S. Pascal e Técnicas de Programação. LTC, 1986.
ÍNDICE REMISSIVO