notas-de-aula- Schneider
29 pág.

notas-de-aula- Schneider

Disciplina:Linguagens de Programação I260 materiais733 seguidores
Pré-visualização11 páginas
de outro if,
exceto se estiver numa instrução composta);

• endentação (nas linguagens em que a endentação determina as instruções compostas - ex.:
Python).

Algumas linguagens usam sequências de instruções (em oposição a instruções compostas) nos
seletores, o que exige um marcador de final e elimina a ambiguidade.

2.4.2.3 Seleção múltipla
Alguns seletores permitem escolher dentre qualquer quantidade de instruções (ex.: case/switch).

Questões de projeto:

• Qual o tipo da expressão de seleção?

• Que tipo de instruções podem ser usadas (sequências, instruções compostas, etc.)?

• Somente um segmento pode ser executado?

• O que fazer se o valor da expressão não foi representado?

Em muitas linguagens, a seleção múltipla requer números inteiros, algumas permitem qualquer tipo
discreto.

Nem sempre a seleção múltipla por valores discretos é adequada. Várias linguagens oferecem a
possibilidade de aninhar testes nos seletores bidirecionais (elseif/elsif/elif), tornando-os seletores
múltiplos que não sofrem da falta de legibilidade do aninhamento profundo de seletores
bidirecionais. Esse tipo de estrutura é mais genérica que a anterior (case/switch).

2.4.3 Instruções iterativas
São instruções que proporcionam repetição da execução de um bloco (laço).

2.4.3.1 Laços controlados por contador
São interessantes nos casos em que se conhece o número de repetições desejadas, em especial, para
processamento de vetores.

São parametrizados por “valor inicial”, “valor final” e “passo”.

As linguagens variam muito a respeito dos laços controlados por contador. As questões de projeto
são:

• o tipo da variável de controle;

• o escopo da variável de controle;

• o valor da variável ao final do laço (última atribuição / indefinido);

prof. Bruno Schneider 15

Notas de Aula de GCC105 - BCC e BSI - UFLA

• a validade de alterar os parâmetros e, caso seja válido, o efeito da alteração;

• a avaliação única dos parâmetros ou a cada iteração.

Algumas formas são muito flexíveis e complicadas (C / Algol60) permitindo inclusive a mistura
entre o controle numérico e lógico.

2.4.3.2 Laços controlados por lógica
A repetição é controlada por uma expressão booleana.

São mais genéricos que os controlados por contador.

Podem realizar o teste antes ou depois do laço.

2.4.3.3 Controle localizado pelo usuário
Para aumentar a flexibilidade dos laços, é comum encontrar mecanismos de controle que podem ser
colocados em qualquer instrução interna ao laço. Essas instruções são comuns para tratamento de
situações especiais, e podem aumentar a velocidade do código ao custo de legibilidade.

Algumas linguagens oferecem estruturas de laço sem controle (loop infinito) ou determinam que o
controle é opcional.

As estruturas de controle envolvem saída prematura do laço (talvez de um laço mais externo) e
volta prematura ao teste de controle (talvez de um laço mais externo).

2.4.3.4 Controle por estruturas de dados
Pode ser interessante fazer uma repetição para cada elemento de um conjunto ou para cada parte de
uma estrutura de dados.

Neste tipo de iteração, um elemento sintático proporciona a repetição para todos os elementos de
uma coleção (ex.: o comando for em Java, a partir da versão 5). A forma usada para percorrer a
estrutura de dados fica abstraída.

A iteração controlada por estrutura de dados costuma ser imitada usando-se iteradores num laço
controlado por lógica. Neste caso a forma usada para percorrer a estrutura de dados costuma estar
definida em outra parte do código, proporcionando alguma abstração desse processo. O comando
for da linguagem C++ (que é um laço controlado por lógica) é frequentemente usado para
proporcionar esse efeito, já que a linguagem não oferece iterações controladas por estruturas de
dados.

2.4.4 Desvio incondicional
O desvio incondicional, usualmente chamado de “goto” foi assunto de muito debate quando as
bases da programação estruturada estavam sendo formadas. Eles são perigosos e eram na época o
principal fator a afetar negativamente a legibilidade dos programas. Ainda assim, sua utilidade é
enorme o que motivou tantos debates.

Hoje em dia, a maioria das linguagens de programação ainda oferece essa instrução, porém
juntamente com estruturas de controle que desincentivam ou limitam o seu uso. Linguagens que
apareceram a partir da década de 90 como Java, já começaram a abandonar a instrução.

prof. Bruno Schneider 16

Notas de Aula de GCC105 - BCC e BSI - UFLA

Essa instrução ainda é parte fundamental do conjunto de instruções de qualquer processador e é
usada pelos compiladores para produzir as instruções de controle de fluxo (alto nível) das
linguagens de programação em geral (seletores e laços). A tendência é que seja eliminada apenas
dos códigos de alto nível de abstração.

O desvio incondicional funciona em conjunto com rótulos, que são identificadores (às vezes
numéricos) para instruções de um programa.

Para reduzir os problemas relacionados com o desvio incondicional, as linguagens proporcionam
formas limitadas de uso desse comando. Frequentemente as limitações incluem desviar somente
“para frente” e mesmo assim, somente para o comando imediatamente após um bloco. Nessa forma,
o comando não diz para onde o fluxo de instruções será desviado, evitando abusos por parte do
programador. Exemplos comuns são o break para sair de laços e o return para sair de
subprogramas. Algumas linguagens procuram desincentivar até mesmo essa forma limitada de
desvio. Por exemplo, em Pascal e em Python, existe uma variável especial para definir o valor que
uma função retorna (em oposição a algo tipo “return”), dificultando a criação de saídas múltiplas.

2.4.5 Comandos protegidos
Uma outra forma de seleção muito diferente e incomum são os comandos protegidos, que tem a
seguinte forma original:
if <expressão booleana> → <instrução>
[] <expressão booleana> → <instrução>
[] ...
fi

A instrução executada é escolhida de forma não determinística dentre as demarcadas por expressões
verdadeiras.

É uma construção interessante para programação concorrente.

2.5 Subprogramas
São essenciais para a abstração de um programa, permitindo que processos completos possam ser
abstraídos numa entidade única e reusados em vários contextos. Ajudam a ressaltar a estrutura geral
de um programa.

É desejável permitir a compilação de subprogramas para criação de bibliotecas (também chamadas
de “pacotes”).

2.5.1 Fundamentos dos subprogramas

2.5.1.1 Características gerais
Subprogramas (exceto as co-rotinas), tem as seguintes características:

• um único ponto de entrada;

• o início da execução suspende a execução da unidade chamadora;

• o término da execução faz a execução da unidade chamadora continuar.

prof. Bruno Schneider 17

Notas de Aula de GCC105 - BCC e BSI - UFLA

2.5.1.2 Definições básicas
Uma “definição de subprograma” descreve a interface (forma para trocar informações com o
chamador) e o processo (ações). Também chamado de “implementação”.

Uma “chamada a subprograma” é a solicitação para executar o processo.

Um subprograma está “ativo” se a sua execução começou mas ainda não terminou.

Uma “declaração de subprograma” (também chamada de “cabeçalho”, “declaração avançada” ou
“protótipo”) identifica um bloco como sendo um subprograma (geralmente por meio de uma
palavra especial) de um determinado tipo (ex.: procedimento/função), dá um nome para ele e (com
exceção de algumas poucas linguagens) identifica seus parâmetros. Pode vir separada da definição,
para fins de verificação estática de tipos.

Os parâmetros, quando vistos como instâncias de valores ou no ponto de vista da unidade
chamadora, são chamados “argumentos”. Também podem ser chamados, respectivamente, de
“parâmetros formais” e “parâmetros reais”.

O “perfil de parâmetro” é o número, a ordem e os tipos dos parâmetros.

O “protocolo” de um subprograma é o “perfil