# Programação estruturada

Programação Estruturada (PE) é um padrão ou paradigma de programação da engenharia de softwares, com ênfase em sequência, decisão e, iteração (sub-rotinas, laços de repetição, condicionais e, estruturas em bloco), criado no final de 1950 junto às linguagens ALGOL 58 e ALGOL 60,
Este paradigma é normalmente formado por código em um único bloco e foi impulsionado pelas vantagens práticas que o paradigma oferece, e também pelo 'teorema do programa estruturado [en]' (de 1966, também chamado de teorema de Böhm-Jacopini) e a carta aberta de Dijkstra 'Go To Statement Considered Harmful' (de 1968). De fato, muitas linguagens não possuem GOTOs para desincentivar a programação não-estruturada (nota: Donald Knuth advogou o GOTO em algumas circunstâncias.
A PE foi o paradigma dominante na escrita de software até a programação orientada a objetos (POO). Enquanto a PE fia-se em estruturas de controle de alto nível (em oposição ao uso de GOTOs), concepções top-down e refinamento por passos, a POO se baseia no conceito de objetos que possuem atributos (dados) e métodos (procedimentos).
Apesar de ter sido sucedida pela POO, a PE ainda é muito influente pois grande parte das pessoas ainda aprende programação através dela. Para a resolução de problemas simples e diretos, a programação estruturada é bastante eficiente (talvez mais eficiente que a POO). Além disso, por exigir formas de pensar relativamente complexas, a POO até hoje ainda não é bem compreendida ou usada pela maioria.
Diversas linguagens relevantes hoje (e.g. Cobol, PHP, Perl e Go) ainda utilizam o paradigma estruturado, embora possuam suporte para a orientação ao objeto e para outros paradigmas de programação.

## Estrutura do paradigma

É formada por três estruturas:
* Sequência: a tarefa é executada logo após a outra;
* Decisão: a tarefa é executada após um teste lógico, e;
* Iteração: a partir do teste lógico, um trecho do código pode ser repetido finitas vezes.

## Elementos básicos da teoria
### Estruturas de controle

Na PE, os programas são vistos como compostos das seguintes 'estruturas de controle' (ECs) :
* Sequência: de instruções ou sub-rotinas executadas em sequência (a=4; b=4*5)
* Seleção/condicional: instruções são executadas ou não conforme o estado do programa (if, else, elif/elseif, endif)
* iteração/repetição: instruções são executados até que o programa atinja um determinado estado (for, while, repeat, do..until)
* recursão: instruções executadas com chamadas auto-referenciadas até que certas condições sejam satisfeitas. Exemplo:
Há a utilização de 'sub-rotinas' em que as ECs são agrupadas e utilizadas através de um única instrução (são as funções, métodos, subprogramas, procedimentos). Blocos permitem que uma sequência de instruções seja tratada como uma única instrução.

### Refinamento por passos

Uma ideia central na PE é o refinamento por passos, em que o programa é desenvolvido de maneira top-down, por exemplo:
* comece com o programa principal
** use as ECs de iteração e seleção
** escreva as chamadas para as rotinas (r1, r2, etc) quando necessário. Diz-se 'postule r1, r2'.
* Implemente r1, r2, ..., com chamadas para outras rotinas conforme conveniente.
* Continue implementando as rotinas até que não sejam necessários procedimentos adicionais.
Na prática, é usual iniciar a programação não exatamente do topo, até porque é comum que haja vários topos, mas isso depende da complexidade e modularidade do software.

### Desvios

Dentre os desvios mais comuns da programação estruturada, há múltiplos pontos:
* De saída:
** terminação antecipada: return em uma função, break or continue em um laço de interação, ou um exit em algum programa. Na programação estruturada, a rigor, há um só ponto de saída da rotina sendo executada.
** Manejo de exceção: clausulas como (try.. except) do Python ou (try.. catch) do C++, também implicam em múltiplos pontos de saída da rotina.
* De entrada: útil e.g. para geradores, streaming, máquinas de estado.

## Conceito-chave: GOTO

Seja um programa uma sequência de instruções a serem seguidas (e.g. por um computador). Considere um ponteiro que indica a instrução a ser executada na próxima oportunidade. Um GOTO é um reposicionamento arbitrário deste ponteiro. Embora seja um comando poderoso, o uso de GOTOs é considerado, em geral, má prática, havendo quem o defenda em algumas situações.
Na programação imperativa, que possui ênfase na modificação de valores em endereços de memória (i.e. instruções de atribuição), o uso de GOTOs é abundante. Em muitos contextos, pode-se assumir que 'programação estruturada' é sinônimo de programação sem GOTO (sem pulos, sem redirecionamentos arbitrários do ponteiro da sequência de instruções em execução). Estes foram os dois primeiros paradigmas dominantes na programação de computadores. A imperativa desde o início da programação até os anos 1970. A estruturada até o final década de 1990, e então deu lugar à POO.

## Críticas usuais à PE

Dentre as críticas à PE, constam:
* PE é orientada para a resolução de um problema em particular.
** Um escopo mais amplo é muitas vezes conveniente.
* PE é realizada pela decomposição gradual da funcionalidade.
** As estruturas advindas de funcionalidade/ação/controle não são as partes mais estáveis de um programa.
** Foco em estruturas de dados ao invés de estruturas de controle é uma alternativa.
* Sistemas reais não possuem um único topo.
** Pode ser apropriado considerar alternativas à abordagem top-down.
Veja também a POO, paradigma que foi estabelecido depois de décadas de PE.

## PE vs POO

Entres os paradigmas PE e POO, não existe certo e errado. A POO tende a dar melhores resultados em programas maiores com reuso de partes/sub-rotinas dos programas. Ambos os paradigmas possuem vantagens e desvantagens. A melhor prática é evitar extremismo (moldes rígidos): há casos em que é melhor priorizar a POO ou a PE, e mesmo quando uma estratégia é evidentemente melhor, o purismo tende a gerar software menos organizado ao custo de mais trabalho.

## Tópicos avançados

* Diagrama Nassi-Shneiderman: uma representação gráfica (estructograma) para PE, desenvolvida em 1972.
* Carta de estrutura (structure chart): um diagrama usado na PE para organizar os módulos em árvore.