• Nenhum resultado encontrado

Exemplos com a estrutura for

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

Os seguintes exemplos mostram métodos de variação de variável de controle em uma instrução for. Em cada caso, escrevemos o cabe- çalho da instrução for apropriado. Observe a alteração no operador relacional para loops que decrementam a variável de controle.

a) Altere a variável de controle de 1 a 100 em incrementos de 1.

for ( int i = 1; i <= 100; i++ )

b) Altere a variável de controle de 100 para baixo até 1 em incrementos de -1 (isto é, decrementos de 1).

for ( int i = 100; i >= 1; i-- )

c) Altere a variável de controle de 7 a 77 em passos de 7.

for ( int i = 7; i <= 77; i += 7 )

d) Altere a variável de controle de 20 para baixo até 2 em passos de -2.

for ( int i = 20; i >= 2; i -= 2 )

e) Altere a variável de controle sobre a seguinte seqüência de valores: 2, 5, 8, 11, 14, 17, 20.

for ( int i = 2; i <= 20; i += 3 )

f) Altere a variável de controle sobre a seguinte seqüência de valores: 99, 88, 77, 66, 55, 44, 33, 22, 11, 0.

for ( int i = 99; i >= 0; i -= 11 )

Erro comum de programação 5.6

Não utilizar o operador relacional adequado na condição de continuação do loop de um loop que conta para baixo (como utilizar incorretamente i <= 1 em vez de i >= 1 em um loop que conta para baixo até 1) é normalmente um erro de lógica que leva a resultados incorretos quando o programa executa.

Aplicativo: somando os inteiros pares de 2 a 20

Os dois próximos exemplos fornecem aplicações simples da instrução for. O programa da Figura 5.5 utiliza uma instrução for para somar os inteiros de 2 a 20. Cada iteração do loop (linhas 12–13) adiciona o valor atual da variável de controle number à variável total.

Figura 5.4 Diagrama de atividades UML para a instrução for na Figura 5.2. Determina se o loop deve continuar [counter > 10] [counter <= 10] int counter = 1 counter++ Exibe o valor do contador Inicializa variável de controle Incrementa a variável de controle cout << counter << " "; Deitel_C++_Cap05.indd 146 Deitel_C++_Cap05.indd 146 15/4/2006 13:23:2115/4/2006 13:23:21

147

Observe que o corpo da instrução for na Figura 5.5 não poderia ser realmente fundido na parte de incremento do cabeçalho for

utilizando o operador vírgula como mostrado a seguir:

for ( int number = 2; // inicialização

number <= 20; // condição de continuação do loop total += number, number += 2 ) // total e incremento ; // corpo vazio

Boa prática de programação 5.6

Embora as instruções que precedem um for e as instruções no corpo de um for possam ser freqüentemente fundidas no cabeçalho

for, fazer isso pode tornar o programa mais difícil de ler, manter, modificar e depurar.

Boa prática de programação 5.7

Limite o tamanho dos cabeçalhos da instrução de controle a uma única linha, se possível. Aplicativo: cálculos de juros compostos

O próximo exemplo calcula os juros compostos utilizando uma instrução for. Considere a seguinte declaração do problema:

Uma pessoa investe $ 1.000,00 em uma conta-poupança que rende 5% de juros. Supondo que todos os juros sejam deixados na conta, calcule e imprima o valor em dinheiro na conta ao fim de cada ano durante 10 anos. Utilize a seguinte fórmula para determinar essas quantidades:

a = p (1 + r)n

onde

p é a quantidade original investida (isto é, o principal) r é a taxa de juros anual

n é o número de anos e

a é a quantidade em depósito no fim do n-ésimo ano

Esse problema envolve um loop que realiza o cálculo indicado para cada um dos 10 anos que o dinheiro permanece em depósito. A solução é mostrada na Figura 5.6.

A instrução for (linhas 28–35) executa o seu corpo 10 vezes, alterando uma variável de controle de 1 a 10 em incrementos de 1. O C++ não inclui um operador de exponenciação, portanto utilizamos a função de biblioteca-padrãopow (linha 31) para esse propósito. A função pow( x, y ) calcula o valor de x elevado à yésima potência. Nesse exemplo, a expressão algébrica (1 + r)n é escrita como

pow( 1.0 + rate, year ), onde a variável rate representa r e a variável year representa n. A função pow aceita dois argumentos do tipo double e retorna um valor double.

1 // Figura 5.5: fig05_05.cpp

2 // Somando inteiros com a instrução for. 3 #include <iostream> 4 using std::cout; 5 using std::endl; 6 7 int main() 8 {

9 int total = 0; // inicializa o total 10

11 // total de inteiros pares de 2 a 20

12 for ( int number = 2; number <= 20; number += 2 ) 13 total += number;

14

15 cout << “Sum is “ << total << endl; // exibe resultados 16 return 0; // terminação bem-sucedida

17 } // fim de main

Sum is 110

Figura 5.5 Somando inteiros com a instrução for.

5.4 Exemplos com a estrutura for

Deitel_C++_Cap05.indd 147

1 // Figura 5.6: fig05_06.cpp

2 // Cálculos de juros compostos com for. 3 #include <iostream> 4 using std::cout; 5 using std::endl; 6 using std::fixed; 7 8 #include <iomanip>

9 using std::setw; // permite que o programa configure a largura de um campo 10 using std::setprecision;

11

12 #include <cmath> // biblioteca de matemática C++ padrão 13 using std::pow; // permite ao programa utilizar a função pow 14

15 int main() 16 {

17 double amount; // quantia em depósito ao fim de cada ano 18 double principal = 1000.0; // quantia inicial antes dos juros 19 double rate = .05; // taxa de juros

20

21 // exibe cabeçalhos

22 cout << “Year” << setw( 21 ) << “Amount on deposit” << endl; 23

24 // configura o formato de número de ponto flutuante 25 cout << fixed << setprecision( 2 );

26

27 // calcula quantia de depósito para cada um dos dez anos 28 for ( int year = 1; year <= 10; year++ )

29 {

30 // calcula nova quantia durante ano especificado 31 amount = principal * pow( 1.0 + rate, year ); 32

33 // exibe o ano e a quantia

34 cout << setw( 4 ) << year << setw( 21 ) << amount << endl; 35 } // fim do for

36

37 return 0; // indica terminação bem-sucedida 38 } // fim de main

Year Amount on deposit

1 1050.00 2 1102.50 3 1157.63 4 1215.51 5 1276.28 6 1340.10 7 1407.10 8 1477.46 9 1551.33 10 1628.89

Figura 5.6 Cálculos de juros compostos com for.

Esse programa não compilará sem incluir arquivo de cabeçalho <cmath> (linha 12). A função pow requer dois argumentos double. Observe que year é um inteiro. O cabeçalho <cmath> inclui informações que instruem o compilador a converter o valor de year em uma representação double temporária antes de chamar a função. Essas informações estão contidas no protótipo da função pow. O Capítulo 6 fornece um resumo de outras funções de biblioteca de matemática.

Deitel_C++_Cap05.indd 148

149

Erro comum de programação 5.7

Em geral, esquecer de incluir o arquivo de cabeçalho apropriado ao utilizar funções de biblioteca-padrão (por exemplo, <cmath>

em um programa que utiliza funções de biblioteca de matemática) é um erro de compilação. Uma nota de atenção sobre o uso do tipo double para valores monetários

Note que as linhas 17–19 declaram as variáveis amount, principal e rate como tipo double. Fizemos isso para simplificar porque estamos lidando com partes fracionárias de valores monetários e precisamos de um tipo que permita pontos decimais em seus valores. Infelizmente, isso pode causar problema. Eis uma explicação simples do que pode dar errado ao utilizar float ou double para repre- sentar quantias monetárias (supondo que setprecision( 2 ) é utilizado para especificar dois dígitos de precisão na impressão): duas quantias monetárias armazenadas na máquina poderiam ser 14,234 (que é impressa como 14,23) e 18,673 (que é impressa como 18,67). Quando são adicionadas, essas quantidades produzem a soma interna 32,907, que é impressa como 32,91. Assim, sua impressão poderia se parecer com

14.23 + 18.67 --- 32.91

mas uma pessoa que adiciona os números individuais como impressos esperaria a soma 32,90! Você foi avisado!

Boa prática de programação 5.8

Não utilize variáveis de tipo float ou double para realizar cálculos monetários. A imprecisão de números de ponto flutuante pode causar erros que resultam em valores monetários incorretos. Nos Exercícios, exploramos o uso de inteiros para realizar cálculos monetários. [Nota: Alguns fornecedores independentes vendem bibliotecas de classes C++ que realizam cálculos monetários precisos. Incluímos vários URLs no Apêndice I.]

Utilizando manipuladores de fluxo para formatar a saída numérica

A instrução de saída na linha 25 antes do loop for e a instrução de saída na linha 34 no loop for se combinam para imprimir os valores das variáveis year e amount com a formatação especificada pelos manipuladores de fluxo parametrizado setprecision e setw e o ma- nipulador de fluxo não parametrizado fixed. O manipulador de fluxo setw( 4 ) especifica que a próxima saída de valor deve aparecer em uma largura de campo de 4 — isto é, cout imprime o valor com pelo menos 4 posições de caractere. Se o valor a ser enviado para a saída for menor do que a largura de 4 posições de caractere, o valor é alinhado à direita no campo por padrão. Se o valor a ser enviado para saída tiver mais de 4 caracteres, a largura de campo é estendida para acomodar o valor inteiro. Para indicar que a saída dos valores deve ser alinhada à esquerda, simplesmente gere a saída do manipulador de fluxo não parametrizado left (localizado no cabeçalho

<iostream>). O alinhamento à direita pode ser restaurado gerando a saída do manipulador de fluxo não parametrizado right. A outra formatação nas instruções de saída indica que a variável amount é impressa como um valor de ponto fixo com um ponto de fração decimal (especificado na linha 25 com o manipulador de fluxo fixed) alinhado à direita em um campo de 21 posições de caractere (especificadas na linha 34 com setw( 21 )) e dois dígitos de precisão à direita do ponto de fração decimal (especificado na linha 25 com o manipulador setprecision( 2 )). Aplicamos os manipuladores de fluxo fixed e setprecision ao fluxo de saída (isto é, cout) antes do loop for porque essas configurações de formato permanecem em vigor até serem alteradas — tais configurações são chamadas configurações aderentes. Portanto, elas não precisam ser aplicadas durante cada iteração do loop. Entretanto, a largura de campo especificada com setw se aplica somente à próxima saída de valor. Discutimos as poderosas capacidades de formatação de entrada/saída do C++ em detalhes no Capítulo 15.

Observe que o cálculo 1.0 + rate, que aparece como um argumento para a função pow, está contido no corpo da instrução for. De fato, esse cálculo produz o mesmo resultado durante cada iteração do loop, então repeti-lo é um desperdício — ele deve ser realizado uma vez antes do loop.

Dica de desempenho 5.1

Evite colocar expressões cujos valores não mudam dentro de loops — mas, mesmo se você colocá-las, muitos dos compiladores de otimização sofisticados de hoje irão, automaticamente, colocar essas expressões fora dos loops no código de linguagem de máquina gerado.

Dica de desempenho 5.2

Muitos compiladores contêm recursos de otimização que aprimoram o desempenho do código que você escreve, mas ainda é melhor escrever direito o código desde o início.

Por diversão, não deixe de experimentar o problema de Peter Minuit no Exercício 5.29. Esse problema demonstra as maravilhas dos juros compostos.

5.4 Exemplos com a estrutura for

Deitel_C++_Cap05.indd 149

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

Documentos relacionados