Curso Técnico em Informática
Lógica de Programação
Robson Braga de Andrade Presidente da Confederação Nacional da Indústria
Rafael Lucchesi Diretor do Departamento Nacional do SENAI
Regina Maria de Fátima Torres Diretora de Operações do Departamento Nacional do SENAI
Alcantaro Corrêa Presidente da Federação da Indústria do Estado de Santa Catarina
Sérgio Roberto Arruda Diretor Regional do SENAI/SC
Antônio José Carradore Diretor de Educação e Tecnologia do SENAI/SC
Marco Antônio Dociatti Diretor de Desenvolvimento Organizacional do SENAI/SC
Confederação Nacional da Indústria Serviço Nacional de Aprendizagem Industrial
Curso Técnico em Informática
Lógica de Programação Helenilson Ricardo Kitzberger
Florianópolis/SC 2011
É proibida a reprodução total ou parcial deste material por qualquer meio ou sistema sem o prévio consentimento do editor.
Autor Helenilson Ricardo Kitzberger
Fotografias Banco de Imagens SENAI/SC http://www.sxc.hu/ http://office.microsoft.com/en-us/ images/ http://www.morguefile.com/ http://www.bancodemidia.cni.org.br/
Ficha catalográfica elaborada por Luciana Effting CRB14/937 - Biblioteca do SENAI/SC Florianópolis
K62l
Kitzberger, Helenilson Ricardo Lógica de programação / Helenilson Ricardo Kitzberger. – Florianópolis : SENAI/SC, 2011. 67 p. : il. color ; 28 cm. Inclui bibliografias. 1. Programação (Computadores). 2. Programação lógica. 3. Algoritmos. 4. Estruturas de dados (Computação). I. SENAI. Departamento Regional de Santa Catarina. II. Título. CDU 004.43
SENAI/SC — Serviço Nacional de Aprendizagem Industrial Rodovia Admar Gonzaga, 2.765 – Itacorubi – Florianópolis/SC CEP: 88034-001 Fone: (48) 0800 48 12 12 www.sc.senai.br
Prefácio Você faz parte da maior instituição de educação profissional do estado. Uma rede de Educação e Tecnologia, formada por 35 unidades conectadas e estrategicamente instaladas em todas as regiões de Santa Catarina. No SENAI, o conhecimento a mais é realidade. A proximidade com as necessidades da indústria, a infraestrutura de primeira linha e as aulas teóricas, e realmente práticas, são a essência de um modelo de Educação por Competências que possibilita ao aluno adquirir conhecimentos, desenvolver habilidade e garantir seu espaço no mercado de trabalho. Com acesso livre a uma eficiente estrutura laboratorial, com o que existe de mais moderno no mundo da tecnologia, você está construindo o seu futuro profissional em uma instituição que, desde 1954, se preocupa em oferecer um modelo de educação atual e de qualidade. Estruturado com o objetivo de atualizar constantemente os métodos de ensino-aprendizagem da instituição, o Programa Educação em Movimento promove a discussão, a revisão e o aprimoramento dos processos de educação do SENAI. Buscando manter o alinhamento com as necessidades do mercado, ampliar as possibilidades do processo educacional, oferecer recursos didáticos de excelência e consolidar o modelo de Educação por Competências, em todos os seus cursos. É nesse contexto que este livro foi produzido e chega às suas mãos. Todos os materiais didáticos do SENAI Santa Catarina são produções colaborativas dos professores mais qualificados e experientes, e contam com ambiente virtual, mini-aulas e apresentações, muitas com animações, tornando a aula mais interativa e atraente. Mais de 1,6 milhões de alunos já escolheram o SENAI. Você faz parte deste universo. Seja bem-vindo e aproveite por completo a Indústria do Conhecimento.
Sumário Conteúdo Formativo Apresentação
9
28 Unidade de estudo 3 Estruturas de Seleção
11
12 Unidade de estudo 1 Introdução à Lógica de Programação 13
Seção 1 - Conceitos
14
Seção 2 - Formas de representação
16
Seção 3 - Teste de mesa
16
Seção 4 - Ambiente
20 Unidade de estudo 2 Algoritmos
21
Seção 1 - Tipos de dados
23
Seção 2 - Constantes e variáveis
23
Seção 3 - Expressões
25
Seção 4 - Funções
26
Seção 5 - Atribuição
27
Seção 6 - Comandos de entrada e saída
48 Unidade de estudo 6 Estruturas Heterogêneas
29
Seção 1 - Introdução
49
Seção 1 - Introdução
29
Seção 2 - Comando Se
49
Seção 2 - Registros
31
Seção 3 - Ninhos de comando Se
32
Seção 4 - Comando Escolha
54 Unidade de estudo 1 Funções
34 Unidade de estudo 4 Estruturas de Repetição 35
Seção 1 - Introdução
36
Seção 2 - Comando Enquanto
37
Seção 3 - Comando Repita
38
Seção 4 - Comando Para
40 Unidade de estudo 5 Estruturas Homogêneas 41
Seção 1 - Introdução
42
Seção 2 - Vetores
45
Seção 3 - Matrizes
55
Seção 1 - Introdução
55
Seção 2 - Utilização de subprogramas
56
Seção 3 - Argumentos e parâmetros
57
Seção 4 - Funções
58
Seção 5 - Procedimentos
58
Seção 6 - Âmbito de variáveis
59
Seção 7 - Argumentos de subprogramas
61
Seção 8 - Erros mais comuns
Finalizando
62
Referências
64
8
CURSOS TÉCNICOS SENAI
Conteúdo Formativo Carga horária da dedicação Carga horária: 120 horas
Competências Desenvolver algoritmos e programas utilizando técnicas, lógica e linguagens de programação para soluções computacionais.
Conhecimentos ▪▪ Estruturas de controle e repetição. ▪▪ Estruturas de dados heterogêneas (registros). ▪▪ Estruturas de dados homogêneas (vetores, matrizes). ▪▪ Ferramentas de auxílio à aprendizagem/interpretador de portugol. ▪▪ Fluxogramas. ▪▪ Funções, procedimentos, métodos. ▪▪ Matrizes. ▪▪ Metodologias de testes (teste de mesa). ▪▪ Programação estruturada. ▪▪ Pseudocódigo. ▪▪ Tipos de dados. ▪▪ Variáveis e constantes. ▪▪ Vetores. ▪▪ Operadores aritméticos, relacionais e lógicos, expressões lógicas e aritméticas.
Habilidades ▪▪ Aplicar a lógica de programação. ▪▪ Aplicar linguagens para construção de algoritmos. ▪▪ Estruturar soluções lógicas. ▪▪ Elaborar documentação do algoritmo. ▪▪ Executar testes manuais e automatizados. ▪▪ Aplicar abstração.
LÓGICA DE PROGRAMAÇÃO
9
Atitudes ▪▪ Organização e zelo na utilização de equipamentos. ▪▪ Foco no conteúdo trabalhado. ▪▪ Acesso a sítios relacionados ao tema trabalhado. ▪▪ Organização e limpeza dos ambientes coletivos. ▪▪ Dedicação e empenho nas atividades curriculares e extracurriculares. ▪▪ Capacidade de abstração. ▪▪ Trabalho em equipe. ▪▪ Apresentação de novas soluções para situações-problema. ▪▪ Cumprimento de prazos. ▪▪ Análise crítica de suas produções.
10
CURSOS TÉCNICOS SENAI
Apresentação Seja bem-vindo à unidade curricular de Lógica de Programação! O objetivo principal é demonstrar técnicas para a resolução de problemas e, consequentemente, automatização de tarefas. Você sabia que o aprendizado da lógica é essencial para a formação de um bom programador? É verdade. E os conhecimentos sobre lógica servirão de base para o aprendizado de todas as linguagens de programação, estruturadas ou não. De um modo geral, esses conhecimentos serão de suma importância, pois ajudarão no cotidiano para o desenvolvimento de um raciocínio rápido. Nesta unidade curricular você estudará os conceitos básicos de lógica de programação, as formas de representação e, principalmente, os algoritmos, que auxiliam na estruturação de uma sequência lógica para resolução de problemas e automatização de tarefas. Você irá aprender de que forma utilizamos os algoritmos para a tomada de decisões, repetições e manipulação de informações. Esperamos que, por meio desse conteúdo, você conheça em detalhes o que é e como aplicar a lógica de programação em sua vida profissional. Bons estudos!
Helenilson Ricardo Kitzberger Helenilson Ricardo Kitzberger é graduado em Sistemas de Informação pelo Centro Universitário de Jaraguá do Sul. Atualmente trabalha como analista de sistemas e também é proprietário de uma empresa de desenvolvimento de software para gestão empresarial. Atua também como pesquisador e professor no SENAI de Jaraguá do Sul, onde ministra aulas no curso Técnico em Informática.
LÓGICA DE PROGRAMAÇÃO
11
Unidade de estudo 1 Seções de estudo Seção 1 – Conceitos Seção 2 – Formas de representação Seção 3 – Teste de mesa Seção 4 – Ambiente
Introdução à Lógica de Programação Seção 1 Conceitos
Você já ouviu falar em lógica de programação, sequência lógica, instruções, algoritmos e programas? Esses são alguns dos conceitos elementares de lógica que você verá a seguir. Em relação aos algoritmos, você verá que, relacionados à lógica, eles resultam em programação. Vamos iniciar? Aperte os cintos e embarque no mundo da lógica de programação!
Lógica de programação Para Forbellone e Eberspächer (2005, p. 12), a lógica pode ser relacionada com a “correção do pensamento”. Correção de pensamento? Isso mesmo! Uma de suas preocupações é determinar quais operações são válidas e quais não são, fazendo análises das formas e leis do pensamento.
A lógica de programação significa o uso correto das leis do pensamento e de processos de raciocínio e simbolização formais na programação de computadores, objetivando a racionalidade e o desenvolvimento de técnicas que cooperem para a produção de soluções logicamente válidas e coerentes, que resolvam com qualidade os problemas que se deseja programar.
A lógica de programação é necessária para pessoas que desejam trabalhar com o desenvolvimento de sistemas e programas. Ela permite definir a sequência lógica para o desenvolvimento. Lógica de programação é a técnica de encadear pensamentos para atingir determinado objetivo.
E sequência lógica, você sabe o que é? Então acompanhe!
Sequência lógica Os pensamentos que você estudou na lógica de programação podem ser descritos como uma sequência de instruções, que devem ser seguidas para cumprir uma determinada tarefa. Sequência lógica são passos executados até atingir um objetivo ou solução de um problema.
Em informática, porém, instrução é a informação que indica a um computador uma ação elementar a executar. Convém ressaltar que uma ordem isolada não permite realizar o processo completo. Para isso, é necessário um conjunto de instruções colocadas em ordem sequencial lógica. Por exemplo, para fazer uma omelete de batatas, é preciso colocar em prática uma série de instruções: descascar as batatas, bater os ovos, fritar as batatas etc. É evidente que essas instruções precisam ser executadas em uma ordem adequada – não se pode descascar as batatas depois de fritá-las. Dessa maneira, uma instrução tomada de forma isolada não tem muito sentido. Para se obter o resultado, é preciso colocar em prática o conjunto de todas as instruções, na ordem correta.
Instruções Na linguagem comum, entende-se por instruções um conjunto de regras ou normas definidas para a realização ou emprego de algo.
Instruções são um conjunto de regras ou normas definidas para a realização ou emprego de algo. Em informática, é o que indica a um computador uma ação elementar a executar.
LÓGICA DE PROGRAMAÇÃO
13
Algoritmos Um algoritmo é formalmente uma sequência finita de passos que levam à execução de uma tarefa. É possível pensar em algoritmo como uma receita, uma sequência de instruções que dão cabo de uma meta específica. Essas tarefas não podem ser redundantes nem subjetivas na sua definição. Elas devem ser claras e precisas. Como exemplos de algoritmos existem os algoritmos das operações básicas (adição, multiplicação, divisão e subtração) de números reais decimais. Outros exemplos seriam os manuais de aparelhos eletrônicos, que explicam passo a passo como utilizá-los. Até mesmo as coisas mais simples podem ser descritas por sequências lógicas. Vamos a um exemplo: como chupar bala. Observe!
▪▪ ▪▪ ▪▪ ▪▪
Os programas de computadores nada mais são do que algoritmos escritos em uma linguagem de computador (Pascal, C, Cobol, Fortran, Visual Basic, entre outras) e que são interpretados e executados por uma máquina; no caso, um computador. Com essa interpretação rigorosa, um programa é, por natureza, muito específico e rígido em relação aos algoritmos da vida real. Com esses conceitos, certamente agora você estará pronto para seguir para a próxima seção. Vamos lá!
Seção 2
Formas de representação
Retirar o papel.
As formas mais comuns de representação de algoritmos são as seguintes. Acompanhe!
Chupar a bala.
▪▪ Descrição narrativa: os algo-
Pegar a bala.
Jogar o papel no lixo.
Algoritmo é a descrição de um conjunto de ações que, obedecidas, atingem o objetivo esperado.
Segundo Lopes e Garcia (2002), algoritmo não é a solução de um problema, pois, se assim fosse, cada problema teria um único algoritmo. Algoritmo é um conjunto de passos que levam à solução de um determinado problema e, em geral, são muitos os caminhos que levam à solução.
14
Programas
CURSOS TÉCNICOS SENAI
ritmos são expressos diretamente em linguagem natural.
▪▪ Fluxograma convencional: é
uma representação gráfica que emprega formas geométricas padronizadas para indicar as diversas ações e decisões que devem ser executadas para resolver o problema.
▪▪ Pseudolinguagem: emprega uma linguagem intermediária entre a linguagem natural e uma linguagem de programação para descrever os algoritmos.
Mas veja bem! Não existe consenso entre os especialistas sobre qual seria a melhor maneira de representar um algoritmo. Atualmente, a maneira mais comum de representar algoritmos é por meio de uma pseudolinguagem ou pseudocódigo. Essa forma de representação tem a vantagem de fazer com que o algoritmo seja escrito de uma maneira próxima de uma linguagem de programação de computadores.
Descrição narrativa Como ilustração de algoritmo em linguagem natural, considera a seguinte receita. Providencie manteiga, ovos, 2 Kg de massa etc.
▪▪ Misture os ingredientes. ▪▪ Despeje a mistura na forma
de bolo.
▪▪ ▪▪ ▪▪ ▪▪ ▪▪
Leve a forma ao forno. Espere 20 minutos. Retire a forma do forno. Deixe esfriar. Prove.
Essa forma de representação é bastante conhecida, por utilizar a linguagem natural, porém tem algumas desvantagens, como imprecisão, pouca confiabilidade e principalmente ser extensa, pois escreve-se muito para dizer pouca coisa.
Fluxograma convencional Essa representação de algoritmos emprega várias formas geométricas para descrever cada uma das possíveis ações durante a execução dos algoritmos. Existem algumas formas geométricas empregadas normalmente e que você poderá ver na figura seguinte. Cada uma das formas se aplica a uma determinada ação, como está indicado. Existem outras formas que podem ser aplicadas, no entanto, essas formas serão suficientes para os exemplos que serão mostrados nesta unidade curricular.
Figura 1: Formas geométricas
Como primeiro exemplo de um algoritmo descrito por meio de fluxogramas, considere o exemplo do algoritmo para decidir o que fazer em um dia de domingo. Veja a próxima figura!
Figura 2: Fluxograma de um domingo
LÓGICA DE PROGRAMAÇÃO
15
A representação gráfica por meio de fluxograma é uma das ferramentas mais conhecidas na representação de algoritmos, utiliza um padrão mundial e diz muito mais do que palavras. Porém, sua utilização reflete em pouca atenção aos dados, não oferecendo recursos para descrevê-los, e complica-se na medida em que o algoritmo cresce. Você sabe o que é uma pseudolinguagem? Vamos descobrir juntos!
Pseudolinguagem Esse modo de representar algoritmos procura empregar uma linguagem que esteja o mais próxima possível de uma linguagem de programação de computadores de alto nível, mas evitando definir regras de construção gramatical muito rígidas. A ideia é usar as vantagens do emprego da linguagem natural, mas restringindo o escopo da linguagem. Normalmente, essas linguagens são versões ultrarreduzidas de linguagens de alto nível do tipo Pascal ou C. Ficou mais claro agora? Então veja a seguir um exemplo de pseudolinguagem. algoritmo“CALCULA_DOBRO” var varNum, varDobro : inteiro inicio leia (varNum) varDobro ← 2 * varNum Escreva (varDobro) fimalgoritmo
16
CURSOS TÉCNICOS SENAI
O uso da pseudolinguagem, ou linguagem algorítmica, tem inúmeras vantagens, como utilização do português como base e a passagem quase imediata do algoritmo para uma linguagem de programação qualquer. No entanto, não tem padrão definido, dificultando a leitura em alguns momentos.
Seção 3
Teste de mesa Após desenvolver um algoritmo é preciso testá-lo. Esse teste é chamado de TESTE DE MESA, que significa seguir as instruções do algoritmo de maneira precisa para verificar se o procedimento utilizado está correto ou não. Mas como esse teste deve ser feito? Veja na tabela seguinte um exemplo de teste de mesa que valida o algoritmo CALCULA_DOBRO, apresentado na seção anterior.
Seção 4 Ambiente
O computador Os computadores podem ser usados de forma eficiente na solução de certos tipos de problemas. Os problemas que suportam tratamento por computador em geral envolvem grandes quantidades de dados ou são problemas de natureza complexa, exigindo a execução de um grande número de passos para alcançar a solução. Basicamente, são problemas na área de processamento de dados e na área científica.
Tabela 1: Teste de mesa
varNum
varDobro
2
4
6
12
Nesse exemplo deve-se atribuir valores a “varNum”, executar o cálculo descrito no algoritmo e avaliar se “varDobro” vai resultar como na tabela anterior.
O computador é uma ferramenta que permite a realização do processamento automático (ou eletrônico) de dados.
Mas o que é processamento de dados? Define-se por processamento de dados qualquer atividade que, utilizando informações (ou dados), efetua transformações para obter novas informações (ou dados) como resultado.
Figura 3: Processamento de dados
Porém, a tarefa desempenhada pelos computadores é apenas parte do processo de solução de problemas. As etapas na solução de problemas são:
▪▪ entendimento do problema; ▪▪ criação de uma sequência de operações (ou ações) que, quando exe-
cutadas, produzem a solução para o problema;
▪▪ execução dessa sequência de operações; ▪▪ verificação da adequação da solução. As etapas de entendimento do problema, criação de sequência de ações e verificação da adequação da solução são tarefas desempenhadas por pessoas. Já a execução das operações pode ser desempenhada por computadores. Os computadores têm a capacidade de executar processos complicados e com grande quantidade de informações de forma rápida e confiável.
Programação Programação é a sequência de planejamento, projeto, escrita e testes de instruções desempenhados pelo computador. É uma arte e uma ciência. Arte porque existem muitas maneiras de se realizar o trabalho de programação. Existe espaço para uma considerável dose de criatividade. É também uma ciência, porque existem algumas regras que devem ser seguidas, porque é necessário o uso de lógica e porque existem alguns métodos rigorosos de programação que asseguram a eficiência, economia e a utilidade dos programas gerados. Para tornar o trabalho de programação mais fácil, divida sistematicamente em partes menos complexas (essa técnica denomina-se “dividir para conquistar”). E você sabe quando um programa é confiável?
Um programa é considerado confiável quando consegue fazer com que o computador cumpra com o objetivo proposto. Os programas construídos devem ser eficazes, realizando a tarefa definida de forma eficiente, utilizando os melhores meios para realizá-la. O maior problema na construção de programas é a complexidade. Essa complexidade representa a quantidade de situações diferentes que um problema pode apresentar e que devem ser previstas na solução do mesmo. Portanto, ao se construir um programa, o objetivo principal é vencer a complexidade do problema a ser solucionado.
LÓGICA DE PROGRAMAÇÃO
17
Mas o que fazer para trabalhar com essa complexidade?
Você poderá dividir a programação em duas fases distintas. Acompanhe!
Figura 4: Fases da programação
Para a fase da programação você terá as seguintes etapas:
▪▪ Modelização (ou resolução) do problema: determinação do modelo de solução para o problema proposto na forma de um algoritmo computacional. Assim, a elaboração de um algoritmo é o primeiro passo para a preparação de um programa de computador. Esse algoritmo deve ser independente da linguagem de programação que será utilizada. ▪▪ Implementação: é a transformação (ou codificação) do algoritmo
em alguma linguagem de programação adequada ao modelo elaborado. Linguagem de programação? O que é isso? Veja a seguir!
Linguagens de programação Linguagem é uma maneira de comunicação que segue uma forma e uma estrutura com significado interpretável. Portanto, linguagem de programação é um conjunto finito de palavras, comandos e instruções, escritos com o objetivo de orientar a realização de uma tarefa pelo computador. Logicamente, a linguagem utilizada pelos indivíduos no cotidiano é diferente da linguagem utilizada pela máquina. A máquina trabalha somente com códigos numéricos (linguagem de máquina), baseados nos números 0 e 1 (sistema binário), que representam impulsos elétricos, ausente e presente. Assim, qualquer linguagem de programação deve estar situada entre dois extremos: o da linguagem natural do homem (muito clara, porém lenta) e o da linguagem de máquina (muito rápida, porém complexa).
18
CURSOS TÉCNICOS SENAI
Esse é o conceito de nível de linguagem: alto nível para as mais próximas da linguagem humana; baixo nível para as mais semelhantes à linguagem de máquina.
Tradutores Para que um computador possa “entender” um programa escrito em uma linguagem de alto nível, torna-se necessário um meio de tradução entre a linguagem utilizada no programa e a linguagem de máquina. Esse meio pode ser de dois tipos: compilador e interpretador. Saiba mais sobre cada um deles!
Compilador Traduz o programa escrito em linguagem de alto nível (programa-fonte) para um programa equivalente escrito em linguagem de máquina (programa-objeto).
Interpretador Traduz e envia para execução instrução por instrução e o programa permanece na forma de fonte.
Aqui você finaliza a primeira unidade do curso, onde conheceu conceitos de lógica de programação, sequência lógica, instruções, algoritmos e programas. Viu que os algoritmos podem ser representados por descrição narrativa, fluxograma convencional e pseudolinguagem, além do teste de mesa e do ambiente. Agora você está pronto para seguir para a próxima etapa: o estudo da seção seguinte, cujo tema será algoritmos. Então, reúna motivação e comprometimento e vá em busca de novos saberes!
LÓGICA DE PROGRAMAÇÃO
19
Unidade de estudo 2 Seções de estudo Seção 1 – Tipos de dados Seção 2 – Constantes e variáveis Seção 3 – Expressões Seção 4 – Funções Seção 5 – Atribuição Seção 6 – Comandos de entrada e saída
Algoritmos Seção 1
Tipos de dados Como você já estudou, um algoritmo é constituído de uma sequência de instruções a serem seguidas para a obtenção de soluções a algum problema. Nessa solução, são manipulados diversos dados. Esses dados podem ser os apresentados pelo problema – os dados intermediários – que são gerados durante a execução do algoritmo, ou os dados que representam a solução do problema. Com isso, pode-se concluir que os dados manipulados dentro de um algoritmo podem ser classificados em vários tipos, com suas características e operações. Cada linguagem de programação tem sua própria classificação.
Inteiro Toda e qualquer informação numérica que pertença ao conjunto dos números inteiros (negativo, nulo ou positivo). Exemplos: 39; 0; -56 entre outros.
Real Toda e qualquer informação numérica que pertença ao conjunto dos números reais (negativo, nulo ou positivo, inteiro ou fracionário). Exemplos: -4, 3; 0, 35; 1,23
Caractere São caracterizadas como tipos caracteres as sequências contendo letras, números e símbolos especiais. Uma sequência de caracteres deve ser indicada entre aspas (“ ”). Esse tipo de dado é também conhecido como alfanumérico, string, literal ou texto. Exemplos: “Rua Alfa, 52 Apto 1”; “Fone: 3276-9988”; “04387-456”; “ “; “7”.
Lógico Todo dado a ser tratado em um algoritmo deve pertencer a algum tipo, que irá determinar o domínio de seu conteúdo. Os tipos mais comuns de dados são conhecidos como tipos primitivos de dados. São eles: inteiro, real, caractere e lógico. Quer saber o que cada um deles representa? Vamos adiante!
São caracterizados como tipos lógicos os dados com valores verdadeiros e falsos, sendo que podem representar apenas um desses dois valores. Ele é chamado por alguns de tipo booleano, devido à contribuição do filósofo e matemático inglês George Boole na área da lógica matemática. A tabela que você verá a seguir resume os tipos de dados mais comuns e sua definição nas linguagens utilizadas no decorrer do material. Veja! Tabela 2: Tipos de dados
Tipo
Exemplo
VisuAlg
Java
Inteiro
2 | 45 | 100
inteiro
int
Real
2,456 | 101,19
real
float
Caractere
“A” | “4” | “Teste”
caractere
char / string
Lógico
Verdadeiro | Falso
logico
true / false
LÓGICA DE PROGRAMAÇÃO
21
Seção 2
Constantes e variáveis
Uma variável é composta por dois elementos básicos:
▪▪ conteúdo: valor da variável e
identificador;
Constantes Constante é um determinado valor fixo que não se modifica ao longo do tempo durante a execução de um programa. Conforme o seu tipo, a constante é classificada como sendo inteira, real, caractere e lógica. Exemplo: constPI = 3.14
Variáveis Variável é um objeto (uma posição frequentemente localizada na memória), capaz de armazenar um valor ou expressão. As variáveis só “existem” em tempo de execução, sendo associadas a “nomes”, chamadas identificadores, durante a criação dos algoritmos. Em relação à variável, estamos tratando de uma região de memória (do computador) previamente identificada, cuja finalidade é armazenar os dados ou informações de um programa por um determinado espaço de tempo. Para que você entenda melhor, pense que a memória do computador se organiza tal qual um armário com várias divisões. Cada divisão é identificada por um endereço diferente em uma linguagem que o computador entende. Assim, o computador armazena os dados nessas divisões, sendo que em cada divisão só é possível armazenar um dado e, toda vez que o computador armazenar um dado em uma dessas divisões, o dado que antes estava armazenado é eliminado. Mas lembre-se de que o conteúdo pode ser alterado, mas somente um dado pode ser armazenado por vez naquela divisão.
22
CURSOS TÉCNICOS SENAI
▪▪ nome: dado à variável para possibilitar sua utilização e localização. O conteúdo de uma variável pode ser de vários tipos: inteiro, real, caractere ou lógico, entre outros. Normalmente, quando se ensina algoritmo, trabalha-se com os quatro tipos citados. Uma vez definidos o nome e o tipo de uma variável, não será possível alterá-los no decorrer do algoritmo. Por outro lado, o conteúdo de uma variável é um objeto de constante modificação no decorrer do programa, de acordo com o fluxo de execução do mesmo. Em algoritmos, as variáveis serão definidas no início, por meio de um comando definido conforme o exemplo seguinte. algoritmo “CALCULA_DOBRO” var varNum, varDobro : inteiro inicio fimalgoritmo
Existem duas variáveis declaradas. Uma é a “varNum” e a outra é a “varDobro”, ambas possuindo o mesmo tipo de dado, no caso inteiro. Como pode ser visto, “varNum” e “varDobro” são os nomes das variáveis, e é por meio desses nomes que é possível alterar e resgatar o valor presente nela.
Quer saber o que são variáveis globais e variáveis locais? Então vá em frente para saber mais!
Variáveis globais Uma variável global é uma variável acessível em todos os escopos de um algoritmo. O mecanismo de interação com variáveis globais é chamado ambiente global. Mas fique atento! O uso de variáveis globais é geralmente considerado inadequado, pois seu conteúdo pode ser potencialmente modificado de qualquer local e qualquer parte de um código pode depender dele.
Variáveis locais Variáveis locais são aquelas declaradas no início de um subalgoritmo. São visíveis, ou seja, podem ser utilizadas somente pelo subalgoritmo onde foram declaradas. Outros subalgoritmos ou mesmo o algoritmo principal não pode utilizá-la. Variáveis locais somente permanecem válidas durante a execução da função ou procedimento e, em seguida, são reinicializadas em zero.
Cada vez que a função é chamada, os valores gerados anteriormente não estão disponíveis. E você sabe qual a diferença entre constantes e variáveis? Acompanhe!
Constantes X variáveis A diferença primordial entre esses dois conceitos é que constantes são valores inalterados e variável é uma entidade capaz de manifestar diferenças em valor. Diz-se que a variável possui qualquer valor dentro de um campo determinado. Atua como uma “gaveta”, onde se pode guardar qualquer valor, desde que o tipo seja respeitado.
Seção 3 Expressões
Para que você entenda melhor, é possível ligar o conceito de expressão ao conceito de expressão (ou fórmula) matemática, onde um conjunto de variáveis e constantes numéricas relaciona-se por meio de operadores, compondo uma fórmula que, uma vez avaliada, resulta em um valor. As expressões dividem-se em:
▪▪ aritméticas; ▪▪ relacionais; ▪▪ lógicas. Saiba o que significa cada uma delas.
Aritméticas Expressões aritméticas são aquelas que apresentam como resultado um valor numérico que pode ser um número inteiro ou real, dependendo dos operandos e operadores. Observe os operadores aritméticos na tabela seguinte.
Tabela 3: Operadores aritméticos
Operadores
Simbologia
Prioridade
+
3
Subtração
-
3
Multiplicação
*
2
Divisão
/
2
Módulo
%
2
Exponenciação
^
1
Radiciação
//
1
Soma
Mas o que representa a prioridade? A prioridade indica a ordem em que cada operação deverá ser executada. Quanto menor o número, maior a prioridade da operação. Observe que o operador de multiplicação é o caractere asterisco, um símbolo que é empregado na maioria das linguagens para essa operação. Expressões aritméticas podem manipular operandos de dois tipos: reais e inteiros. Se todos os operandos de uma expressão são do tipo inteiro, então a expressão fornece como resultado um número inteiro. Caso pelo menos um dos operandos seja real, o resultado será real. Isso pode parecer estranho a princípio, mas esse procedimento reflete a forma como as operações são executadas pelos processadores. Por exemplo, o resultado da operação 1/5 é 0, porque os dois operadores são inteiros. Caso a expressão tivesse sido escrita como 1.2/5, o resultado 0.24 seria o correto. A seguir temos exemplos de algumas expressões aritméticas. Confira!
▪▪ A + B - C ▪▪ A / B ▪▪ 3.14 * (A + B)
Um ponto importante é a ordem de avaliação das expressões. As prioridades que você viu na tabela anterior não são suficientes para resolver todas as situações. Para isso, você precisa conhecer algumas regras adicionais. Veja a seguir!
▪▪ Deve-se observar primeiro a prioridade dos operadores, conforme a tabela anterior. Ou seja, operadores com maior prioridade (números menores) são avaliados primeiramente. Caso haja empate na ordem de prioridade, deve-se resolver a expressão da esquerda para a direita. ▪▪ Parênteses servem para mudar
a ordem de prioridade de execução das operações. Quando houver parênteses dentro de parênteses, as expressões dentro dos mais internos são avaliadas primeiro.
Ficou claro até aqui? Para entender melhor, observe alguns exemplos que mostram como essas regras são aplicadas. Considere as seguintes variáveis:
▪▪ A = 2 ▪▪ B = 4 ▪▪ C = 1
LÓGICA DE PROGRAMAÇÃO
23
Vamos então analisar expressões com essas variáveis e seus resultados.
▪▪ ▪▪ ▪▪ ▪▪
A*B-C A * (B - C) B+A/C+5 (B + A) / (C + 5)
A primeira expressão tem como resultado o valor 7, como era de se esperar. Na segunda expressão, a ordem de avaliação foi alterada pelos parênteses e primeiro é feita a subtração e o resultado passa a ser 6. A primeira operação na terceira expressão é a divisão que tem maior prioridade. Nesse caso, o resultado final é 11. Na última expressão as somas são realizadas primeiro e, por último, a divisão, ficando o resultado igual a 1.
Para entender melhor, considere alguns exemplos que mostram como é possível utilizar os operadores relacionais. Considere as seguintes variáveis:
▪▪ Não: uma expressão “não» inverte o valor da expressão ou condição; se verdadeira, inverte para falsa e vice-versa.
▪▪ A = 5 ▪▪ B = 3
tem resultado verdadeiro se seus dois operandos lógicos forem diferentes e falso, se forem iguais. Os resultados das operações lógicas são sempre valores lógicos (verdadeiro ou falso). Para trabalharmos adequadamente com operadores lógicos, temos que conhecer a tabela verdade para cada um dos operadores. Tabela verdade? Isso mesmo! Uma tabela verdade é o conjunto de todas as possibilidades combinatórias entre os valores das variáveis lógicas, conforme você verá nas tabelas seguintes.
Vamos então analisar as expressões com essas variáveis e seus resultados. Tabela 5: Expressões com variáveis e resultados
Expressão
Resultado
A=B
Falso
A <> B
Verdadeiro
A>B
Verdadeiro
A
Falso
A >= B
Verdadeiro
A <= B
Falso
▪▪ Xou: Uma expressão “xou”
Tabela 7: Exemplo de tabela verdade
Lógicas
Relacionais As expressões relacionais são utilizadas para comparar caracteres e números. Os valores a serem comparados podem ser literais ou variáveis. Esses operadores sempre retornam valores lógicos (verdadeiro ou falso). Para estabelecer prioridades no que diz respeito a qual operação executar primeiro podem ser utilizados os parênteses, conforme mostrado anteriormente. Observe os operadores relacionais disponíveis na tabela seguinte. Tabela 4: Operadores relacionais
Descrição
Simbologia
Igual a
=
Diferente de
<>
Maior que
>
Menor que
<
Maior ou igual a
>=
Menor ou igual a <=
24
CURSOS TÉCNICOS SENAI
As expressões lógicas servem para combinar resultados de expressões, retornando se o resultado final é verdadeiro ou falso. Veja quais são os operadores lógicos a seguir. Tabela 6: Operadores lógicos
Descrição
Simbologia
A
B
AeB
F
F
F
F
V
F
V
F
F
V
V
V
A
B
A ou B
F
F
F
F
V
V
V
F
V
V
V
E
e
V
Ou
ou
A
B
A xou B
Não
nao
F
F
F
Xou
xou
F
V
V
V
F
V
V
V
F
Puxa! Quantos dados, não é mesmo? Saiba o que cada um significa.
▪▪ E: uma expressão “e” é verda-
deira se todas as condições forem verdadeiras.
▪▪ Ou: uma expressão “ou” é
verdadeira se pelo menos uma condição for verdadeira.
A
nao A
F
V
V
F
Veja agora uma tabela com todos os valores possíveis criados pelos três operadores lógicos.
Tabela 8: Resultados das operações lógicas
Primeiro valor
Operador
Segundo valor
Resultado
Verdadeiro
e
Verdadeiro
Verdadeiro
Verdadeiro
e
Falso
Falso
Falso
e
Verdadeiro
Falso
Falso
e
Falso
Falso
Verdadeiro
ou
Verdadeiro
Verdadeiro
Verdadeiro
ou
Falso
Verdadeiro
Falso
ou
Verdadeiro
Verdadeiro
Falso
ou
Falso
Falso
Verdadeiro
nao
Falso
Falso
nao
Verdadeiro
Seção 4 Funções
O conceito de função está intimamente ligado ao conceito de função (fórmula) matemática, onde um conjunto de variáveis e constantes numéricas relaciona-se por meio de operadores, compondo uma fórmula que, uma vez avaliada, resulta em um valor. Na verdade, as funções ajudam a reduzir a quantidade de expressões dentro de um algoritmo, já que em uma única linha é possível obter resultado de uma fórmula matemática que poderia resultar em muitas linhas. E você sabia que existem vários tipos de funções? É verdade! Entre elas, podem ser destacadas as seguintes.
▪▪ Numéricas: são aquelas cujo resultado da avaliação é do tipo numérico, seja ele inteiro ou real. Somente podem ser efetuadas entre números propriamente apresentados ou variáveis numéricas. ▪▪ Caractere: são aquelas cujo resultado da avaliação é do tipo caractere. Somente podem ser efetuadas entre caracteres propriamente apresentados ou variáveis literais do tipo caractere. ▪▪ Conversão de tipos: são aquelas que convertem valores numéricos de um determinado tipo para outro valor numérico de outro tipo. Entre esses tipos é possível encontrar diversas funções matemáticas, descritas conforme a próxima tabela.
LÓGICA DE PROGRAMAÇÃO
25
Tabela 9: Operadores matemáticos
Função
Resultado
sen (x)
Seno de x
cos (x)
Cosseno de x
tg (x)
Tangente de x
arcsen (x)
Arco cujo seno é x
arccos (x)
Arco cujo cosseno é x
arctg (x)
Arco cuja tangente é x
abs (x)
Valor absoluto (módulo) de x
int (x)
A parte inteira de x
frac (x)
A parte fracionária de x
ard (x)
Arredondamento de x
rnd (x)
Valor randômico de x
Um ponto importante é que as funções matemáticas variam conforme a linguagem de programação utilizada.
DICA Portanto, uma dica é avaliar a equivalência dos comandos apresentados anteriormente com o da linguagem escolhida.
Seção 5 Atribuição
Como o próprio nome diz, um comando de atribuição permite fornecer um valor a uma variável (guardar um objeto em uma gaveta), em que o tipo do dado deve ser compatível com o tipo da variável. Isto é, somente podemos atribuir um valor lógico a uma variável capaz de comportá-lo, ou seja, uma variável declarada como sendo do tipo lógico. Veja um exemplo de algoritmo utilizando o comando de atribuição (←). algoritmo “CALCULA_DOBRO” var varNum, varDobro : inteiro inicio varNum ← 3 + 3 varDobro ← 2 * varNum fimalgoritmo
26
CURSOS TÉCNICOS SENAI
Nesse exemplo, o resultado final (valor) da variável “varDobro” será 12. No computador, no momento em que temos uma atribuição, o espaço em memória que já estava alocado para as variáveis “varNum” e “varDobro”, porém vazio, receberá o valor das expressões. Nos comandos em que o valor a ser atribuído à variável é representado por uma expressão aritmética ou lógica, esta deve ser resolvida em primeiro lugar, para que depois o resultado possa ser armazenado na variável.
Seção 6
Comandos de entrada e saída Um comando de entrada (leitura) tem por função transferir dados do meio externo para a memória de trabalho do computador. Os dados do meio externo, na maioria das vezes, entram em nosso computador por meio do teclado. Vamos a mais um exemplo? Veja um algoritmo exemplificando o comando de entrada de dados. algoritmo “CALCULA_DOBRO” var varNum, varDobro : inteiro inicio leia (varNum) fimalgoritmo
Nesse exemplo fazemos com que o computador aguarde que um valor seja digitado. Após, ele efetua um cálculo e, por fim, exibe o resultado desse cálculo armazenado na variável “varDobro” na tela do computador. Mais uma etapa cumprida e quanto conhecimento novo, não é mesmo? Nesta unidade você aprendeu sobre os algoritmos, os tipos de dados, constantes e variáveis, viu o que são as expressões, as funções, a atribuição e os comandos de entrada e saída. Foi um estudo muito interessante, não é mesmo? E não para por aí. Na próxima unidade você estudará sobre estruturas de seleção. Lembre-se de buscar novas informações sobre os temas estudados e praticar. Em frente!
Como você pode ver nesse exemplo, é possível fazer com que o computador fique aguardando que um valor seja digitado. O valor digitado será armazenado na variável “varNum”. Ao contrário de um comando de entrada, um comando de saída é utilizado quando necessitamos apresentar valores ao meio externo. Os valores são comumente apresentados na tela do computador. A seguir, você verá um algoritmo exemplificando o comando de saída de dados “escreva”: algoritmo “CALCULA_DOBRO” var varNum, varDobro : inteiro inicio leia (varNum) varDobro ← 2 * varNum escreva (varDobro) fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
27
Unidade de estudo 3 Seções de estudo Seção 1 – Introdução Seção 2 – Comando Se Seção 3 – Ninhos de comando Se Seção 4 – Comando Escolha
Estruturas de Seleção Seção 1
Introdução Para iniciar o estudo, é importante ressaltar que existem problemas que podem ter mais de um caminho para serem resolvidos em uma seleção correta. Muitas vezes também podem existir restrições nas soluções. Portanto, para executar o algoritmo, em dado momento é preciso tomar a decisão do caminho que deverá ser seguido para chegar à solução correta para o problema. A decisão do caminho a ser seguido precisa estar fundamentada em alguma lógica. E é função de quem escreve o algoritmo dar condições para o sujeito que o executa fazer a escolha correta do caminho para se chegar à solução do problema. Um exemplo simples de problema que pode ter metodologias diferentes em sua solução são os cálculos das raízes de equações polinomiais de 2° grau (ax2 + bx + c = 0). Se o termo b2 – 4ac for maior ou igual a zero, as raízes serão reais. Caso contrário, serão complexas. Não seria correto escrever um algoritmo que resolvesse somente a parte de raízes reais ou a parte complexa, pois a metodologia que vai ser usada somente será conhecida na execução do algoritmo. Logo, é preciso descrever a solução por ambas as metodologias, mas deixando claro para quem irá executá-la que será preciso fazer uma escolha entre os caminhos possíveis.
Mas se deixássemos a critério de quem executa o algoritmo, será que ele sempre escolheria o caminho correto? Não se pode arriscar. Por isso, além de saber que existe mais de um caminho para a solução do problema, é preciso prover subsídios para que o mesmo faça a escolha do caminho correto. Assim, o simples fato de informar que a solução do problema tem duas ou mais metodologias diferentes em sua solução não funcionaria. É preciso dizer em quais situações ele utilizará a metodologia A e quando utilizará a B. No caso das raízes de polinômio de 2° grau, é possível utilizar a seguinte descrição narrativa:
▪▪ se o resultado de b2 – 4ac for
maior ou igual a zero:
▪▪ então utilize a metodologia de cálculo de raízes reais; ▪▪ caso contrário, utilize a
metodologia de cálculo de raízes complexas. Até agora, os algoritmos seguiram um mesmo padrão: entrava-se com dados, que eram processados e alguma informação era mostrada na tela.
Dessa forma, o computador mais parecia uma máquina de calcular. O aprendizado de novos conceitos, como a estrutura de seleção, dará uma visão maior da complexidade de tarefas que ele poderá executar. E que tal agora refletir sobre a importância dessa estrutura? Para isso, leia com atenção as afirmativas seguintes:
▪▪ Distribuição gratuita de cestas básicas. ▪▪ Distribuição gratuita de cestas básicas para as famílias com quatro ou mais componentes. ▪▪ Distribuição gratuita de ingressos para o teatro, sendo dois para pessoas do sexo feminino e um para pessoas do sexo masculino. O que você pôde concluir com essas afirmações? ▪▪ Na primeira, todas as pes-
soas recebem a cesta básica, o que equivaleria a um comando sequencial.
▪▪ Na segunda, só recebem as cestas básicas as famílias com pelo menos quatro integrantes. ▪▪ Na terceira, dependendo do sexo, recebe-se um ou dois ingressos.
LÓGICA DE PROGRAMAÇÃO
29
Assim, é possível avaliar a importância do teste nas duas últimas afirmativas, pois ações diferentes são executadas de acordo com o resultado.
Seção 2
Comando Se É muito comum ver situações em programação, assim como na prática, em que se decide por um ou por outro procedimento, de acordo com certas condições. Por exemplo, ao dizer “SE estiver chovendo ENTÃO leve um guarda-chuva”. Certamente você já passou por alguma situação como essa, certo? Observe um exemplo de seleção simples.
Figura 5: Exemplo de seleção simples
A figura anterior significa que certa ação (levar o guarda-chuva) deverá ser tomada se a condição (estar chovendo) for verdadeira. Caso contrário, a ação não será realizada. Em alguns casos, especifica-se também o que deverá ser feito caso a condição não se cumpra, onde: “SE a piscina estiver livre ENTÃO faça natação, CASO CONTRÁRIO faça uma caminhada”.
30
CURSOS TÉCNICOS SENAI
Seção 3
Ninhos de comando Se Dentro de um comando de seleção (comando Se) é possível colocar qualquer tipo de comando. Assim, dentro de um comando Se, pode-se ter outros comandos de seleção. Veja a seguir.
Figura 6: Exemplo de seleção composta
Essas situações são muito comuns em programação, razão pela qual será preciso recorrer aos comandos de seleção (ou de decisão). A condição Se-Então (-Senão) é uma estrutura de seleção comum em diversas linguagens de programação. Sua estrutura básica é a seguinte. algoritmo “SE” var varNum : inteiro inicio se varNum < 10 entao escreva (“Número menor que 10”) senão escreva (“Número maior ou igual a 10”) fimse fimalgoritmo
Quando o interpretador encontra o identificador Se, ele espera em seguida uma condição booleana sob forma de expressão relacional (como por exemplo, “varNum < 10”), que pode ser verdadeira ou falsa. Se a condição é verdadeira, o bloco de código seguido de Então é executado. Caso a condição seja falsa, o bloco de código seguido de Senão é executado. Em ambos os casos, após a execução do bloco de código, o fluxo do programa é retornado para o ponto indicado por Fim Se. Note que a parte do Senão é opcional e pode ser omitida. Caso seja omitida, a estrutura é chamada de seleção simples; caso contrário, é chamada seleção composta.
algoritmo “MAXIMO” var varNum1, varNum2 : inteiro inicio leia (varNum1) leia (varNum2) se varNum1 > varNum2 entao escreva (“Maior valor é o primeiro”) senão escreva (“Maior valor é o segundo”) fimse fimalgoritmo
Como você pode perceber, nesse algoritmo é determinado o maior valor entre dois valores. Se os dois números forem iguais, o algoritmo informará que o “varNum2” é o maior valor, o que obviamente não é verdade. Assim, esse algoritmo não está correto. Note que nesse problema há três situações possíveis: “varNum1” maior que “varNum2”, “varNum1” menor que “varNum2” e os dois com valores iguais. Utilizando um único comando Se, conseguimos avaliar apenas duas situações. Para levar em conta as três situações, outro comando de seleção faz-se necessário. Quer saber a seleção para esse problema? Então veja o exemplo seguinte.
LÓGICA DE PROGRAMAÇÃO
31
algoritmo “MAXIMO” var varNum1, varNum2 : inteiro inicio leia (varNum1) leia (varNum2) se varNum1 > varNum2 entao escreva (“Maior valor é o primeiro”) senão se varNum1 < varNum2 escreva (“Maior valor é o segundo”) senão escreva (“Os dois valores são iguais”) fimse fimse fimalgoritmo
Note que, nessa nova versão, caso o valor da expressão “varNum1 > varNum2” seja falso, o fluxo de execução irá executar o que estiver dentro do Senão do primeiro Se. Dentro do Senão do primeiro Se, um outro Se é executado, sendo então verificado se o conteúdo de “varNum1” é menor que conteúdo de “varNum2”. Veja que o comando de seleção que está colocado dentro do Senão do primeiro Se, só será executado se ao executar o primeiro Se, a expressão for falsa. Em seguida, é feita a verificação se o conteúdo de “varNum1” é menor que o conteúdo de “varNum2”. Caso positivo, será definido que o conteúdo de “varNum2” é maior, senão definirá que ambos são iguais. E você já ouviu falar no Comando Escolha? Mesmo que não saiba o que é fique tranquilo, pois esse será o tema da seção seguinte. Até lá!
Seção 4
Comando Escolha Quando um conjunto de valores discretos precisa ser testado e ações diferentes são associadas a esses valores, estamos diante de uma seleção com ninhos de comando Se. Como essa situação é bastante frequente na construção de algoritmos que dependem de alternativas, utilizaremos uma estrutura específica para esses casos: a seleção de múltipla escolha. O comando Escolha é uma alternativa para os comandos Se aninhados, deixando o algoritmo com uma estrutura melhor.
32
CURSOS TÉCNICOS SENAI
Suponha que o conceito de um aluno seja determinado em função de sua nota. Suponha também que essa nota seja um valor inteiro na faixa de 1 a 4. O problema está na seguinte situação: dada a nota, determine o respectivo conceito. Considere ainda os conceitos que você verá na tabela seguinte. Tabela 10: Notas e conceitos
Nota
Conceito
1
Insuficiente
2
Regular
3
Bom
4
Ótimo
Para resolver o problema, veja a seguir o algoritmo por meio da utilização de Se´s aninhados.
algoritmo “CONCEITO” var varNota : inteiro varConceito : caractere inicio leia (varNota) se varNota = 1 entao varConceito ← “Insuficiente” senão se varNota = 2 varConceito ← “Regular” senão se varNota = 3 varConceito ← “Bom” senão varConceito ← “Ótimo” fimse fimse fimse escreva (varConceito) fimalgoritmo
Perceba que, no algoritmo anterior, vários testes são feitos sobre o conteúdo da variável “varNota”. Em vez de escrevermos os vários testes utilizando Se´s aninhados e considerando que todos os testes são realizados sobre uma mesma expressão, é possível utilizar um comando alternativo, que tem essa função. Trata-se do comando Escolha, cuja função é tornar possível a escolha de uma alternativa, entre as várias disponíveis. Usando o comando Escolha, o problema de determinação do conceito de um aluno pode ser resolvido conforme apresentado no próximo algoritmo. Acompanhe com atenção!
Com isso, ao executar o comando Escolha no algoritmo anterior, será avaliada cada uma das opções de valores de “varNota”. Portanto, veja que a opção 1, por exemplo, significa valor igual a 1. Assim, se o valor de “varNota” for igual ao da comparação, essa opção será satisfeita. As opções serão sempre avaliadas na ordem em que aparecem e será executada a instrução relativa à primeira opção que satisfazer o valor de “varNota”. Caso nenhuma das opções satisfaça o valor da expressão do comando Escolha, serão executadas as instruções colocadas no Outrocaso. Quantos comandos importantes você aprendeu nesta unidade de estudo, não é mesmo? O comando Se, os ninhos de comando Se e o comando Escolha certamente serão muito úteis para seus cálculos! Existem muitos outros comandos que você aprenderá no decorrer desta unidade curricular. Então não perca tempo. Aplique seus conhecimentos praticando e siga com dedicação e disciplina!
algoritmo “CONCEITO” var varNota : inteiro varConceito : caractere inicio leia (varNota) escolha varNota caso 1 varConceito ← “Insuficiente” caso 2 varConceito ← “Regular” caso 3 varConceito ← “Bom” outrocaso varConceito ← “Ótimo” fimescolha escreva (varConceito) fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
33
Unidade de estudo 4 Seções de estudo Seção 1 – Introdução Seção 2 – Comando Enquanto Seção 3 – Comando Repita Seção 4 – Comando Para
Estruturas de Repetição Seção 1
Introdução Existem situações em que, para obter-se a solução do problema, é necessário fazer com que um conjunto de instruções seja executado várias vezes. Esta unidade de estudo tem por objetivo apresentar e discutir estruturas que possibilitem a execução de um conjunto de instruções por várias vezes, com o programador escrevendo este conjunto apenas uma vez. Em detalhes, uma estrutura de repetição é uma estrutura de desvio do fluxo de controle que realiza e repete diferentes ações dependendo se uma condição é verdadeira ou falsa, em que a expressão é processada e transformada em um valor booleano. Estão associadas a uma estrutura de repetição uma condição (também chamada “expressão de controle” ou “condição de parada”) e um bloco de código: verifica-se a condição e, caso seja verdadeira, o bloco é executado. Após o final da execução do bloco, a condição é verificada novamente e, caso ela ainda seja verdadeira, o código é executado novamente.
Mas atenção! Caso o bloco de código nunca modifique o estado da condição, observe que a estrutura será executada para sempre. E essa será uma situação chamada laço infinito. Da mesma forma, é possível especificar uma estrutura em que o bloco de código modifica o estado da condição, mas esta é sempre verdadeira. Algumas linguagens de programação especificam ainda uma palavra reservada para sair da estrutura de repetição de dentro do bloco de código, “quebrando” a estrutura. Também é oferecida por algumas linguagens uma palavra reservada para terminar uma iteração específica do bloco de código, forçando uma nova verificação da condição. Ficou claro até aqui? Esta unidade de estudo é uma das mais importantes para o seu estudo! Você notará que a partir desse ponto começará a ter mais dificuldade na resolução dos algoritmos em função da dificuldade de entender onde as estruturas de repetição deverão ser colocadas para atender às exigências dos enunciados. Portanto, continue atento!
Vamos a um exemplo. Suponha que um determinado clube social tenha registrado a quantidade de latas de cerveja vendidas no último carnaval. Considerando que cada lata foi vendida a R$ 1,40, deseja-se saber o total arrecadado no último carnaval, com a venda das latas de cerveja. Obviamente que para esse problema tem-se como entrada a quantidade de latas vendidas e deseja-se saber, como solução do problema, qual o total arrecadado. Veja a seguir o respectivo algoritmo. algoritmo “QUANTIDADE_ ARRECADADA” var varQuantidadeVendida : inteiro varValorArrecadado : real inicio leia (varQuantidadeVendida) varValorArrecadado ← varQuantidadeVendida * 1,40 escreva (varValorArrecadado) fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
35
Como você pôde perceber, o problema apresentado consiste em determinar o total arrecadado com a venda de latas de cerveja no último carnaval. Se desejarmos determinar o total arrecadado em cada um dos último três carnavais, o algoritmo poderia ser escrito da forma seguinte: algoritmo “QUANTIDADE_ARRECADADA” var varQuantidadeVendida : inteiro varValorArrecadado : real inicio // Total arrecadado no último ano leia (varQuantidadeVendida) varValorArrecadado ← varQuantidadeVendida * 1,40 escreva (varValorArrecadado) // Total arrecadado no penúltimo ano leia (varQuantidadeVendida) varValorArrecadado ← varQuantidadeVendida * 1,40 escreva (varValorArrecadado) // Total arrecadado no antepenúltimo ano leia (varQuantidadeVendida) varValorArrecadado ← varQuantidadeVendida * 1,40 escreva (varValorArrecadado) fimalgoritmo
Observe no algoritmo anterior que a solução do problema é a mesma para cada ano. Assim, as instruções para cada um dos anos podem ser as mesmas. Veja também que, se você quisesse determinar o total arrecadado em cada um dos últimos 30 anos, usando a mesma metodologia, teríamos que escrever 30 vezes o mesmo conjunto de instruções, o que obviamente se tornaria impraticável. Considerando que para cada um dos casos as instruções a serem executadas são as mesmas, é muito mais adequado que se escreva um conjunto de instruções apenas uma vez, e que instrua o computador para que repita a execução das instruções por um determinado número de vezes. Os laços de repetição também são conhecidos por sua tradução em inglês: loops ou looping. Ganham esse nome por lembrarem uma execução finita em círculos, que depois segue seu curso normal.
Nesta unidade, você estudará três tipos de estrutura de repetição: com teste no início (comando Enquanto), com teste no final (comando Repita) e automática (comando Para). Ficou curioso para saber o que cada um dos comandos representa? Vamos iniciar com o comando Enquanto. Em frente!
Seção 2
Comando Enquanto O comando Enquanto é uma estrutura recomendada quando o número de repetições for desconhecido, sendo necessária uma chave (um teste) para interromper a repetição.
36
CURSOS TÉCNICOS SENAI
Consiste em uma estrutura de controle do fluxo de execução que permite repetir diversas vezes um mesmo trecho do algoritmo, porém, sempre verificando antes de cada execução se é permitido executar o mesmo trecho.
Para realizar a repetição com teste no início, utilizamos a estrutura Enquanto, que permite que um bloco ou uma ação primitiva seja repetido enquanto uma determinada Condição for verdadeira. O modelo genérico desse tipo de repetição é o que você verá a seguir. algoritmo “ENQUANTO” inicio enquanto faca // Trecho a ser repetido fimenquanto fimalgoritmo
Preste atenção! Quando o resultado de Condição for falso, o comando de repetição é abandonado. Se já da primeira vez o resultado é falso, os comandos não são executados nenhuma vez, o que representa a característica principal desse modelo de repetição. Com isso, é possível concluir que em algum momento do processo de repetição das instruções internas ao comando Enquanto será necessário que a expressão lógica assuma o valor falso, pois, do contrário, o fluxo jamais sairá de dentro do Enquanto e o conjunto de instruções será repetido infinitas vezes. Para que você entenda melhor, veja a seguir um exemplo de análise de saldo bancário. Se você quiser um algoritmo que faça a análise para dez contas, pode escrever a solução conforme o exemplo.
algoritmo “ANALISE_BANCARIA” var varSaldo : real varConta, varContador : inteiro inicio varContador ← 0 enquanto varContador < 10 faca varContador ← varContador + 1 leia (varConta) leia (varSaldo) se varSaldo < 0 entao escreva (varConta, “ está estourada”) senao escreva (varConta, “ está normal”) fimse fimenquanto fimalgoritmo
Observe que no algoritmo anterior utilizamos uma variável “varContador”, que inicialmente assume o valor zero. Na primeira vez que o fluxo de execução chega ao Enquanto, a expressão lógica “varContador < 10” tem o valor verdadeiro. Assim, são executados todos os comandos internos do Enquanto. Observe também que no interior do comando Enquanto colocamos o comando “varContador ß varContador + 1”, o qual fará com que o conteúdo da variável “varContador” seja incrementado de uma unidade toda vez que o mesmo for executado. Mas o que é incrementar nesse tipo de cálculo? Incrementar é o mesmo que somar um valor constantemente. O ponteiro dos segundos de um relógio é um legítimo contador de segundos, que sempre vai incrementando 1 a cada instante de tempo, equivalente a 1 segundo. Quando atinge 60 segundos, é a vez do ponteiro dos minutos ser incrementado e assim por diante.
E o comando Repita, você sabe qual sua função? Esse será o assunto da próxima seção!
Seção 3
Comando Repita O comando Repita é uma estrutura recomendada quando o número de repetições for desconhecido, sendo necessária uma chave (um teste) para interromper a repetição. Sua diferença em relação ao Enquanto é que ele testa ao final, executando o trecho pelo menos uma vez. Essa estrutura também precisa de uma condição para interromper a repetição. Veja um modelo genérico: algoritmo “REPITA” inicio repita // Trecho a ser repetido ate fimalgoritmo
Quando o fluxo de execução chegar ao Repita, automaticamente serão executados os comandos internos ao Repita. Chegando no ate, será avaliada a condição. Se a condição for falsa, então o fluxo de execução retornará ao Repita, e os comandos internos serão novamente executados. Quando o fluxo de execução chegar no ate e a condição for verdadeira, a execução sairá do Repita. O algoritmo seguinte utiliza o Repita para determinar o melhor aluno de uma turma. Observe com atenção!
LÓGICA DE PROGRAMAÇÃO
37
algoritmo “MELHOR_ALUNO” var varNota, varMaximo, varQuantidade, varContador : inteiro varNome, varMelhor : caractere inicio escreval (‘Entre com a quantidade de alunos’) leia (varQuantidade) varMaximo ← -1 varContador ← 0 repita escreval (“Entre com o nome do aluno”) leia (varNome) repita escreval (“Digite um valor de 0 a 10”) leia (varNota) ate (varNota >=0) e (varNota <= 10) se varNota > varMaximo entao varMaximo ← varNota varMelhor ← varNome fimse varContador ← varContador + 1 ate varContador = varQuantidade fimalgoritmo
Ficou mais fácil com o exemplo, não é mesmo? Como você pôde ver, a cada vez que for executado o conjunto de instruções internas ao primeiro comando Repita, um aluno é processado. Ou seja, é solicitado o nome e a nota de cada aluno. Cada nota de um aluno é comparada com o conteúdo da variável “varMaximo” e, se o conteúdo de “varNota” for maior que “varMaximo”, então é possível concluir que essa nota é a maior entre as que já foram processadas. Portanto, o conteúdo de “varMaximo” deve ser alterado para o valor de “varNota”. Como o algoritmo se propõe a determinar também qual o nome do melhor aluno, então toda vez que for encontrada uma nota maior que o conteúdo de “varMaximo”, o nome do aluno é salvo na variável “varMelhor”. Note que, a cada aluno processado, o conteúdo da variável “varContador” é incrementado em uma unidade, resultando em algum momento do processo de repetição, que a expressão “varContador = varQuantidade” assumirá o valor verdadeiro, fazendo com que a repetição seja encerrada. Ainda no algoritmo, o segundo comando Repita faz com que o valor lido para nota do aluno esteja no intervalo de 0 a 10. Veja que este Repita só é encerrado se a expressão “(varNota >= 0) e (varNota <= 10)” tiver o valor verdadeiro. Sempre que a expressão for avaliada e apresentar o valor falso, o fluxo retornará ao respectivo Repita e será solicitado que o usuário digite novamente a nota. O último comando dessa unidade é o Para. Está pronto para saber mais sobre ele? Adiante!
38
CURSOS TÉCNICOS SENAI
Seção 4
Comando Para O comando Para é usado quando o número de repetições for conhecido durante a elaboração do algoritmo ou quando puder ser fornecido durante a execução. Nas estruturas de repetição vistas até agora, ocorrem casos em que se torna difícil determinar o número de vezes em que o bloco será executado. Sabemos que ele será executado enquanto uma condição for satisfeita (Enquanto), ou até que uma condição seja satisfeita (Repita). A estrutura Para é diferente, já que sempre repete a execução do bloco durante um número predeterminado de vezes, pois ela não prevê uma condição e possui limites fixos. Quer saber qual o modelo genérico para a estrutura de repetição Para? Então veja a seguir. algoritmo “PARA” inicio para de ate faca // Trecho a ser repetido fimpara fimalgoritmo
Onde:
▪▪ : é a variável contadora que controla o número de repetições; ▪▪ : é uma expres-
são que especifica o valor de inicialização da variável contadora antes da primeira repetição;
▪▪ : é uma expressão que especifica o valor máximo que a variável contadora pode alcançar.
e são avaliados uma única vez antes da execução da primeira repetição e não se alteram durante a execução da repetição, mesmo que variáveis eventualmente presentes nessas expressões tenham seus valores alterados. No exemplo a seguir, os números de 1 a 10 são exibidos em ordem crescente. Observe!
algoritmo “NUMEROS” var varJ : inteiro inicio para varJ de 1 ate 10 faca escreval (varJ) fimpara fimalgoritmo
Para entender melhor, veja mais um exemplo da utilização da estrutura Para. O mesmo determina o total arrecadado para um clube no final do ano.
Veja que no algoritmo anterior a variável de controle do Para é a “varMes”. A variável “varMes”, conforme especifica o comando, assume os valores inteiros que vão de 1 até 12. Para cada valor de “varMes”, as instruções internas ao Para são executadas. O valor do incremento, quando não especificado, o que é possível incluindo “passo ”, no comando Para antes do faca, sempre é 1. Vamos assumir que ao chegar no Para pela primeira vez será calculado o número de vezes que as instruções internas ao Para serão executadas. A determinação do número de repetições é feita usando-se os valores inicial e limite, combinados com o valor do incremento para a variável de controle. Assim, estamos assumindo também que não será possível abandonar a repetição das instruções antes que o número de repetições seja alcançado.
algoritmo “BALANCO” var varMes : inteiro varSoma, varReceita, varDespesa : real inicio varSoma ← 0 para varMes de 1 ate 12 faca escreval (“Digite a receita e a despesa do mês de “, varMes)
Veja então, que o comando Para só pode ser utilizado quando você souber o número de vezes que se quer repetir. Confira a seguir um exemplo do comando Para, utilizando um incremento diferente do padrão. algoritmo “NUMEROS” var varJ : inteiro inicio para varJ de 1 ate 10 passo 2 faca escreval (varJ) fimpara fimalgoritmo
No exemplo anterior, serão escritos somente os valore 1, 3, 5, 7 e 9. Para o valor do passo também é possível definir um valor negativo, que fará a repetição subtrair o valor definido até chegar a 0. Nesse caso, o valor inicial deverá ser maior que o valor final. Mais uma unidade chega ao final e agora você já tem muitos conhecimentos novos. Aqui você aprendeu sobre as estrutura de repetição, com os comandos Enquanto, Repita e Para. Siga em frente, pois tem muita coisa interessante aguardando por você! Faça do seu estudo um momento significativo e prazeroso!
leia (varReceita) leia (varDespesa) varSoma ← varSoma + (varReceita - varDespesa) fimpara escreva(“Total arrecadado durante o ano “, varSoma) fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
39
Unidade de estudo 5 Seções de estudo Seção 1 – Introdução Seção 2 – Vetores Seção 3 – Matrizes
Estruturas Homogêneas Seção 1
Introdução Para iniciar o estudo, é importante destacar que as estruturas de dados homogêneos possibilitam o armazenamento de grupos de valores em uma única variável que será armazenada na memória do computador. Mas por que essas estruturas são chamadas de homogêneas? Porque os valores que serão armazenados são de um mesmo tipo de dado. As estruturas homogêneas são divididas em unidimensionais e multidimensionais. Normalmente, as estruturas unidimensionais são chamadas de vetores e as multidimensionais são chamadas de matrizes. De fato, um vetor também é uma matriz, porém varia em somente uma dimensão. No intuito de compreender as facilidades do processamento de valores usando adequadamente uma estrutura de dados, observe o algoritmo a seguir, supondo a necessidade de armazenamento da altura de cinco atletas. algoritmo “ATLETA” var varAltura1, varAltura2, varAltura3, varAltura4, varAltura5 : real inicio escreval (“Informe a altura do primeiro atleta: “) leia (varAltura1) escreval (“Informe a altura do segundo atleta: “) leia (varAltura2) escreval (“Informe a altura do terceira atleta: “) leia (varAltura3)
Esse algoritmo possibilitaria a leitura de cinco alturas de cinco atletas diferentes e as armazenaria em cinco variáveis distintas (varAltura1, varAltura2, varAltura3, varAltura4, varAltura5). Uma instrução de repetição não melhoraria muito essa lógica, pois os cinco valores precisarão estar disponíveis independente dos outros valores informados. Mas imagine se a leitura das alturas tivesse que ser realizada para um time de futebol, ou para uma equipe de futebol americana, por seu algoritmo, o que seria feito, então? E se em um próximo campeonato seu algoritmo fosse usado para registrar todos os participantes de todas as equipes que participam da competição? Em situações como essa é que as estruturas de dados fazem a diferença, sendo essenciais ao processamento dos dados eficiente por um computador.
escreval (“Informe a altura do quarto atleta: “) leia (varAltura4) escreval (“Informe a altura do quinto atleta: “) leia (varAltura5) fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
41
Seção 2
▪▪ Único identificador dessa estrutura de dados = alturas
Vetores
Uma estrutura de dados composta de forma homogênea e unidimensional, ou vetor, é um arranjo de elementos (dados) armazenados na memória do computador, sendo que esses dados são organizados de forma eficiente um após o outro, sob um mesmo identificador, cujas regras são as mesmas para criar um identificador de uma variável simples, que possui capacidade de guardar somente um valor. Um vetor é uma estrutura de dados homogênea que pode ser acessado de forma aleatória (qualquer posição que seja necessária).
Suas principais características são:
▪▪ contém vários valores (núme-
ro definido);
▪▪ todos os valores são do mesmo tipo de dado (homogênea); ▪▪ possui um único nome (identificador da variável); ▪▪ cada valor do conjunto é acessível independentemente, de acordo com o seu índice (ou posição na estrutura de dados); ▪▪ todos os seus elementos, ou dados armazenados, são igualmente acessíveis a qualquer momento do processamento (acesso aleatório). Modificando a forma de solução do algoritmo anterior, que possuía cinco variáveis para guardar cinco alturas de atletas, é possível empregar um vetor para armazenar essas cinco alturas.
42
CURSOS TÉCNICOS SENAI
Mas o que representam os Valores e os Índices? Os Valores correspondem aos conteúdos lidos pelo usuário, ou seja, são as alturas dos atletas. Os Índices são as posições que garantem independência a cada um desses valores armazenados na estrutura de dados homogênea. Por meio desses índices, também chamados de posições do vetor, seus valores (conteúdos) podem ser manipulados de forma independente. Imagine a necessidade de mostrar a altura do maior atleta cadastrado nesse vetor. Entre essas cinco alturas, a maior é a quarta no vetor. Como o índice de uma estrutura de dados inicia sempre a partir de zero, a quarta altura está armazenada na terceira posição da estrutura, sendo o conteúdo dessa posição (3) igual a 2.20 (altura do quarto atleta cadastrado). Os vetores são chamados de estruturas compostas unidimensionais. E você sabe por quê? São compostas pois podem armazenar vários valores. E unidimensionais, pois só possuem variação em uma dimensão.
Declaração de vetor A sintaxe correta para declaração de uma estrutura de dados composta homogênea unidimensional (vetor), na representação de português estruturado, deve respeitar a seguinte forma geral: algoritmo “VETOR” var : vetor [..] de inicio fimalgoritmo
Onde:
▪▪ – tipo de dado que será armazenado no vetor; ▪▪ – nome definido ao vetor, respeitando as regras de identificação;
▪▪ e – são os valores inteiros que definem início e fim dos índices do vetor, sendo o seu intervalo a quantidade exata de elementos do vetor, ou seja, seu tamanho.
Veja mais um exemplo. algoritmo “ALTURAS” var vetAlturas : vetor [0..4] de real inicio fimalgoritmo
Nesse exemplo será criado um vetor chamado alturas, que poderá armazenar até cinco números reais diferentes. E veja bem! Uma atenção especial deve ser dedicada na compreensão de que esse tipo de estrutura de dados tem seu primeiro elemento armazenado na posição zero e não na um. Poucas linguagens de programação não seguem esse padrão. Ele é comumente adotado pela maioria das linguagens de desenvolvimento de programas. O gráfico a seguir representa a organização de um vetor com tamanho três. Confira!
Normalmente é utilizada uma instrução de repetição para guardar e acessar os dados que são armazenados em um vetor (seu conteúdo). Suponha que exista a necessidade de leitura e armazenamento das cinco alturas de atletas em um vetor que tenha capacidade de realizar esse armazenamento. Saiba mais com um exemplo. algoritmo “ALTURAS” var varAuxiliar : inteiro vetAlturas : vetor [0..4] de real inicio para varAuxiliar de 0 ate 4 faca escreval (“Informe a altura do “, varAuxiliar + 1 , “º atleta”) leia (vetAlturas[varAuxiliar]) fimpara fimalgoritmo
Nesse exemplo, são criados somente duas variáveis, sendo uma denominada auxiliar e a outra alturas, que consiste em um vetor de cinco posições (índice de zero até quatro). Esse vetor possui um único identificador, mas tem a capacidade de armazenar até cinco valores reais como seu conteúdo, similar à criação das cinco variáveis alturas (altura1, altura2, altura3, altura4, altura5) da proposta de solução do algoritmo anterior. Suponha que o usuário desse algoritmo digite os seguintes valores: 1.80, 2.03, 1.75, 2.20, 2.12. Uma representação gráfica desse vetor seria:
algoritmo “VETOR” var vetValores : vetor [0..2] de inteiro inicio fimalgoritmo
Figura 8: Representação gráfica do vetor
Isso indica que a posição 3 do vetor possui como conteúdo o valor de 2.20, informado pelo usuário no momento de execução do algoritmo anterior. A terceira altura informada é 1.75 e está armazenada no índice 2, que corresponde ao terceiro conteúdo guardado nesse vetor.
Vetor do tipo de dado caractere Figura 7: Organização de um vetor com tamanho três
Para armazenar o nome de uma pessoa, por exemplo, deve-se criar uma estrutura de dados composta homogênea do tipo de dado caractere. Todo nome consiste em um conjunto de caracteres (letras, caracteres especiais e até dígitos numéricos, se assim os pais dessa pessoa desejarem).
LÓGICA DE PROGRAMAÇÃO
43
Especificamente para esse tipo de vetor, que envolve um conjunto de caracteres, é estabelecida uma expressão que a caracteriza facilmente, sendo importante na área de informática: string ou simplesmente cadeia de caracteres. A sintaxe que você verá a seguir declara um vetor de caracteres com a capacidade de armazenar até dez conjuntos de caracteres, sendo essa declaração representada graficamente após a instrução de criação desse vetor chamado “vetNomes”. algoritmo “VETOR” var vetNomes : vetor [0..9] de caractere inicio fimalgoritmo
A representação anterior mostra um vetor de dez elementos. Isto é, tem a capacidade de dez variáveis do tipo caractere agrupadas em um identificador, “vetNomes” , independentes por sua posição dentro do vetor, indicadas por seu índice que varia de zero até 9 (nove). Você percebeu que existe um espaço entre a palavra Ricardo e Henrique (no índice 5)? Esse espaço consiste em um único caractere especial (espaço em branco), ocupando sua respectiva posição no vetor “vetNomes”. Para acessar cada uma de suas posições, será usado o identificador do vetor, seguido do valor de seu índice entre colchetes. Vamos a mais um exemplo.Veja a seguir o algoritmo que lê os dez nomes. algoritmo “NOME DA PESSOA” var varAuxiliar : inteiro vetNomes : vetor [0..9] de caractere inicio para varAuxiliar de 0 ate 9 faca escreval (“Digite o nome: “) leia(vetNomes[varAuxiliar]) fimpara fimalgoritmo
44
CURSOS TÉCNICOS SENAI
Nesse exemplo, o usuário digitará um nome de cada vez, pressionando a tecla ENTER após cada nome digitado, sendo que todos eles são armazenados no vetor “vetNomes”.
Seção 3 Matrizes
Um vetor não deixa de ser uma matriz, porém essa matriz possui sua representação no algoritmo com mais de um índice, variando a partir do valor inteiro zero em todas as suas possíveis dimensões. Convencionalmente, na área de programação, a variação de seu primeiro índice, ou primeira dimensão da matriz, é representada como dimensão de linhas nas quais serão armazenados os respectivos conteúdos da matriz, enquanto que a segunda dimensão, ou segundo índice, corresponderia às colunas em que serão armazenados seus conteúdos. Já uma terceira dimensão, também chamada de matriz tridimensional, seria representada como páginas de um livro, enquanto outras dimensões teriam maiores dificuldades de uma representação didática adequada que facilitaria sua compreensão. Apesar dessa dificuldade de representação, uma matriz possui o limite das dimensões coerentes com a quantidade de memória disponível no computador que a estará manipulando.
Similar aos vetores, as matrizes possuem o primeiro elemento de cada linha, ou coluna, ou ainda qualquer outra dimensão iniciada com índice 0 (zero). Por exemplo, o elemento na primeira linha da primeira coluna de uma matriz de alturas terá índice [0,0], enquanto o elemento na segunda linha da primeira coluna terá o índice [1,0]. Repare que as posições do exemplo anterior ([0,0] ou [1,0]) estão indicando dois valores inteiros que correspondem à exata posição em cada uma das dimensões dessa matriz bidimensional (varia em duas dimensões – linha e coluna).
Declarando uma matriz Você sabia que a declaração de uma matriz é bem parecida com a declaração de um vetor? É verdade! Afinal, o vetor não deixa de ser uma matriz, mas poderá ser bidimensional, tridimensional, entre outras possíveis variações de dimensões (multidimensional), possuindo uma definição inteira para cada uma dessas dimensões que terão seu tamanho máximo definido no momento da declaração no algoritmo. algoritmo “MATRIZ” var : vetor [..,..] de inicio fimalgoritmo
Onde:
▪▪ – tipo de dado que será armazenado na matriz; ▪▪ – nome defi-
nido para matriz, respeitando as regras de definição de identificadores;
▪▪ . e . – são os valores inteiros de início e fim de cada dimensão definida na matriz, tendo essa sintaxe geral somente duas dimensões, que são separadas por vírgula (,). Veja a seguir a representação gráfica para uma matriz que tenha capacidade de armazenar as alturas dos cinco atletas titulares de uma equipe de basquete e ainda as cinco alturas de seus reservas.
Figura 9: Representação gráfica para matriz
A representação que você acabou de ver pode ser definida em linguagem algorítmica, no bloco de declarações do algoritmo, respeitando a forma genérica apresentada anteriormente para declaração de uma matriz. Observe que essa matriz tem capacidade de armazenamento de dez alturas independentes, ao invés de somente cinco, como foi abordado no primeiro exemplo no estudo de vetores. Caso tenha dúvidas, retorne ao conteúdo sobre vetores para relembrar. Veja mais uma situação!
LÓGICA DE PROGRAMAÇÃO
45
algoritmo “ALTURAS” var vetAlturas : vetor [0..1,0..4] de real inicio fimalgoritmo
Assim, a manipulação e armazenamento das alturas na memória estão mais bem organizados, propiciando maior eficiência do computador no acesso aos seus endereços de memória que guardam essas dez alturas (todos estes valores estão guardados de maneira consecutiva na memória por estarem definidos para o armazenamento em uma estrutura de dados – matriz ou vetor). Acompanhe o exemplo seguinte que permite a manipulação dessa matriz bidimensional denominada “varAlturas”. algoritmo “ALTURAS” var varLinha, varColuna, varContador : inteiro varSoma : real vetAlturas : vetor [0..1,0..4] de real inicio varContador ← 1 varSoma ← 0 escreval(“Cadastro das Alturas dos Atletas Titulares”) para varLinha de 0 ate 1 faca para varColuna de 0 ate 4 faca escreva(“Digite a altura do ”, varContador , “ atleta: ”) leia(vetAlturas[varLinha,varColuna]) varContador ← varContador + 1 varSoma ← varSoma + vetAlturas[varLinha,varColuna] fimpara se varLinha = 0 entao escreval(“Cadastro das Alturas dos Atletas Reservas”) fimse fimpara
46
CURSOS TÉCNICOS SENAI
// Percorre a matriz novamente para apresentar as alturas cadastradas para varLinha de 0 ate 1 faca para varColuna de 0 ate 4 faca escreval(“Altura [“, varLinha, “,”, varColuna,”]=”, vetAlturas[varLinha,varColuna]) fimpara fimpara escreval(“Média da Altura destes Atletas = ” , (varSoma / (varContador - 1))) fimalgoritmo Perceba que, no exemplo anterior, na primeira linha (zero), serão guardadas as alturas dos atletas titulares, enquanto que na segunda linha (um) serão as dos reservas. Apesar de existir um único identificador, é possível armazenar dez valores, como também poderia ser feito por um vetor de dez posições ([0..9]). Porém, a organização no armazenamento das alturas dos titulares e reservas não poderia ser feita de maneira lógica adequada e eficiente para manipulação dos endereços de memória do computador que estiver executando esse algoritmo. Note que tanto a quantidade de linhas como a de colunas estão iniciando de zero e chegando até o valor final definido na declaração da matriz, onde a multiplicação da quantidade de elementos em cada dimensão pode ser somada para identificar a capacidade máxima de armazenamento da matriz.
▪▪ Linhas [0..1] – Dimensão com duas linhas ▪▪ Colunas [0..4] – Dimensão com cinco colunas
A quantidade de duas linhas sendo multiplicada por cinco colunas resultará em dez posições, independentes de memória para essa estrutura de dados composta homogênea (matriz de alturas), com duas dimensões (bidimensional). O mesmo cálculo e manipulação são realizados para estruturas de dados de caracteres (string), o que pode organizar melhor o armazenamento de vários nomes de pessoas diferentes, frase e outros dados que correspondam a um conjunto de caracteres. Puxa, quantas informações importantes nesta unidade! Você conheceu as estruturas homogêneas, vetores e matrizes. Foi um aprendizado e tanto, não é mesmo? E as estruturas heterogêneas? Esse será o assunto da próxima unidade. Então, sinta-se convidado a aprender ainda mais. Até lá!
LÓGICA DE PROGRAMAÇÃO
47
Unidade de estudo 6 Seções de estudo Seção 1 – Introdução Seção 2 – Registros
Estruturas Heterogêneas
Seção 1
Seção 2
Agora você já sabe que um conjunto homogêneo de dados, tal como uma alcateia, é composto de variáveis do mesmo tipo (lobos), certo? Mas veja bem! Se você tivesse um conjunto em que os elementos não são do mesmo tipo, teria um conjunto heterogêneo de dados. Vamos entender melhor! Poderíamos ter um conjunto de animais quadrúpedes, formado por cães (matilha), camelos (cáfila), búfalos (manada) etc. Sendo assim, uma das principais estruturas de dados é o registro. Imagine uma identificação de passageiro, aquele formulário de informações que o passageiro entrega ao motorista antes de embarcar no ônibus, junto com sua passagem. Ela é formada por um conjunto de informações logicamente relacionadas, porém, de tipos diferentes, tais como número de passagem (inteiro), origem e destino (caracteres), data (caracteres), horário (caracteres), poltrona (inteiro), idade (inteiro) e nome do passageiro (caracteres), que são subdivisões do registro (elementos do conjunto), também chamadas de campos. Quer saber mais sobre os registros? Vamos para a próxima seção!
Os registros são agrupamentos de dados, possivelmente heterogêneos (real, inteiro, lógico, caractere), que visam a oferecer meios mais simples de manipular informações relacionadas que o projetista do algoritmo quer manter unidas. Por exemplo, pense em um algoritmo que implemente operações sobre número de empregados, valor do salário, departamento dos projetos, lucros obtidos de uma empresa. A manipulação de tais dados se torna trivial com a utilização dos registros. E sabe por quê? Pois por meio de um rótulo (identificador do conjunto de dados) é possível acessar os dados membros do conjunto.
Introdução
Registros
Um registro é composto por campos que são partes que especificam cada uma das informações que o compõe. Uma variável do tipo registro é uma variável composta, pois engloba um conjunto de dados, e é heterogênea, pois cada campo pode ser de um tipo primitivo diferente.
A figura que você verá a seguir ilustra graficamente um exemplo de uma hipotética identificação de embarque (registro) em um ônibus, com diversas informações (campos) solicitadas pela companhia de transporte para o controle dos passageiros embarcados.
Figura 7: Passagem de ônibus
LÓGICA DE PROGRAMAÇÃO
49
Todas as operações concernentes aos algoritmos podem ser realizadas com as estruturas, atribuições, operações lógicas e/ou aritméticas e declarações de vetores de estruturas. Além dos vetores e matrizes, os registros permitem a confecção de algoritmos mais sofisticados, tendo em vista que fornecem uma maneira mais cômoda de trabalhar com os dados e facilitam a vida do projetista do algoritmo em relação ao planejamento de como simular os dados do mundo real para os conceitos abstratos inerentes aos algoritmos. Agora vamos imaginar o seguinte problema: uma empresa vai fornecer o crediário para um cliente efetuar o pagamento em várias parcelas. Mas, para isso, será necessário efetivar um cadastro dos dados mais relevantes para a localização do cliente, caso algum problema venha a ocorrer com os pagamentos. Você sabe quais seriam as informações? As informações são estas:
▪▪ nome; ▪▪ endereço; ▪▪ número do CPF.
A criação dessas fichas cadastrais conterá dados com tipos diferentes e, por isso, não será possível usar uma variável composta homogênea para guardar todos. Apesar disso, todos esses dados são relacionados, pois pertencem a uma mesma pessoa. Ou seja, cada ficha possuirá diferentes dados (nome, endereço e CPF), mas todos eles são de um mesmo cliente, sendo que todos esses dados são relacionados logicamente a esse cliente. Cada um dos dados que formam essa ficha é chamado de componente ou elemento do registro, sendo que cada ficha completa é identificada como um código de registro. Portanto, nesse exemplo, só será possível conseguir um crediário após a efetivação do registro do cliente, sendo esse registro formado pelos componentes nome, endereço e número do CPF. Vamos ver um exemplo? Acompanhe!
Figura 8: Registro de crediário
Essa empresa também não fará o crediário somente para um cliente, mas para os vários clientes que possuírem um perfil interessante para o negócio. Assim, será necessário criar uma estrutura de dados que possa armazenar vários dados (composta) de tipos diferentes (heterogênea). Essas estruturas (compostas heterogêneas) também são chamadas de registros e permitem uma organização eficiente no armazenamento e manipulação dos dados que estão implicitamente relacionados. E que tal, agora, conhecer as características dos registros? Elas serão muito importantes. Observe!
▪▪ ▪▪ ▪▪ ▪▪
Podem conter vários registros com valores (número definido). Os valores não precisam ser do mesmo tipo de dado. Um registro possui um único nome (identificador).
Cada registro é acessível independentemente, sendo seus elementos também independentes, de acordo com o seu nome significativo.
50
CURSOS TÉCNICOS SENAI
Veja mais um exemplo.
Figura 9: Registro de crediário
No exemplo anterior, você pôde observar dois registros cadastrados. A primeira ficha contém os dados do João Carlos da Silva, enquanto que a segunda possui os dados da Maria Rita Amaral. Os componentes desse registro são identificados por meio dos seus nomes, atribuídos após a especificação do registro com o uso do operador ponto (.).
Declaração geral de registro Para que você entenda o que é uma estrutura básica para declaração de um registro, acompanhe a seguir. algoritmo “REGISTRO” var registro = ; ; fimregistro inicio fimalgoritmo
Onde:
▪▪ é o nome do registro (segue as regras de nomenclatura); ▪▪ é o nome do componente que forma esse registro; ▪▪ é o tipo de dado que será armazenado em cada compo-
nente.
LÓGICA DE PROGRAMAÇÃO
51
Ficou mais claro agora? Então vamos criar um registro para armazenar os três componentes diferentes (SEXO, CPF, PESO). Veja! algoritmo “REGISTRO” var registro = regPessoa CPF inteiro; Sexo caracter; Peso real; fimregistro inicio escreva (“Informe o seu CPF: ”) leia (regPessoa.CPF) escreva (“Digite F para sexo feminino e M para masculino”) leia (regPessoa.Sexo) escreva (“Digite seu peso: ”) leia (regPessoa.Peso) fimalgoritmo
Suponha que esse cadastro seja feito por uma empresa de publicidade, que está procurando alguns novos modelos. Ela não irá cadastrar somente um candidato à vaga de modelo mas todos os interessados, que poderão ser vários. Portanto, será criado um vetor para esse tipo de estrutura heterogênea. Observe o exemplo a seguir, que cria a possibilidade de 1.000 registros serem armazenados na estrutura composta homogênea (vetor).
52
CURSOS TÉCNICOS SENAI
algoritmo “REGISTRO” var varContador : inteiro registro = regPessoa CPF inteiro; Sexo caracter; Peso real; fimregistro inicio para varAuxiliar de 0 ate 999 faca escreva (“Informe o seu CPF: ”) leia (regPessoa[varAuxiliar].CPF) escreva (“Digite F para sexo feminino e M para masculino”) leia (regPessoa[varAuxiliar].Sexo) escreva (“Digite seu peso: ”) leia (regPessoa[varAuxiliar].Peso) fimpara fimalgoritmo
Esse algoritmo permite o cadastramento de 1.000 fichas com os componentes CPF, SEXO e PESO, sendo cada um para uma pessoa diferente. Essa estrutura armazenará no algoritmo todos os 1.000 registros, denominados FICHA, sendo ela homogênea, pois cada um desses elementos do vetor é do mesmo tipo de dado criado no bloco de declarações. O registro criado imediatamente antes dos dados acima é do tipo PESSOA. Muito bem! Aqui terminamos mais uma unidade de estudos, onde você aprendeu o que são registros e como deve ser feita uma declaração geral de registro. Está preparado para mais uma etapa? Na unidade seguinte você estudará as funções. Lembre-se de que, para apropriar-se de novos conhecimentos, é indispensável motivação e interesse. Siga os passos rumo ao conhecimento!
LÓGICA DE PROGRAMAÇÃO
53
Unidade de estudo 7 Seções de estudo Seção 1 – Introdução Seção 2 – Utilização de subprogramas Seção 3 – Argumentos e parâmetros Seção 4 – Funções Seção 5 – Procedimentos Seção 6 – Âmbito de variáveis Seção 7 – Argumentos de subprogramas Seção 8 – Erros mais comuns
Funções Seção 1
Introdução A complexidade dos algoritmos está intimamente ligada à da aplicação a que se destinam. Em geral, problemas complicados exigem algoritmos extensos para sua solução. Lembre-se também de que sempre é possível dividir um problema grande em problemas menores e de solução mais simples. Assim, pode-se solucionar cada um desses problemas mais simples e combinar essas soluções de forma que o problema maior seja resolvido. E você sabe como? Podemos codificar a solução desses problemas simples utilizando os chamados subalgoritmos ou sub-rotinas. Subalgoritmo é um nome dado a um trecho de um algoritmo mais complexo e que, em geral, encerra em si mesmo um pedaço da solução de um problema maior a que ele está subordinado.
O subalgoritmo divide-se em funções e procedimentos. É importante observar que existe distinção entre funções (possui um único retorno) e procedimentos (não possui retorno algum).
E você sabia que a ideia de reutilização de software tem sido adotada há muito tempo por muitos desenvolvedores de sistemas de computador? É verdade! Isso se deve à economia de tempo e trabalho que proporcionam. Seu princípio é o seguinte: um conjunto de algoritmos destinado a solucionar uma série de tarefas bastante corriqueiras é desenvolvido e vai sendo aumentado com o passar do tempo, com o acréscimo de novos algoritmos. A esse conjunto se dá o nome de biblioteca. No desenvolvimento de novos sistemas, procura-se ao máximo basear a concepção em subalgoritmos já existentes na biblioteca, de modo que a quantidade de software realmente novo que venha a ser desenvolvido seja minimizada. Mas veja bem! Muitas vezes, os subalgoritmos são utilizados para conter certas sequências de instruções que são repetidas em um algoritmo. Nesses casos, os subalgoritmos proporcionam uma diminuição no tamanho dos algoritmos. Em resumo, os subalgoritmos são importantes na:
▪▪ subdivisão de algoritmos com-
plexos, facilitando o seu entendimento;
▪▪ estruturação de algoritmos, facilitando principalmente a detecção de erros e a documentação de sistemas;
▪▪ modularização de sistemas, que facilita a manutenção de softwares e a reutilização de subalgoritmos já implementados. Após essa introdução sobre o tema da unidade, vamos à próxima seção, onde o foco de estudos será a utilização de subprogramas. Até lá!
Seção 2
Utilização de subprogramas Na escrita de um programa de computador, muitas vezes surge a necessidade de repetir a mesma sequência de instruções em locais diferentes do programa. Para evitar essa repetição, que implica em um aumento do número de linhas e um tempo de desenvolvimento maior, muitas linguagens de programação apresentam o conceito de subprograma. Esse conceito, por vezes também designado por sub-rotina, permite escrever um conjunto de instruções da linguagem identificadas por um nome determinado. Assim, ao invés de repetir as instruções sempre que sejam necessárias no programa, bastaria indicar o nome do subprograma correspondente a essas linhas nos locais onde a sequência seria repetida.
LÓGICA DE PROGRAMAÇÃO
55
Um subprograma é controlado por um programa de nível superior que determina quando e sob que condições o subprograma deve ser executado e que pode eventualmente recolher um valor devolvido por este.
Outra questão importante é que os subprogramas podem ser chamados a partir de várias zonas do programa e sob condições diferentes. O seu uso introduz também uma maior flexibilidade no processo de desenvolvimento de software, pois permite a substituição fácil de um subprograma por uma versão mais atual. A divisão em subprogramas corresponde à divisão de um problema em subproblemas mais simples, o que facilita a resolução do problema inicial e permite uma abordagem top-down. A utilização de subprogramas é também uma forma de facilitar a produção de software favorecendo o recurso a módulos previamente desenvolvidos e constituídos por conjuntos de subprogramas.
DICA A utilização desses módulos evita a reescrita de subprogramas sempre que um novo programa necessita de atualização, diminuindo o tempo de desenvolvimento de programas complexos e evitando que o programador se preocupe com detalhes pouco importantes para a compreensão do problema. Esses módulos são designados por bibliotecas.
56
CURSOS TÉCNICOS SENAI
Os subprogramas são normalmente classificados como funções ou como procedimentos. Em qualquer subprograma é também possível a definição de outros subprogramas. Alguns deles apresentam ainda uma característica importante e que consiste na possibilidade de se chamarem a si próprios, ou seja, um subprograma é invocado recursivamente pelo mesmo subprograma. Agora que você já sabe mais sobre os subprogramas, siga para a próxima seção!
Seção 3
Argumentos e parâmetros Muitas vezes é necessário indicar explicitamente ao subprograma as condições sob as quais a sua execução vai ser realizada. Por essas razões, um subprograma poderá aceitar argumentos que determinam essas condições. Os argumentos poderão ser variáveis, constantes ou expressões. Na descrição do subprograma, devem estar definidos os parâmetros que correspondem aos argumentos que o programa do nível acima determinou. Essas considerações são válidas para subprogramas definidos pelos programadores e para subprogramas predefinidos. Vamos entender melhor! Considere, por exemplo, um subprograma, designado por AREA, para calcular a área de um retângulo, dados os comprimentos dos lados. Esse subprograma irá devolver o valor da área do retângulo. O subprograma seria invocado recorrendo a uma instrução do tipo “varA = AREA (varComprimento,varLargura)”.
A variável A seria de um tipo compatível com o valor de retorno do subprograma. Já o comprimento e a largura seriam variáveis usadas como argumentos. O subprograma seria definido da seguinte maneira. Observe! funcao AREA (varX, varY : real) : real var varAux : real inicio varAux ← varX * varY retorne varAux fimfuncao
No subprograma AREA estão definidos os parâmetros varX e varY do tipo real. Os parâmetros declaram-se imediatamente antes da chaveta que marca o início do conjunto de instruções que constituem a função ou procedimento. Existe uma relação direta entre os argumentos usados na chamada de um subprograma e os parâmetros definidos para esse subprograma. A esses parâmetros irão ser atribuídos os valores dos argumentos. Se o subprograma fosse invocado como “varA = AREA (10,5)”, os parâmetros varX e varY passariam a conter os valores 10 e 5, respectivamente. Note que não precisa existir nenhuma correspondência entre os nomes das variáveis definidas como parâmetros de um subprograma e os nomes de eventuais variáveis usadas como argumentos na chamada desse subprograma. Aliás, no exemplo anterior, o subprograma foi invocado com valores constantes.
Outra possibilidade é a utilização de expressões com significado dentro do programa a partir do qual o subprograma é executado. Por exemplo: “varA = AREA( varX * 2, varLargura / 10 )”. Nesse caso, a variável varX usada na expressão correspondente ao primeiro argumento tem um significado diferente do parâmetro varX usado na definição do subprograma, embora os nomes sejam iguais. Lembre-se de que é muito importante ter bem clara a distinção entre essas situações. Vamos em frente!
Seção 4 Funções
Na seção anterior você conheceu uma característica importante: o subprograma AREA possui um valor de retorno. Ou seja, devolve um valor determinado que pode ser utilizado pelo programa que o invocou. Os subprogramas que apresentam essa característica designam-se por funções. As funções podem ser definidas com ou sem parâmetros. algoritmo “QUADRADO” funcao QUADRADO (varX : real) : real var varAux : real inicio varAux <- varX * varX retorne varAux fimfuncao var varNumero, varResultado : real varFim : logico inicio enquanto varFim = falso faca
As funções incluem sempre a palavra retorne, seguida do valor a devolver ou de uma expressão que defina esse valor. Nas funções é também necessário indicar o tipo do valor de retorno. A linha “funcao QUADRADO (varX : real) : real” indica uma função designada por QUADRADO que aceita um parâmetro varX e retorna um valor real. Genericamente, a sintaxe para definição de uma função é a que você verá a seguir. funcao [()]: // Seção de Declarações Internas inicio // Seção de Comandos fimfuncao
Mas lembre-se de que a lista de parâmetros e declarações respectivas são opcionais.
leia (varNumero) se varNumero = 0 entao varFim = verdadeiro senão varResultado ← QUADRADO (varNumero) escreva (“Quadrado de ”, varNumero, “ é ”, varResultado) fimse fimenquanto fimalgoritmo
LÓGICA DE PROGRAMAÇÃO
57
Seção 5
Procedimentos Os procedimentos são subprogramas que se distinguem das funções pelo fato de não apresentarem qualquer valor de retorno. Os procedimentos, tal como as funções, podem apresentar ou não uma lista de parâmetros que definem a forma como o procedimento irá ser executado. Tal como nas funções, é necessário declarar os parâmetros do procedimento, caso existam. Por exemplo, considere-se o programa que permite o cálculo da área de um retângulo, escrevendo o valor calculado. Nesse programa foram definidos dois subprogramas: a função AREA, que permite o cálculo da área do retângulo, e o procedimento ESCREVE_AREA, que apresenta o resultado calculado. O programa termina se for introduzido um valor negativo para o comprimento de um lado do retângulo. algoritmo “AREA” funcao AREA (varX, varY : real) : real var varAux : real inicio varAux ß varX * varY retorne varAux fimfuncao procedimento ESCREVE_AREA (varX : real) inicio escreva (“O valor da área é ”, varX) fimfuncao var varX, varY, varA : real varFim : logico inicio repita leia (varX) leia (varY) se varX < 0 ou varY < 0 entao varFim = verdadeiro senão varA ← AREA (varX, varY) ESCREVE_AREA(varA) fimse ate varFim = falso fimalgoritmo
58
CURSOS TÉCNICOS SENAI
Note que as funções e procedimentos que eventualmente possam existir em um programa são sempre definidos antes do procedimento especial “inicio”. Portanto, fique atento! Genericamente, a sintaxe para definição de um procedimento é a seguinte, veja: procedimento [()] // Seção de Declarações Internas inicio // Seção de Comandos fimprocedimento
Tal como no caso das funções, a lista de parâmetros e declarações respectivas são opcionais.
Seção 6
Âmbito de variáveis As variáveis que representam o comprimento dos lados de um retângulo no programa exemplificado têm o mesmo nome no programa principal e na função AREA. E você sabe o que aconteceria se a função AREA alterasse os valores dessas variáveis? Os novos valores seriam reconhecidos no programa principal, ou esse consideraria apenas os valores iniciais? Ah, essas são boas perguntas! Na realidade, em ambos os casos, as variáveis são locais, ou seja, são variáveis que são reconhecidas apenas nas funções onde se encontram declaradas. Assume-se que o computador cria novas variáveis em cada um dos casos e as armazena em locais diferentes, embora os nomes sejam iguais.
Dessa forma, evitam-se conflitos entre os valores armazenados nas duas situações. Quando termina uma função ou procedimento, as suas variáveis locais são destruídas e o espaço de memória respectivo é libertado, podendo ser usado pelo programa para outros fins. Uma variável local só é reconhecida no subprograma em que se encontra declarada, não podendo ser invocada por outros subprogramas. O uso de variáveis locais diminui o espaço na memória do computador requerido por um programa, uma vez que apenas possuem uma área de memória reservada durante a execução do bloco do programa no qual se encontram definidas.
Existem, no entanto, muitas situações em que é importante que uma determinada variável seja reconhecida em qualquer ponto do programa. Isso significa que, independentemente da função ou procedimento que utilizar a variável, esta estará sempre associada à mesma posição de memória, não sendo destruída depois de ser utilizada por um subprograma. A variável existirá, permanecendo reservado o espaço de memória respectivo, até que o programa termine a sua execução. Assim, é possível considerar a existência de variáveis com características distintas: as variáveis locais ou automáticas, que apenas têm existência dentro do subprograma em que se encontram declaradas, e as variáveis globais ou estáticas, que existem enquanto o programa não terminar, sendo reconhecidas por qualquer subprograma.
As variáveis globais são declaradas fora de qualquer função ou procedimento, incluindo o procedimento especial “inicio”. Ficou claro até aqui? Então siga para a seção seguinte!
Seção 7
Argumentos de subprogramas Um subprograma definido de forma a aceitar parâmetros, cria cópias das variáveis passadas como argumentos pelo programa que invocou o subprograma em questão. Mas o que isso representa? Significa que os parâmetros definidos para um subprograma vão funcionar como variáveis locais desse subprograma. É por esse motivo que não existe qualquer conflito em invocar um subprograma cujos argumentos são variáveis com nomes iguais aos parâmetros definidos para o subprograma. Internamente, o computador irá reservar áreas de memória diferentes para os seus parâmetros. Acompanhe o seguinte procedimento. procedimento SOMA_UM (varX) inicio varX ← varX + 1 escreva (varX) fimprocedimento
Como você pode perceber, esse procedimento limita-se apenas a aceitar um valor inteiro, somar o valor 1 ao valor recebido e escrever o resultado. Se esse procedimento for chamado em conjunto com as instruções que você verá a seguir, o resultado obtido seria 4 e sucessivamente 3.
algoritmo “SOMA” procedimento SOMA_UM (varX) inicio varX ← varX + 1 escreva (varX) fimprocedimento var varX : real inicio varX ← 3 SOMA_UM (varX) escreva (varX) fimalgoritmo
Conforme o exemplo anterior, o procedimento SOMA_UM não alterou o valor da variável varX que continuou a ter o valor 3 após a chamada do procedimento. O valor 4 corresponde ao valor da variável varX no procedimento SOMA_UM. Mas fique atento! Esse mecanismo de cópia dos argumentos para variáveis locais no subprograma não é desejável em todas as situações. Existem muitos casos em que se pretende que as alterações exercidas sobre as variáveis correspondentes aos parâmetros do subprograma sejam reconhecidas no programa ou subprograma de nível superior. Um exemplo típico consiste na definição de um subprograma que permita proceder à troca dos valores de duas variáveis. Veja a seguir um procedimento capaz de executar essa tarefa.
LÓGICA DE PROGRAMAÇÃO
59
procedimento TROCA (varA, varB) var varC : inteiro inicio varC ← varA varA ← varB varB ← varC fimprocedimento
Com esse procedimento, pretende-se atribuir à variável varA ao conteúdo da variável varB e a esta, o conteúdo de varA recorrendo a uma variável auxiliar varC. Caso esse procedimento fosse utilizado, seria feito da seguinte maneira. Saiba mais! algoritmo “TROCA” procedimento TROCA (varA, varB) var varC : inteiro inicio varC ← varA varA ← varB varB ← varC fimprocedimento var varX, varY : real inicio varX ← 5 varY ← 6 TROCA (varX, varY) escreva (“X = ”, varX, “, Y = ”, varY) fimalgoritmo
60
CURSOS TÉCNICOS SENAI
E sabe qual o resultado para essa operação? O resultado obtido seria “X = 5, Y = 6, ou seja, não houve qualquer troca dos valores das variáveis. Para que você entenda melhor, a explicação é simples. Ao ser invocado, o procedimento TROCA criou cópias dos argumentos que recebeu, trocou esses valores entre si e, ao terminar, libertou o espaço reservado para os parâmetros que continham o valor dos argumentos. Isso significa que o procedimento funcionou, mas apenas em relação às cópias dos argumentos que recebeu. Para resolver o problema, ao invés de passar como argumentos os valores das variáveis, deve-se indicar ao procedimento TROCA as posições de memória (endereços) ocupadas por essas variáveis. Na prática, isso significa que os parâmetros do procedimento são substituídos pelos argumentos que são passados, fazendo com que as alterações efetuadas dentro do procedimento sejam reconhecidas no programa que o invocou. Nesse caso, diz-se que os argumentos foram passados por referência. A situação inicial corresponde a passar os argumentos por valor. Mas como será possível distinguir essas duas situações? Para isso, é feita a colocação do caractere var antes do nome do argumento que é passado por referência na instrução correspondente à chamada do procedimento. A palavra var permite aceder ao endereço da variável e não ao seu conteúdo. A troca correta de valores das duas variáveis precisa ser efetuada indicando o endereço dos argumentos do procedimento TROCA. Confira!
algoritmo “TROCA” procedimento TROCA (var varA, var varB) var varC : inteiro inicio varC ← varA varA ← varB varB ← varC fimprocedimento var varX, varY : real inicio varX ← 5 varY ← 6 TROCA (varX, varY) escreva (“X = ”, varX, “, Y = ”, varY) fimalgoritmo
O resultado obtido seria “X = 6, Y = 5”, ou seja, houve troca dos valores das variáveis. Nesse caso, as alterações efetuadas no procedimento foram reconhecidas no programa que o invocou. Em relação a essa questão, é importante destacar que esses problemas podem ser resolvidos de outra maneira. Para tal, basta que as variáveis envolvidas sejam definidas como variáveis globais, sendo reconhecidas em todo o programa. Assim, não seria necessário fazer a passagem de argumentos por referência. Aliás, não seria necessário passar essas variáveis como argumentos aos subprogramas que atuassem sobre elas, pois todos os subprogramas são capazes de reconhecer variáveis globais. Mas esse processo não é muito aconselhável. Sabe por quê? Porque ele limita as potencialidades de utilização dos subprogramas, que passam a ter um caractere muito restrito. As linguagens de programação apresentam formas diversas de efetuar a distinção entre a passagem de argumentos por valor ou por referência.
Um erro frequente consiste na utilização de uma variável global como se fosse uma variável local. Embora normalmente o computador não acuse qualquer erro, gera-se uma situação que, em geral, leva a um mau funcionamento do programa. Essas situações são normalmente difíceis de detectar. Por isso, fique atento! Os erros que ocorrem pela troca na forma de passagem de argumentos também podem ser difíceis de detectar e têm como consequências a alteração de valores de variáveis que se pretendiam inalteráveis (troca da passagem por valor pela passagem por referência) ou a não alteração de conteúdos de variáveis que se pretendiam modificar (troca da passagem por referência pela passagem por valor). Puxa, foram muitos termos técnicos, não é mesmo? E agora você já está mais familiarizado para aplicar os conhecimentos sobre lógica de programação. Mas não pare por aqui. Busque novas informações para aprimorar ainda mais o seu trabalho!
Seção 8
Erros mais comuns A correta compreensão do âmbito de uma variável envolvida em um programa e a análise das situações que permitem a escolha da forma de passagem de parâmetros são fundamentais na elaboração de programas de computador. Esses aspectos tornam-se mais críticos à medida que a complexidade dos programas aumenta. Os programas complexos podem envolver um número elevado de variáveis e a utilização de diversos subprogramas, implicando maiores cuidados na definição do âmbito das diversas variáveis e nas formas de passagem de argumentos.
LÓGICA DE PROGRAMAÇÃO
61
Finalizando Parabéns, querido aluno! Como você viu nesta unidade curricular, a lógica de programação nada mais é do que a organização coerente das instruções do programa para que seu objetivo seja alcançado. Para criar essa organização, instruções simples do programa – como mudar o valor de uma variável ou desenhar uma imagem na tela do computador –, são interconectadas a estruturas lógicas que guiam o fluxo da execução do programa. Isso é muito próximo ao que usamos em nosso cotidiano para realizar atividades simples, não é mesmo? Além das atividades que realizamos no dia a dia, há sempre o chamado raciocínio lógico, que define os passos para que nossa atividade seja completada com sucesso. Quando esse raciocínio falha, ou seja, não é suficientemente preciso, há grandes chances de não alcançarmos nosso objetivo. A mesma coisa acontece com os programas de computador. Esta unidade curricular teve como principal objetivo fazer com que você entendesse os conceitos fundamentais de lógica de programação independentemente da linguagem e introduzi-lo em uma metodologia de desenvolvimento de programas. E saiba que conhecer lógica de programação é mais importante que conhecer uma linguagem de programação. Sem saber como se planeja um programa, dificilmente poderá ser implantada, tanto na linguagem de programação mais antiga como nas mais modernas. Portanto, lembre-se de que um aprendizado efetivo depende do seu empenho e dedicação. Esses conhecimentos serão úteis em várias ocasiões de sua vida. Boa sorte e muito sucesso!
LÓGICA DE PROGRAMAÇÃO
63
Referências ▪▪
ASCENCIO, Ana Fernanda Gomes; CAMPOS, Edilene Aparecida Veneruchi de. Fundamentos da programação de computadores. 2. ed. São Paulo, SP: Pearson Prentice Hall, 2007.
▪▪
BOENTE, Alfredo. Aprendendo a programar em Pascal: técnicas de programação. Rio de Janeiro, RJ: Brasport, 2003.
▪▪
FORBELLONE, André Luiz Villar. Lógica de programação – A construção de algoritmos e estruturas de dados. São Paulo, SP: Makron, 1993.
▪▪
FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederico. Lógica de programação – a construção de algoritmos e estrutura de dados. 3. ed. São Paulo, SP: Makron, 2000.
▪▪
FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederico. Lógica de programação – a construção de algoritmos e estruturas de dados. São Paulo, SP: Pearson Prentice Hall, 2005.
▪▪
LOPES, Anita; GARCIA, Guto. Introdução à programação – 500 algoritmos resolvidos. Rio de Janeiro, RJ: Elsevier, 2002.
▪▪
MORAES, Paulo Sérgio de. Curso básico de lógica de programação. São Paulo, SP: Unicamp, 2000.
▪▪
OLIVEIRA, Álvaro Borges de. Introdução à programação – algoritmos. Florianópolis: Bookstore, 1999.
LÓGICA DE PROGRAMAÇÃO
65
Equipe de Desenvolvimento de Recursos Didáticos Coordenação de Educação a Distância Beth Schirmer Coordenação Projetos EaD Maristela de Lourdes Alves Coordenação de Desenvolvimento de Recursos Didáticos Gisele Umbelino Projeto Educacional Angela Maria Mendes Israel Braglia Projeto Gráfico Daniela de Oliveira Costa Jordana Paula Schulka Juliana Vieira de Lima
Design Educacional Daiana Silva Capa, Ilustrações, Tratamento de Imagens D’imitre Camargo Martins Diego Fernandes Luiz Eduardo Meneghel Diagramação Daniela de Oliveira Costa Flavia Akemi Ito Revisão e Fechamento de Arquivos Juliana Vieira de Lima Revisão Ortográfica e Normatização FabriCO
LÓGICA DE PROGRAMAÇÃO
67