Baixe o app para aproveitar ainda mais
Prévia do material em texto
GCC 105 – LINGUAGENS DE PROGRAMAÇÃO I AULA 11 – Controle de Fluxo 1º Semestre de 2015 Prof. Janderson Rodrigo de Oliveira Universidade Federal de Lavras Departamento de Ciência da Computação Introdução • Computações em programas escritos em linguagens imperativas são realizadas por meio de expressões e da atribuição dos valores resultantes a variáveis. • Contudo, existem poucos programas úteis compostos inteiramente por sentenças de atribuição. • No mínimo, dois mecanismos linguísticos adicionais são necessários para tornar as computações nos programas mais flexíveis e poderosas. Introdução 1. Alguma forma de selecionar entre caminhos alternativos de fluxo de controle 2. Uma forma de causar a execução repetida de sentenças ou de sequências de sentenças. • Sentenças que fornecem tais tipos de capacidade são chamadas de sentenças de controle. • Uma estrutura de controle é uma sentença de controle e a coleção de sentenças cuja execução ela concorda. Sentenças de Seleção • Uma sentença de seleção fornece os meios para escolher entre dois ou mais caminhos de execução em um programa. • Sentenças de seleção caem em duas categorias gerais: 1. Dois caminhos; 2. n caminhos, ou seleção múltipla. Sentenças de Seleção • Sentenças de seleção de dois caminhos – Apesar das sentenças de seleção de dois caminhos das linguagens imperativas contemporâneas serem bastante similares, existem algumas variações em seus projetos. – A forma geral de um seletor de dois caminhos é: if expressão_de_controle cláusula então cláusula senão Sentenças de Seleção • Sentenças de seleção de dois caminhos – Expressões de controle são especificadas entre parênteses se a palavra reservada then (ou algum outro marcador sintático) não for usado para introduzir a cláusula então. – No C89, que não tinha um tipo de dados booleano, as expressões aritméticas eram usadas como expressões de controle. – Isso também pode ser feito em Python, C99 e C++. Entretanto, nestas linguagens, tanto expressões aritméticas quanto booleanas podem ser usadas. Sentenças de Seleção • Sentenças de seleção de dois caminhos – Em muitas linguagens contemporâneas, as cláusulas então e senão aparecem ou como sentenças simples ou como sentenças compostas. – As linguagens baseadas em C usam chaves para formar sentenças compostas. – Python usa indentação para especificar sentenças compostas: if x > y : x = y print “caso 1” Sentenças de Seleção • Sentenças de seleção de dois caminhos – Um problema pode aparecer quando tem-se sentenças de seleção aninhadas. – Quando uma construção de seleção é aninhada na cláusula então de uma outra construção de seleção, não é claro a qual if uma cláusula senão deve ser associada. – Considere o seguinte código parecido com Java: if (soma == 0) if (contador == 0) resultado = 0; else resultado = 1 Sentenças de Seleção • Sentenças de seleção de dois caminhos – Essa construção pode ser interpretada de duas maneiras, dependendo se a cláusula senão casa com a primeira cláusula então ou com a segunda. – Com a exceção de Python, a indentação não tem efeito na semântica das linguagens contemporâneas e é ignorada pelo seus compiladores. Sentenças de Seleção • Sentenças de seleção de dois caminhos – Em Java, como em outras linguagens imperativas, a semântica estática da linguagem especifica que a cláusula senão sempre casa com a cláusula então anterior mais próxima que ainda não está casada. – Para forçar a semântica alternativa em Java, o if interno é colocado em uma sentença composta, como em: if (soma == 0){ if (contador == 0) resultado = 0; } else resultado = 1 Sentenças de Seleção • Sentenças de seleção de dois caminhos – C, C++ e C# têm o mesmo problema de Java com o aninhamento de sentenças de seleção. – Como Perl requer que todas as cláusulas então e senão sejam compostas, a linguagem não sofre desse problema. Exemplo: if (soma == 0){ if (contador == 0){ resultado = 0; } }else{ resultado = 1 } Sentenças de Seleção • Construções de seleção múltipla – A construção de seleção múltipla permite a seleção de uma dentre qualquer número de sentenças ou de grupos de sentenças. – Ela pode ser vista como uma generalização de um seletor. Na verdade, seletores de dois caminhos podem ser construídos com um seletor múltiplo. – Apesar de um seletor múltiplo poder ser construído a partir de seletores de dois caminhos, as estruturas resultantes são deselegantes, não confiáveis e difíceis de serem lidas e escritas. Sentenças de Seleção • Construções de seleção múltipla – O construtor de seleção múltipla da linguagem C, o switch, que também é parte de C++, Java e JavaScript, é um projeto relativamente primitivo. Sua forma geral é: onde a expressão de controle e as expressões constantes são de algum tipo discreto. switch (expressão){ case expressão_constante_1 : sentença_1 ... case expressão_constante_n : sentença_n [default : sentença_n+1] } Sentenças de Seleção • Construções de seleção múltipla – O segmento opcional default é usado para valores não representados da expressão de controle. – A construção switch não fornece desvios implícitos no final de seus segmentos de código. Isso permite que o controle flua por mais de um segmento de código selecionável em uma única execução. – Considere o seguinte exemplo: Sentenças de Seleção • Construções de seleção múltipla – Em que casos a mensagem de erro é impressa? switch (indice){ case 1 : case 3 : impar += 1; somaImpar += indice; case 2 : case 4 : par += 1; somaPar += indice; default : printf(“Erro no switch\n”); } Sentenças de Seleção • Construções de seleção múltipla – Para separar logicamente os segmentos, um desvio explícito deve ser incluído. A sentença break é usada para restringir cada execução a um dado segmento selecionável. switch (indice){ case 1 : case 3 : impar += 1; somaImpar += indice; break; case 2 : case 4 : par += 1; somaPar += indice; break; default : printf(“Erro no switch\n”);} Sentenças de Seleção • Construções de seleção múltipla – Ocasionalmente, é conveniente permitir que o controle flua a partir de um segmento de código para outro. – O problema de confiabilidade com esse projeto surge quando a ausência errônea de uma sentença break em um segmento que permita que o controle flua incorretamente para o próximo segmento. – Estudos têm mostrado que a habilidade de fazer com que o controle flua de um segmento selecionável para outro é raramente usada. Sentenças de Seleção • Construções de seleção múltipla – A sentença switch de C praticamente não tem restrições a respeito do posicionamento das expressões case, tratadas como se fossem rótulos de sentenças normais. – Essa permissividade pode resultar em estruturas altamente complexas dentro do corpo da sentença switch. switch (x) default : if (primo(x)) case 2 : case 3: case 5: case 7: processo_Primo(x); else case 4: case 6: case 9: case 10: processo_NaoPrimo(x); Sentenças de Seleção • Construções de seleção múltipla – O switch em Java previne esse tipo de complexidade ao proibir que expressões case apareçam em qualquer lugar, exceto no nível superior do corpo switch. – Perl, Python e Lua não tem construções de seleção múltipla. Sentenças de Seleção • Seleção múltipla usando if – Em muitas situações, uma construção switch ou case é inadequada para seleção múltipla. – Por exemplo, quando as seleções devem ser feitas com base em uma expressão booleana em vez de por meio de algum tipo ordinal.– Nestes casos, os seletores aninhados de dois caminhos podem ser usados para simular um seletor múltiplo. Sentenças de Seleção • Seleção múltipla usando if – Para aliviar a legibilidade pobre de seletores de dois caminhos profundamente aninhados, algumas linguagens, como Perl e Python estenderam-no especificamente para esse uso. – O seletor aninhado é então chamado de uma cláusula elseif. – Considere a seguinte construção de seleção em Python (note que else if é escrito como elif em Python). Sentenças de Seleção • Seleção múltipla usando if – Este trecho de código seria equivalente ao código a seguir. if contador < 10 : valor1 = True; elif contador < 100 : valor2 = True; elif contador < 1000 : valor3 = True; Sentenças de Seleção • Seleção múltipla usando if – A versão else-if (a primeira) é a mais legível das duas. if contador < 10 : valor1 = True; else: if contador < 100 : valor2 = True; else: if contador < 1000 : valor3 = True; Sentenças de Seleção • Seleção múltipla usando if – Note que esse exemplo não é facilmente simulado com uma sentença switch, porque cada sentença selecionável é escolhida como base em uma expressão booleana. – Logo, a construção else-if não é uma forma redundante de switch. – Na verdade, nenhum dos seletores múltiplos em linguagens contemporâneas é tão geral quanto a construção if-then-else- if. Exercícios 1. Reescreva o seguinte segmento de código usando uma sentença de seleção múltipla: if ((k == 1) || (k == 2)) j = 2*k-1 if ((k == 3) || (k == 5)) j = 3*k+1 if ((k == 4) j = 4*k-1 if ((k == 6) || (k == 7) || (k == 8)) j = k-2 Exercícios 2. Considere o seguinte problema de programação: os valores de três variáveis inteiras – primeira, segunda e terceira – devem ser colocados em três variáveis max, meio e min, com os significados óbvios, sem usar subprogramas definidos pelo usuário ou pré-definidos. Escreva duas soluções para esse problema, uma que usa seleções aninhadas e outra que não as usa. Compare a complexidade e a legibilidade esperada das duas.
Compartilhar