Programar é basicamente “Construir Algoritmos”.
A programação estruturada é “a arte ou técnica de construir e formular algoritmos de forma sistemática.” [Niklaus Wirth]
Segundo Wirth, “programas são formulações concretas de algoritmos abstratos, baseados em representações e estruturas específicas de dados”.
Decisões sobre a estruturação dos dados não podem ser feitas sem conhecimento dos algoritmos aplicados a eles e vice-versa: a estrutura e a escolha dos algoritmos depende muitas vezes, fortemente, da estrutura dos dados.
Num algoritmo e em particular num programa, devemos distinguir claramente dois aspectos complementares:
• Aspecto Estático: A formulação de um algoritmo consiste em um texto contendo comandos que devem ser executados na ordem prescrita. Este texto é uma representação concreta do algoritmo e tem um caráter estático.
• Aspecto Dinâmico: Cada execução de um algoritmo é um evento dinâmico. Os efeitos atingidos (gerados) por sua execução no tempo, dado um conjunto de valores iniciais, são o resultado do evento dinâmico.
Uma Ação é um evento que ocorre num período de tempo finito, estabelecendo um efeito intencionado e bem definido. Exemplos:
- Ligar a TV
- Descascar uma laranja
- Escrever no quadro
- Caminhar até a sala de aula
Não nos interessam aqui ações de efeito imprevisível. É fundamental que a ação seja executada num período de tempo finito (início no instante t0 e fim no instante t1).
Quando consideramos um evento como uma seqüência temporal de ações, cujo efeito acumulado é igual ao efeito do evento total, falamos de um Processo Seqüencial, ou apenas de um Processo.
Um evento pode ser considerado como uma ação primitiva (comando) ou como um processo (um algoritmo), dependendo do nosso interesse, se nós estamos interessados no evento total (estados inicial e final) ou em um ou vários estados intermediários.
Descreveremos então um evento na forma de um relato de um observador. O evento total “ler o jornal”, poderia ser escrito por uma sucessão dos seguintes eventos intermediários por parte do agente (quem executa o evento total):
- “Abrir a porta”;
- “Apanhar o jornal no chão”;
- “Entrar em casa”;
- “Fechar a porta”;
- “Sentar no sofá”;
- “Ler os assuntos de interesse”.
Observemos que existe um “símbolo de seqüenciamento” (;) indicando que as ações devem ocorrer na mesma ordem em que aparecem.
Exemplo: Qual o “Padrão de Comportamento” (seqüência de ações) utilizado para gerar a seqüência 1,4,7,10,13,16,19,22?
■ Definição de Algoritmo
“Um algoritmo é a descrição de um padrão de comportamento, expressado em termos de um repertório bem definido e finito de ações primitivas, as quais damos por certo que podem ser executadas”. [Guimarães/Lages.]
Um algoritmo tem um caráter imperativo no qual a ocorrência do nome de uma ação também é chamada de comando.
Em outras palavras, um algoritmo é uma norma executável para atingir um certo efeito desejado (obter uma solução para certo tipo de problema).
■ Exemplos de algoritmos (na vida prática):
- Manuais de uso
- Instruções de montagem
- Receitas de cozinha
- Informações de como chegar a um lugar
Um algoritmo DEVE ser determinístico, ou seja, dadas as mesmas condições iniciais deve produzir, depois de executado, os mesmos resultados.
■ Principais Conectivos ou Tipos de Comandos
Para exemplificar os tipos de comandos utilizados nos algoritmos e basicamente em toda linguagem de programação, analisemos um algoritmo usado por um cozinheiro para “descascar batatas para o jantar”:
■ 1) Seqüência Simples de Comandos:
“Trazer a cesta de batatas da despensa”;
“Trazer a panela do armário”;
“Descascar batatas”;
“Devolver a cesta à despensa”.
E se algumas vezes ele colocar um avental após buscar a panela e antes de descascar as batatas ?
■ 2) Inserção de Comandos:
“Trazer a cesta de batatas da despensa”;
“Trazer a panela do armário”;
“Colocar o avental”;
“Descascar batatas”;
“Devolver a cesta à despensa”.
E se a colocação do avental só ocorrer quando o cozinheiro estiver de roupa branca?
■ 3) Conectivo Condicional:
“Trazer a cesta de batatas da despensa”;
“Trazer a panela do armário”;
SE “roupa é branca” ENTÃO
“Colocar o avental”;
“Descascar batatas”;
“Devolver a cesta à despensa”.
A execução da ação “colocar avental” depende, em cada vez que o algoritmo é executado, do resultado (verdadeiro ou falso) da inspeção “se a roupa é branca”.
E se em um dia o cozinheiro tiver que descascar 10 quantidades batatas?
■ 4) Conectivo Repetitivo:
“Trazer a cesta de batatas da despensa”;
“Trazer a panela do armário”;
SE “roupa é branca” ENTÃO
“Colocar o avental”;
10 “Descascar batatas”;
“Devolver a cesta à despensa”.
Podemos ver ainda que, desta forma, é difícil sabermos determinar se o número de batatas escolhido (nº de repetições de “Descascar...”) foi suficiente para o jantar. Precisamos então introduzir outro tipo de comando:
■ 5) Conectivo Repetitivo Condicional:
“Trazer a cesta de batatas da despensa”;
“Trazer a panela do armário”;
SE “roupa é branca” ENTÃO
“Colocar o avental”
ENQUANTO “número de batatas é insuficiente” FAÇA
“Descascar batatas”
“Devolver a cesta à despensa”.
Com isto vemos o poder do conceito de algoritmo. Um texto estático, capaz de cobrir toda uma classe de acontecimentos, escrito no mesmo nível de detalhes do relato de um observador.
■ Programas e Estruturas de Dados
O computador é uma máquina capaz de seguir uma certa espécie de algoritmos chamados Programas. Possui uma memória para armazenar dados e uma unidade aritmética capaz de causar mudanças nos dados armazenados na memória.
Os computadores só entendem os algoritmos escritos em linguagem de máquina (de leitura difícil para nós).
Para podermos fazer com que o computador “entenda” uma linguagem próxima da linguagem natural, utilizaremos programas chamados Compiladores.
Compiladores são programas que “traduzem” os algoritmos escritos em uma linguagem de programação para a linguagem de máquina, além de verificar a corretude dos programas escritos.
■ Uma Linguagem de Programação é uma técnica de notação para programar, com a intenção de:
- Expressar raciocínio algorítmico;
- Permitir a execução de um algoritmo por um computador.
■ Programação Estruturada
Consiste em uma Metodologia de Projeto de Programação, visando:
- Facilitar a escrita dos programas;
- Facilitar a leitura (entendimento) dos programas;
- Facilitar a verificação a priori dos programas;
- Facilitar a manutenção e modificação dos programas.
■ Maior problema em grandes sistemas de software: Complexidade dos Sistemas
A Complexidade de um Sistema pode ser vista com uma medida do número dos seus componentes e do grau de interação entre eles.
“A Arte de programar consiste na arte de organizar e dominar a complexidade”. [Dijkstra]
■ A idéia básica da Programação Estruturada é reduzir a complexidade em três níveis:
I) Desenvolvimento do programa em diferentes fases por Refinamento Sucessivo (Desenvolvimento Top-Down);
II) Decomposição do programa total em Módulos Funcionais, organizados de preferencia num Sistema Hierárquico;
III) Uso, dentro de cada módulo, de um número limitado de Estruturas Básicas de Fluxo de Controle.
■ Principais Características da Programação Estruturada
» Desenvolvimento Top-Down – Processo de raciocínio que leva de uma análise do problema dado, passando por um algoritmo simples até um algoritmo detalhado, que consiste em uma seqüência de passos simples que podem ser diretamente expressos em termos de comandos, numa linguagem de programação.
» Cada nova fase desse desenvolvimento “de cima para baixo” é obtida por refinamento da fase anterior, até chegar a um nível de detalhamento que permita implementar o algoritmo diretamente na linguagem de programação.
» Algoritmo simples -> Refinamentos -> Algoritmo Detalhado -> Refinamentos -> Programa
» Modularização – Durante a fase de projeto descrita acima, a solução do problema total vai sendo fatorada em soluções e subproblemas, o que permite geralmente dividir o programa de forma natural em módulos com subfuncões claramente delimitadas, que podem ser implementados separadamente por diversos programadores de uma equipe.
» Estruturas de Controle – Deve-se usar, tanto quanto possível, as estruturas básicas de fluxo de controle (o comando condicional e os comandos repetitivos) que correspondem a formas de raciocínio simples.
» Documentação – Na programação tradicional a documentação consiste habitualmente em Fluxograma e Comentários (que são dispensáveis à execução do programa e podem ser feitos “a posteriori”). A programação estruturada ataca o problema propondo métodos de desenvolvimento que produzem simultaneamente o programa e sua documentação, ou melhor, procuram tornar código e documentação aspectos indivisíveis de um mesmo produto, que ficam forçosamente prontos ao mesmo tempo.
» Fluxo de Controle – O conceito que relaciona os aspectos Estático (algoritmo no papel) e Dinâmico (execução) de uma algoritmo é o fluxo de controle, que determina em cada passo da execução qual o próximo comando a ser executado. A ordem de execução dos comandos geralmente é bem diferente da sua ordem na folha de papel. Precisamos compreender a ordem das ações que ocorrem durante a execução, baseando-nos simplesmente na descrição estática do texto do algoritmo. A ordem de execução dos comandos muda, em geral, de uma execução para outra, dependendo dos dados de entrada. Então, devemos considerar, de fato, não somente um processo, mas toda uma classe de diferentes processos possíveis que o algoritmo pode evocar.
» Entender um algoritmo (a sua lógica) significa compreender (visualizar) essa classe de processos de execução. - Fonte: professor Adriano Caminha.