• Nenhum resultado encontrado

A instrução de seleção dupla if else

No documento C++ Como Programar - 5ª Edição - Original (páginas 137-146)

4.8 Formulando algoritmos: repetição controlada por contador

4.9 Formulando algoritmos: repetição controlada por sentinela

4.10 Formulando algoritmos: instruções de controle aninhadas

4.11 Operadores de atribuição

4.12 Operadores de incremento e decremento

4.13 Estudo de caso de engenharia de software: identificando atributos de classe no sistema ATM (opcional)

4.14 Síntese

Resumo | Terminologia | Exercícios de revisão | Respostas dos exercícios de revisão | Exercícios

4.1 Introdução

Antes de escrever um programa para resolver um problema, devemos ter um entendimento completo do problema e uma abordagem cuidadosamente planejada para resolvê-lo. Ao escrever um programa, também devemos entender os tipos de blocos de construção que estão disponíveis e empregar técnicas comprovadas de construção de programa. Neste capítulo e no Capítulo 5, “Instruções de controle: parte 2”, discutimos essas questões na apresentação da teoria e princípios da programação estruturada. Os conceitos apresentados aqui são cruciais para construir classes eficientes e manipular objetos.

Neste capítulo introduzimos as instruções if, if...else e while do C++, três dos blocos de construção que permitem aos pro- gramadores especificar a lógica requerida para que funções-membro realizem suas tarefas. Dedicamos uma parte deste capítulo (e os capítulos 5 e 7) para desenvolver em mais detalhes a classe GradeBook introduzida no Capítulo 3. Em particular, adicionamos uma função-membro à classe GradeBook que utiliza as instruções de controle para calcular a média de um conjunto de notas de alunos. Outro exemplo demonstra maneiras adicionais de combinar instruções de controle para resolver um problema semelhante. Introduzimos os operadores de atribuição do C++ e exploramos os operadores de incremento e decremento do C++. Esses operadores adicionais abreviam e simplificam muitas instruções de programa.

4.2 Algoritmos

Qualquer problema de computação solucionável pode ser resolvido pela execução de uma série de ações em uma ordem específica. Um procedimento para resolver um problema em termos de

1. ações a executar e

2. ordem em que essas ações executam

é chamado algoritmo. O exemplo a seguir demonstra que é importante especificar corretamente a ordem em que as ações executam. Considere o ‘algoritmo cresça e brilhe’ seguido por um executivo júnior para sair da cama e ir trabalhar: (1) levantar-se da cama, (2) tirar o pijama, (3) tomar banho, (4) vestir-se, (5) tomar o café da manhã, (6) dirigir o carro até o trabalho. Essa rotina leva o executivo a trabalhar bem preparado para tomar decisões críticas. Suponha que os mesmos passos sejam seguidos em uma ordem um pouco diferente: (1) levantar-se de cama, (2) tirar o pijama, (3) vestir-se, (4) tomar banho, (5) tomar o café da manhã, (6) dirigir o carro até o trabalho. Nesse caso, nosso executivo júnior aparece molhado no trabalho. Especificar a ordem em que as instruções (ações) são executadas em um programa de computador é chamado controle do programa. Este capítulo investiga o controle de programa utilizando as instruções de controle do C++.

4.3 Pseudocódigo

Pseudocódigo (ou código ‘fictício’) é uma linguagem artificial e informal que ajuda os programadores a desenvolver algoritmos sem a preocupação com os rigorosos detalhes da sintaxe de linguagem C++. O pseudocódigo que apresentamos aqui é particularmente útil para desenvolver algoritmos que serão convertidos em partes estruturadas de programas C++. O pseudocódigo é similar à língua cotidiana; é conveniente e amigável ao usuário embora não seja uma linguagem de programação de computador real.

Deitel_C++_Cap04.indd 94

95

O pseudocódigo não é executado nos computadores. Mais exatamente, ele ajuda o programador a ‘estudar’ um programa antes de tentar escrevê-lo em uma linguagem de programação como C++. Este capítulo fornece vários exemplos de como utilizar o pseudocódigo para desenvolver programas C++.

O estilo do pseudocódigo que apresentamos consiste puramente em caracteres, de modo que os programadores possam digitar o pseudocódigo convenientemente, utilizando um programa editor qualquer. O computador pode produzir uma nova cópia impressa de um programa em pseudocódigo sob demanda. Um programa em pseudocódigo cuidadosamente preparado pode ser facilmente convertido em um programa C++ correspondente. Em muitos casos, isso simplesmente requer a substituição de instruções em pseu- docódigo por equivalentes em C++.

O pseudocódigo normalmente descreve apenas instruções executáveis, que fazem com que ações específicas ocorram depois que um programador converte um programa do pseudocódigo em C++ e o programa é executado em um computador. As declarações (que não têm inicializadores ou não envolvem chamadas de construtor) não são instruções executáveis. Por exemplo, a declaração

int i;

informa ao compilador o tipo da variável i e o instrui a reservar espaço na memória para a variável. Essa declaração não faz com que qualquer ação — como entrada, saída ou cálculo — ocorra quando o programa é executado. Em geral, não incluímos declarações de variáveis no nosso pseudocódigo. Entretanto, alguns programadores optam por listar as variáveis e mencionar seus propósitos no começo dos programas em pseudocódigo.

Agora examinamos um exemplo em pseudocódigo que pode ser escrito para ajudar um programador a criar o programa de adição da Figura 2.5. Esse pseudocódigo (Figura 4.1) corresponde ao algoritmo que insere dois inteiros a partir do usuário, adiciona esses inteiros e exibe sua soma. Embora mostremos a listagem completa em pseudocódigo aqui, mostraremos como criar pseudocódigo a partir da declaração de um problema mais adiante no capítulo.

As linhas 1–2 correspondem às instruções nas linhas 13–14 da Figura 2.5. Note que as instruções em pseudocódigo são simplesmente instruções em linguagem natural que expressam qual é a tarefa a ser realizada em C++. Da mesma forma, as linhas 4–5 correspondem às instruções nas linhas 16–17 da Figura 2.5 e as linhas 7–8 correspondem às instruções nas linhas 19 e 21 da Figura 2.5.

Há alguns aspectos importantes do pseudocódigo na Figura 4.1. Note que o pseudocódigo corresponde ao código somente na função

main. Isso ocorre porque o pseudocódigo é normalmente utilizado para algoritmos, não para programas completos. Nesse caso, o pseu- docódigo é utilizado para representar o algoritmo. A função em que esse código é colocado não é importante para o algoritmo em si. Pela mesma razão, a linha 23 da Figura 2.5 (a instrução return) não é incluída no pseudocódigo — essa instrução return é colocada no final de cada função main e não é importante para o algoritmo. Por fim, as linhas 9–11 da Figura 2.5 não são incluídas no pseudocódigo porque essas declarações de variável não são instruções executáveis.

4.4 Estruturas de controle

Normalmente, instruções em um programa são executadas uma após a outra na ordem em que são escritas. Isso é chamado execução seqüencial. Várias instruções C++ que discutiremos em breve permitem ao programador especificar que a próxima instrução a executar pode ser diferente da próxima instrução na seqüência. Isso é chamado transferência de controle.

Durante a década de 1960 tornou-se claro que a utilização indiscriminada de transferências de controle era a raiz de muitas dificul- dades experimentadas por grupos de desenvolvimento de software. A culpada disso é a instruçãogoto, que permite ao programador especificar uma transferência de controle para um de vários possíveis destinos em um programa (criando o que é freqüentemente chamado de ‘código espaguete’). A noção da chamada programação estruturada tornou-se quase sinônimo de ‘eliminação do goto’.

A pesquisa de Böhm e Jacopini1 demonstrou que poderiam ser escritos programas sem nenhuma instrução goto. Tornou-se o desafio da era para programadores mudar seus estilos para ‘programação sem goto’. Mas foi só na década de 1970 que os programadores come- çaram a tratar programação estruturada seriamente. Os resultados foram impressionantes, pois grupos de desenvolvimento de software informaram que tinham reduzido o tempo de desenvolvimento, que a entrega de sistemas ocorria com mais freqüência dentro do prazo e

1 Solicite que o usuário insira o primeiro inteiro 2 Insira o primeiro inteiro

3

4 Solicite que o usuário insira o segundo inteiro 5 Insira o segundo inteiro

6

7 Some o primeiro e o segundo inteiros, armazene o resultado 8 Exiba o resultado

Figura 4.1 Pseudocódigo para o programa de adição da Figura 2.5.

1

Böhm, C., & G. Jacopini, “Flow diagrams, turing machines, and languages with only two formation rules”, Communications of the ACM, Vol. 9, No. 5, maio de 1966, p. 366–371.

4.4 Estruturas de controle

Deitel_C++_Cap04.indd 95

que a conclusão do projeto de software ocorria com mais freqüência dentro do orçamento. A chave para esses sucessos é que programas estruturados são mais claros, mais fáceis de depurar, testar e modificar e menos propensos a conter bugs.

O trabalho de Böhm e Jacopini demonstrou que todos os programas poderiam ser escritos em termos de somente três estruturas de controle, a saber, a estrutura de seqüência, a estrutura de seleção e a estrutura de repetição. O termo ‘estruturas de controle’ vem do campo da ciência da computação. Quando introduzirmos as implementações de estruturas de controle do C++, iremos nos referir a eles seguindo a terminologia do documento-padrão do C++2 como ‘instruções de controle’.

Estrutura de seqüência em C++

A estrutura de seqüência é construída no C++. A menos que instruído de outra maneira, o computador executa as instruções C++ uma depois da outra na ordem em que elas são escritas — isto é, em seqüência. O diagrama de atividades Unified Modeling Language (UML) da Figura 4.2 ilustra uma típica estrutura de seqüência em que dois cálculos são realizados na ordem. O C++ permite ter quantas ações quisermos em uma estrutura de seqüência. Como veremos logo, uma única ação pode ser colocada em qualquer lugar do código e também podemos colocar várias ações em seqüência.

Nessa figura, as duas instruções envolvem adicionar uma nota a uma variável total e adicionar o valor 1 a uma variável counter. Tais instruções podem aparecer em um programa que aceita a média das notas de vários alunos. Para calcular uma média, o total das notas cuja média está sendo calculada é dividido pelo número de notas. Uma variável contadora seria utilizada para monitorar o número de valores cuja média está sendo calculada. Você verá instruções semelhantes no programa da Seção 4.8.

Os diagramas de atividades são parte da UML. Um diagrama de atividades modela o fluxo de trabalho (também chamado ativi- dade) de uma parte de um sistema de software. Esses fluxos de trabalho podem incluir uma parte de um algoritmo, como a estrutura de seqüência na Figura 4.2. Os diagramas de atividades são compostos de símbolos de uso especial, como símbolos de estado de ação (um retângulo com seus lados esquerdo e direito substituídos por arcos que se curvam para fora), losangos e círculos pequenos; esses símbolos são conectados por setas de transição, que representam o fluxo da atividade.

Como ocorre com o pseudocódigo, diagramas de atividades ajudam os programadores a desenvolver e representar algoritmos, embora muitos programadores prefiram o pseudocódigo. Os diagramas de atividades mostram claramente como operam as estruturas de controle.

Considere o diagrama de atividades de estrutura de seqüência da Figura 4.2. Ele contém dois estados de ações que representam ações a realizar. Cada estado da ação contém uma expressão de ação — por exemplo, “adicionar grade a total” ou “adicionar 1 a counter” — que especifica uma ação particular a realizar. Outras ações poderiam incluir cálculos ou operações de entrada e saída. As setas no diagrama de atividades são chamadas de setas de transição. Essas setas representam transições, que indicam a ordem em que ocorrem as ações representadas pelos estados de ação — o programa que implementa as atividades ilustradas pelo diagrama de atividades na Figura 4.2 primeiro adiciona grade a total, e, então, adiciona 1 a counter.

O círculo sólido localizado na parte superior do diagrama de atividades representa o estado inicial da atividade — o início do fluxo de trabalho antes de o programa realizar as atividades modeladas. O círculo sólido cercado por um círculo vazio que aparece na parte inferior do diagrama de atividades representa o estado final — o fim do fluxo de trabalho depois que o programa realiza suas atividades.

A Figura 4.2 também inclui retângulos com os cantos superiores direitos dobrados. Essas são chamadas notas na UML. As notas são observações explanatórias que descrevem o propósito dos símbolos no diagrama. As notas podem ser utilizadas em qualquer diagrama UML — não só em diagramas de atividades. A Figura 4.2 utiliza notas da UML para mostrar o código C++ associado ao estado de cada ação no diagrama de atividades. Uma linha pontilhada conecta cada nota ao elemento que a nota descreve. Os diagramas de atividades normalmente não mostram o código C++ que implementa a atividade. Aqui, utilizamos notas para esse propósito a fim de ilustrar como os diagramas se relacionam ao código C++. Para informações adicionais sobre a UML, veja nosso estudo de caso opcional, que aparece nas seções “Estudo de caso de engenharia de software” no final dos capítulos 1–7, 9, 10, 12 e 13 ou visite www.uml.org.

2

Esse documento é mais especificamente conhecido como NCITS/ISO/IEC 14882-2003 Programming languages — C++ e está disponível para download (por uma taxa) em: webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+14882%2D2003.

Figura 4.2 Diagrama de atividades da estrutura de seqüência. adicionar 1 a counter

adicionar grade a total Instrução C++ correspondente: total = total + grade;

Instrução C++ correspondente: counter = counter + 1;

Deitel_C++_Cap04.indd 96

97

Instruções de seleção em C++

O C++ fornece três tipos de instruções de seleção (discutidos neste capítulo e no Capítulo 5). A instrução de seleção if realiza (se- leciona) uma ação se uma condição (predicado) for verdadeira, ou pula a ação se a condição for falsa. A instrução de seleção if...

else realiza uma ação se uma condição for verdadeira, ou realiza uma ação diferente se a condição for falsa. A instrução de seleção

switch (Capítulo 5) realiza uma de muitas ações diferentes, dependendo do valor de uma expressão do tipo inteiro.

A instrução de seleção if é uma instrução de uma única seleção porque seleciona ou ignora uma única ação (ou, como veremos a seguir, um único grupo de ações). A instrução if...else é chamada instrução de seleção dupla porque seleciona entre duas ações dife- rentes (ou grupos de ações). A instrução de seleção switch é chamada de instrução de seleção múltipla, uma vez que seleciona entre muitas ações diferentes (ou grupos de ações).

Instruções de repetição em C++

O C++ fornece três tipos de instruções de repetição (também chamadas de instruções de loops ou loops) que permitem aos programas realizar instruções repetidamente se uma condição (chamada de condição de continuação de loop) permanecer verdadeira. As instruções de repetição são as instruções while, do...while e for. (O Capítulo 5 apresenta as instruções do...while e for.) As instruções while

e for realizam a ação (ou grupo de ações) no seu corpo zero ou mais vezes — se a condição de continuação de loop for inicialmente falsa, a ação (ou grupo de ações) não será executada. A instrução do...while realiza a ação (ou grupo de ações) no seu corpo pelo menos uma vez.

Cada uma das palavras if, else, switch, while, do e for é uma palavra-chave C++. Essas palavras são reservadas pela linguagem de programação C++ para implementar vários recursos, como instruções de controle do C++. As palavras-chave não devem ser utilizadas como identificadores, como nomes de variável. A Figura 4.3 contém uma lista completa de palavras-chave do C++.

Erro comum de programação 4.1

Utilizar uma palavra-chave como um identificador é um erro de sintaxe.

Palavras-chave do C++

Palavras-chave comuns às linguagens de programação C e C++

auto break case char const

continue default do double else

enum extern float for goto

if int long register return

short signed sizeof static struct

switch typedef union unsigned void

volatile while

Palavras-chave do C++ somente

and and_eq asm bitand bitor

bool catch class compl const_cast

delete dynamic_cast explicit export false

friend inline mutable namespace new

not not_eq operator or or_eq

private protected public reinterpret_cast static_cast

template this throw true try

typeid typename using virtual wchar_t

xor xor_eq

Figura 4.3 Palavras-chave do C++.

4.4 Estruturas de controle

Deitel_C++_Cap04.indd 97

Erro comum de programação 4.2

Escrever uma palavra-chave com alguma letra maiúscula é um erro de sintaxe. Todas as palavras-chave do C++ têm apenas letras minúsculas.

Resumo de instruções de controle em C++

O C++ contém somente três tipos de estruturas de controle, que daqui para a frente chamaremos instruções de controle: a instrução de seqüência, instruções de seleção (três tipos — if , if...else e switch) e instruções de repetição (três tipos — while, for e do...while). Todo programa C++ combina quantas dessas instruções de controle for apropriado para o algoritmo que o programa implementa. Como ocorre com a instrução de seqüência da Figura 4.2, você pode modelar cada instrução de controle como um diagrama de atividades. Cada diagrama contém um estado inicial e um estado final, que representam um ponto de entrada e um ponto de saída da instrução de controle, respectivamente. Essas instruções de controle de entrada única/saída única facilitam a construção de programas — as instruções de controle são vinculadas conectando-se o ponto de saída de uma instrução ao ponto de entrada da seguinte. Isso é semelhante à maneira como uma criança empilha blocos de construção, portanto chamamos isso de empilhamento de instruções de controle. Aprenderemos em breve que há somente uma outra maneira de conectar instruções de controle — chamada de aninhamento de instrução de controle, em que uma instrução de controle está contida dentro de outra. Portanto, algoritmos nos programas C++ são construídos a partir de apenas três tipos de instruções de controle, combinadas apenas de duas maneiras. Isso é a essência da simplicidade.

Observação de engenharia de software 4.1

Qualquer programa C++ que criemos pode ser construído a partir de apenas sete tipos de instruções de controle diferentes (se- qüência, if, if...else, switch, while, do...while e for) combinados apenas de duas maneiras (empilhamento de instruções de controle e aninhamento de instruções de controle).

4.5 Instrução de seleção if

Os programas utilizam instruções de seleção para escolher entre cursos alternativos de ações. Por exemplo, suponha que a nota de aprovação de um exame seja 60. A instrução em pseudocódigo

Se a nota do aluno for maior que ou igual a 60 Imprima ‘Passed’

determina se a condição ‘a nota do aluno for maior que ou igual a 60’ é true (verdadeira) ou false (falsa). Se a condição for true, então ‘Passed’ é impresso e a próxima instrução em pseudocódigo é ‘realizada’ (lembre-se de que pseudocódigo não é uma linguagem de programação real). Se a condição for false, a instrução de impressão é ignorada e a próxima instrução em pseudocódigo na seqüência é realizada. Observe que a segunda linha dessa instrução de seleção está recuada. Esse recuo é opcional, mas é recomendado uma vez que enfatiza a estrutura inerente de programas estruturados. Quando você converte o pseudocódigo em código C++, o compilador C++ ignora caracteres de espaço em branco (como espaços em branco, tabulações e nova linha) utilizados para recuo e espaçamento vertical.

Boa prática de programação 4.1

Aplicar consistentemente convenções razoáveis de recuo ao longo de todos os seus programas melhora significativamente a legibili- dade do programa. Sugerimos três espaços por recuo. Algumas pessoas preferem utilizar tabulações, mas estas podem variar de um editor para outro, fazendo com que um programa escrito em um editor seja alinhado diferentemente quando utilizado com outro. A instrução Se do pseudocódigo precedente pode ser escrita em C++ como

if ( grade >= 60 ) cout << “Passed”;

Note que o código C++ apresenta uma íntima correspondência com o pseudocódigo. Essa é uma das propriedades do pseudocódigo que torna essa ferramenta de desenvolvimento de programas tão útil.

A Figura 4.4 ilustra a instrução if de uma única seleção. Ele contém o que talvez seja o símbolo mais importante em um diagrama de atividades — o losango, ou símbolo de decisão, que indica que uma decisão deve ser tomada. O símbolo de decisão indica que o fluxo de trabalho continuará por um caminho determinado pelas condições de guarda do símbolo associado, as quais podem ser verdadeiras ou falsas. Cada seta de transição que sai de um símbolo de decisão tem uma condição de guarda (especificada entre colchetes acima ou ao lado da seta de transição). Se uma condição de guarda for verdadeira, o fluxo de trabalho entra no estado de ação para o qual a seta de transição aponta. Na Figura 4.4, se a nota for maior que ou igual a 60, o programa imprime ‘Passed’ na tela, e, em seguida, passa para o estado final dessa atividade. Se a nota for menor que 60, o programa se dirige imediatamente para o estado final sem exibir uma mensagem.

Aprendemos no Capítulo 1 que as decisões podem ser baseadas em condições contendo operadores relacionais ou de igualdade. De fato, em C++, uma decisão pode ser baseada em qualquer expressão — se a expressão é avaliada como zero, ela é tratada como falsa;

No documento C++ Como Programar - 5ª Edição - Original (páginas 137-146)

Documentos relacionados