estrutura de repetição - eisnt.org+/manuais/08_estruturas_repeticao.pdf · informa o número que...

38
Estrutura de Repetição Existem situações em que um problema exige ou apresenta como resolução um conjunto de instruções que devem ser executadas por mais de uma vez. Nesse capítulo, é apresentada essa estrutura como solução, as quais se dividem em: Repetição Contada, Repetição com Teste Condicional no Início e Repetição com Teste Condicional no Fim. 8.1 Conceitualização Existem várias possibilidades de iteração do usuário em uma lingua- gem visual. A técnica de programação disponibiliza três formas de re- petição: Repetição Contada, Repetição com Teste Condicional no Iní- cio e Repetição com Teste Condicional no Fim, além de o usuário poder interromper essa iteração a qualquer momento através de um recurso do componente. Em uma aplicação com interface visual, o usuário tem um poder maior de interação, podendo interromper um processo iterativo antes mesmo que ele acabe, bastando fechar a janela (se for permitido, é cla- ro) de sua aplicação, enquanto em uma aplicação de console é preciso que a repetição seja terminada pela estrutura. As estruturas de repetição aqui apresentadas, apesar de serem de- monstradas em aplicações que repetem a exibição de formulários, são mais recomendas para o processamento em lote de um conjunto de dados. Para processos iterativos em uma interface visual, recomenda-se o uso de flags, os quais têm a responsabilidade de verificar se o processo como um todo foi finalizado. Essa verificação deve ser feita nos eventos que capturem o encerramento da aplicação por parte do usuário atra- vés de estruturas como if ou switch/case.

Upload: vandang

Post on 22-Nov-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura

de Repetição

Existem situações em que um problema exige ou apresenta como resolução um conjunto de instruções que devem ser executadas por mais de uma vez.

Nesse capítulo, é apresentada essa estrutura como solução, as quais se dividem em: Repetição Contada, Repetição com Teste Condicional no Início e Repetição com Teste Condicional no Fim.

8.1 Conceitualização

Existem várias possibilidades de iteração do usuário em uma lingua-gem visual. A técnica de programação disponibiliza três formas de re-petição: Repetição Contada, Repetição com Teste Condicional no Iní-cio e Repetição com Teste Condicional no Fim, além de o usuário poder interromper essa iteração a qualquer momento através de um recurso do componente.

Em uma aplicação com interface visual, o usuário tem um poder maior de interação, podendo interromper um processo iterativo antes mesmo que ele acabe, bastando fechar a janela (se for permitido, é cla-ro) de sua aplicação, enquanto em uma aplicação de console é preciso que a repetição seja terminada pela estrutura.

As estruturas de repetição aqui apresentadas, apesar de serem de-monstradas em aplicações que repetem a exibição de formulários, são mais recomendas para o processamento em lote de um conjunto de dados.

Para processos iterativos em uma interface visual, recomenda-se o uso de flags, os quais têm a responsabilidade de verificar se o processo como um todo foi finalizado. Essa verificação deve ser feita nos eventos que capturem o encerramento da aplicação por parte do usuário atra-vés de estruturas como if ou switch/case.

Page 2: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

122 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

8.2 Repetição Contada

Essa estrutura é recomendada quando se sabe previamente por quantas vezes um determinado conjunto de instruções ou um termina-do processo deve ser repetido. Essa quantidade de vezes pode ser um valor constante ou valor variável, de acordo com a necessidade do usu-ário ou do problema.

Sintaxe

for(<expressão de inicialização>; <expressão de teste>; <expressão de incre

m en to ) [{]

<instruções>;

[>]

Onde:for(): é a função em C++ Builder para a estrutura de re-

petição contada. Veja o exemplo na seqüência: for(int i=0; i<5; i++)

ShowMessage(IntToStr(i));

<expressão de inicialização: é uma instrução de atribuição (i=0); é sempre executada apenas uma vez antes de o laço ser iniciado com o valor definido.

<expressão de t e s t o : é uma instrução de condição que controla o laço (i<5). Essa expressão é avaliada como verda-deira ou falsa toda vez que o laço for iniciado ou reiniciado. Se verdadeira, o corpo do laço é execu-tado. Quando a expressão tornar-se falsa, o laço é terminado e o controle passa para a instrução se-guinte ao laço.

<expressão de incremente» : define a maneira como a variável de con-trole do laço será incrementada cada vez que o laço é repetido (/++). Essa instrução é executada imedi-atamente após a execução do corpo do laço.

No exemplo anteriormente exibido, a variável z1 inicia com 0 (zero). Cinco janelas mostrando o valor 0, 1, 2, 3 e 4 serão exibidas.

No exemplo que segue, o contador tem seu valor inicial em 1 e seu valor final dependente de um valor de outra variável, nQuantidade. Como existem duas instruções que teriam repetição, foram utilizados o I e }, que identifica um bloco de comandos.

nQuantidade =StrToInt(editl->Text);

for (1= 1; I< = nQuantidade; I++) {

1 Existe uma convenção de variáveis utilizadas na estrutura for, mas não é uma regra. E comum o uso das variáveis I, J ou K.

Page 3: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 123

nNumero = StrToInt(InputBox("Digite o valor " +

IntToStr(I)+", dos "+IntToStr(nQuantidade) +

" a serem informados", "Valor "0"));

MessageDlg("Atenção, número inválido.", mtError,

TmsgDIgButtonsO << mbOK, 0);

>

Esclarecimentos:

Em C++ Builder, não existe a obrigatoriedade de tipo de variável e, ainda, é permitida a inicialização de quantas variáveis, expressões de testes e, conseqüentemente, expressões de atribuição forem necessári-as, bastando separá-las com vírgulas, por exemplo:

for(i=0,j=i+2; ( K l || jclOO); i++, j+=(i*2))

Caso seja necessário fazer um laço que tenha um valor decrementado, basta alterar o tipo do operador e valor inicial, veja o exemplo:

for(i=10; i>0; i—)

Da mesma forma que as estruturas anteriormente explicadas, se houver uma linha de instrução apenas, não existe a obrigatoriedade de usar os delimitadores {}, porém não há nada que impeça.

8.3 Operadores Aritméticos para

Incremento, Decremento e

Atribuição

A linguagem C, não apenas a C++ Builder, traz alguns operadores aritméticos especiais, que têm a função de otimizar o processo de in-cremento, decremento e atribuição de valores.

Supondo que as variáveis X e Y, utilizadas nos exemplos a seguir, tenham, respectivamente, os valores 10 e 20, veja as representações dos operadores aritméticos. Assuma que cada exemplo faz uso dos valores aqui expostos.

Exemplo Representação Novos valores

X++ X = X + 1 X = 11

Y- K II < I Y = 9

X += Y X = X + Y X = 30 e Y = 20

Y -= 10 < li K I o X = 10 e Y = 10

X *= 2 X = X * 2 X = 20 e Y = 20

Y/=2 Y = Y / 2 X = 10 e Y= 10

Uma observação adicional se faz necessária para os operadores ++ e —, pois a ordem em que eles aparecem em relação à variável é relevante.

Page 4: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

124 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

X = Y++ Esse exemplo atribui a X o valor de Y e, após a instrução ter sido

executada, Y é incrementado em 1. Dessa forma, ao final da instrução, X

é igual a 20 e Y é igual a 21.

X = ++Y Este exemplo incrementa o valor de Y em 1 e depois atribui o resultado

para a variável X. Dessa forma, ao final da instrução, X é igual a 21 e Y

também é igual a 21.

8.4 Problemas com Resolução através

do for

8.4.1 Problema 1: Cálculo de Fatorial

Enunciado 8.1

Faça um algoritmo que calcule o fatorial de um número inteiro lido, sabendo-se que:N! = I x 2 x 3 x 4 x 5 x (N - l) x N

0! = 1 e 1! = 1________________________________________________

8.4.1.1 Uma Análise sobre o Problema

O fatorial está ligado à matemática e existem algumas regras que devem ser sabidas e levadas em consideração:

• O fatorial de um número é este número multiplicado por todos os valores abaixo dele até 1. Por exemplo, o fatorial de 3 é 3 x 2 x 1, que resulta em 6 e o fatorial d e 4 é 4 x 3 x 2 x l , que resulta em 24;

• O fatorial de zero é, por definição, 1;• Não existe fatorial de números negativos.A identificação desse problema como repetição contada está direta-

mente ligada ao número que se deseja obter o fatorial, ou seja, se o desejo é fatorial de 4, serão necessárias quatro operações de multiplicação.

8.4.1.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A figura 8.1 exibe o momento da aplicação em execução. O usuário informa o número que deseja obter o valor do fatorial e, então, pressi-ona o botão Calcular, assim, o resultado é informado no Panei.

Figura 8.1 - Interface desejada em execução para a resolução do exercício.

Page 5: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 125

8.4.1.3 Sobre a Implementação

Verifique que a resolução 8.1 apresenta a implementação utilizando a estrutura de repetição contada e as verificações expressas das entra-das inválidas por parte do usuário.

Resolução 8.1 - Evento OnClickáo Button

void __fastcall TfrmFatorial: :BitBtnlClick(TObject *Sender)

{int nNumero, nFatorial;

try {

nNumero = StrToInt(edtNumero->Text);

>catch(EConvertError &E) {

MessageDlg("Atenção, o número informado é inválido.", mtError,

TMsgDIgButtonsO << mbOK, 0);

Abort();

>

if (nNumero < 0) {

MessageDlg("Apenas números positivos são aceitos.", mtError,

TMsgDIgButtonsO << mbOK, 0);

Abort();

>/* A regra para o fatorial é assumida, tendo seu resultado começado em 1 para

o caso de valores informados inferiores a 2. O laço já começa em 2 e vai até o

valor informado. A cada iteração, a variável nFatorial recebe o produto dela

com a variável contadora, que é incrementada a cada retorno ao for. */

nFatorial = 1;

for(int i = 2; i <= nNumero; i++)

nFatorial *= i;

pnlFatorial->Caption = IntToStr(nFatorial);

>__________________________________________________________________

Observe, no comentário anterior, a resolução (cálculo) do fatorial para o número inform ado. Observe que a variável nFatorial inicia com valor 1 (por isso /for() tem sua variável de controle iniciada em 2) e, caso o nNumero informado seja 0 ou 1, o fatorial deste, por definição, será 1, pois a repetição não será efetuada. Além disso, ela representa o papel de acumuladora do produto de cada uma das multiplicações feitas. Observe que o resultado é guardado sempre sobre o valor anteriormente iden-tificado, onde cada resultado é utilizado como operando da nova multiplicação.

Page 6: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

126 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

8.4.2 Problema 2: Média Aritmética

Enunciado 8.2

Faça um algoritmo que solicite 10 números ao usuário e ao final exiba

a média aritmética desses números.

8.4.2.1 Uma Análise sobre o Problema

O problema é relativamente simples, são dez números que serão in-formados pelo usuário. Eles devem ser somados e, ao final, essa soma deve ser dividida por 10.

8.4.2.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A figura 8.2 representa a exibição dos valores digitados em um memo e a média em um Panei. A figura 8.3 representa a tela que receberá cada valor dos 10 que devem ser informados. O memo pode ser seleci-onado na aba Standard da paleta de componentes da VCL (Visual Component Library), como mostra a figura 8.4. Esse componente é utili-zado na interação com o usuário.

...... InformafosNufrieros.......

1 2 4 816 32 64128 256 512

102.30

Figura 8.2 - Interface desejada para a resolução do exercício.

Figura 8.3 - Interface desejada para entrada de dados.

Figura 8.4 - Seleção dos componentes.

Page 7: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 127

Propriedade para o Objeto Memo

Lines: Essa propriedade é um array de strings, onde cadalinha representa um elemento desse array, porém não se preocupe muito com esse conceito no mo-mento, pois o capítulo 9 trata esse assunto. Por enquanto, imagine esse componente como uma folha de caderno, com várias linhas.

O usuário deverá pressionar o botão Informar os Números para que uma janela, solicitando os números (figura 8.3), apareça. Uma vez ten-do sido informado os dez números, eles são visualizados no Memo e a média deles informada no Panei (figura 8.2).

8.4.2.3 Sobre a Implementação

As telas que representam entradas inválidas por parte do usuá-rio não são exibidas, porém as instruções validam as entradas e exi-bem mensagens que, em caso de erro, podem ser identificadas na resolução 8.2.

Resolução 8.2 - Evento Ondickào Button

void __fastcall TfrmMediaAritmetica:: BitBtnlClick(TObject *Sender)

{float nNumero, nMedia = 0;

/* As duas linhas a seguir retiram todas as linhas existentes no Memo e adicio-nam uma linha em branco, respectivamente. */

mem Nu meros-> Lines->Clear();

mem Numeros-> Lines->Add("");

/* No laço a seguir, é solicitado ao usuário um valor, esse valor é imediatamente transformado para Float. Caso o valor não possa ser convertido, uma mensa-gem de erro é exibida ao usuário. */

forfint 1=1; I <= 10; I++) {

try {

nNumero = StrToFloat(InputBox("Digite o valor " + IntToStr(I+l) +

", dos 10 a serem informados", "Valor "0"));

}catch(EConvertError &E) {

nNumero = 0; // se o valor digitado não pôde ser convertido, é assumido

zero.MessageDlg("Atenção, o número informado é inválido.", mtError,

TMsgDIgButtonsQ << mbOK, 0);

>/* O valor digitado, ou zero, em caso de erro, é acumulado na variável nMedia,

e uma representação em string desse valor é anexada a primeira linha do

componente Memo. */

nMedia += nNumero;

Page 8: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

128 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

memNumeros->Lines->Strings[0] = memNumeros->Lines->Strings[0] ++

FloatToStr(nNumero);

>// Ao final, a média é exibida no Panei.

pnlMedia->Caption = FormatFloat("###,##0.00", (nMedia/10));

>_______________________________________________________________

8.4.3 Problema 3: Consumo de Energia

Enunciado 8.3

Em um condomínio fechado, de 10 residências, a companhia de fornecimento de energia está fazendo um levantamento de consumo. O responsável por esse levantamento informará ao seu programa a quantidade de Kw consumido (cada residência) e seu programa deverá informar a quantidade de Kw que 20% representa no total consumido de cada residência. Ao final, deverá informar a projeção de consumo total do condomínio, já descontados os 20% de cada residência.

8.4.3.1 Uma Análise sobre o Problema

A pesquisa é feita em 10 residências e cada uma deve informar seu consumo. A cada valor informado, devem ser obtidos dele 20%. Ao final, a informação solicitada é o total de energia consumida, já des-contados os 20%.

8.4.3.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

Para iniciar a aplicação, o usuário deverá pressionar o botão Informe os consumos (figura 8.6). Será exibida uma janela (figura 8.5) onde os consumos, um a um, deverão ser informados. Após a informação de todos eles, o resultado é exibido no StringGrid.

Figura 8.5 - Interface desejada em execução de entrada de dados para a resolução

do exercício.

Page 9: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 129

Consumo de Energ ia fiT~|fÕ]fX~|

Informe os consumos

........... " 1

Casa Consumo 20% r1 20.00 4.00

2 90,00 18.00

3 110.00 22,00

4 80.00 16,00

5 120.00 24,00

6 70.00 14.00

7 130.00 26.00

8 60,00 12,00

9 140,00 28,00

10 50,00 10.00

Total 696.00

I

Figura 8.6 - Interface desejada em execução para a resolução do exercício.

Propriedade para o Objeto TStringGrid

Cells: A propriedade Cells é declarada como uma arrayde strings, onde cada item do array corresponde ao texto exibido em uma célula da grade, definida pelos índices ARow e ACol, que variam de zero até RowCount-1 e ColCount-1, respectivamente.

Essa propriedade só está disponível durante a exe-cução do aplicativo.Vale ressaltar que o primeiro índice se refere à co-luna e o segundo à linha.

8.4.3.3 Sobre a Implementação

Resolução 8.3.1 - Evento OnCreatedo Form

void __fastcall TfrmKilowatts: :FormCreate(TObject *Sender)

{/* Como não é possível atribuir valores às células do StringGrid em tempo de

desenho, no momento em que o Form é criado, as células que são títulos de

colunas e/ou linhas recebem seus respectivos valores. */

Page 10: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

130 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

sgrConsumos->Cells[0][0] = "Casa";

sgrConsumos->Cells[l][0] = "Consumo";

sgrConsumos->Cells[2][0] = "20%";

sgrConsumos->Cells[0][ll] = "Total";

}___________________________________

Resolução 8.3.2 - Evento Ondickào Button

void __fastcall TfrmKilowatts::BitBtnlClick(TObject *Sender)

{double Consumo, Desconto, TotalConsumo = 0, TotalDesconto = 0;

for(int I = 1; I <= 10; I++) {

/* Observe aqui e mais abaixo a atribuição dos valores às células do Crid. A coluna se mantém constante, mas as linhas variam de acordo com o laço. */

sgrConsumos->Cells[0][I] = IntToStr(I);

try {

Consumo = StrToFloat(InputBox("Digite o consumo da " + IntToStr(I) +

"a. casa, das 10 a serem informadas", "Consumo "0"));

>catch(...) {

Consumo = 0;

MessageDlg("Atenção, o consumo informado é inválido", mtError,

TMsgDIgButtonsQ << mbOK, 0);

>

Desconto = Consumo * 0.20;

sgrConsumos->Cells[l][I] = FormatFioat("##0.00", Consumo);

sgrConsumos->Cells[2][I] = FormatFloat("##0.00", Desconto);

TotalDesconto += Desconto;

TotalConsumo += Consumo;

}sgrConsumos->Cells[2][ll] = FormatFloat("##0.00", (TotaiConsumo- TotalDesconto));

>__________________________________________________________________

Esse exercício utilizou o componente StringGrid que, por sua vez, utiliza o conceito de matriz melhor detalhado no próximo capítulo.

8.5 Repetição Condicional com Teste

no Início

A condição de teste, nessa estrutura, normalmente compara um valor definido pelo desenvolvedor com uma variável que tem seu valor co-nhecido antes (fora da estrutura) pelo usuário ou inicializada pelo desenvolvedor. Deve-se observar que é preciso oferecer a possibilidade de alteração desse valor, nas instruções que estão dentro da repetição, para que assim possa ser encerrado o loop.

Page 11: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 131

Sintaxe

while (<condição_simples_ou_composta>) [{]

<instruções>;

[};]

Onde:

While: é uma palavra obrigatória da estrutura.<condição_simples_ou_composta>: refere-se às verificações. Caso essa(s)

seja(m) verdadeira(s), as instruções da estrutura se-rão executadas. Veja os exemplos a seguir:

I = 2;

while ( I != nNumero) {

nFatorial *= I;

I++;

>edtResp->Text = "S";

while ( edtResp->Text == "S") {

if (StrToInt(edtIdade->Text) > 0) {

lbll->Caption =IntToStr(StrToInt(edtIdade->Text)*365);

edtResp->Text = "N";

>else {

lbll->Caption = ''Valor Inválido";

break;

>>

Esclarecimentos:

Nessa estrutura, o programador deve controlar explicitamente a variável que é responsável pela quantidade de iterações que deverão ser feitas. Essa variável pode ser incrementada dentro da estrutura, pois se sabe o número de vezes, ou dependendo de uma interação do usuário. A condição de parada é testada no início a cada repetição (antes de ocorrer), sendo que, se ela for falsa, haverá a parada do looping (laço). O uso do begin... end tem a mesma regra apresentada anterior-mente. Lembre-se que isso é válido para qualquer tipo de estrutura.

8.6 Problemas com Resolução através

do While

8.6.1 Problema 4: Jogo de Pingue-pongue

Enunciado 8.4

Em um campeonato de pingue-pongue, o acompanhamento do jogo é

feito através de seu programa, o qual solicita sempre o número do

Page 12: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

132 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

jogador que venceu o ponto disputado. 0 código do jogador deve ser 1 ou 2, não sendo aceito outro valor e devendo ser informado ao usuário

quando ele digita um código errado.

Seu programa deverá solicitar a quantidade de pontos para cada partida. Essa quantidade não poderá ser inferior a 5 e tampouco superior

a 21.

O seu programa deverá garantir que o jogador vencedor seja aquele que fez a quantidade de pontos para a partida, porém a diferença entre os dois jogadores deve ser de, no mínimo, 2 pontos, caso contrário, vencerá aquele que primeiro tiver 2 pontos à frente do outro, nesse caso, o limite de pontos da partida não é mais válido.________

8.6.1.1 Uma Análise sobre o Problema

O que deve ser visto é que seu programa deve receber apenas um valor, que é o número do jogador ganhador do ponto. O programa deve garantir o término do jogo através das condições a serem verificadas: a quantidade máxima de pontos atingida conforme infor-mado pelo usuário (mínimo 5 e máximo 21) e a diferença de pontos entre os jogadores deve ser superior ou igual a 2.

8.6.1.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A tela inicial do aplicativo é semelhante à figura 8.8 (que nesse mo-mento representa a interface final), com o rótulo do botão sendo Iniciar Jogo e o valor de pontos da partida e os pontos para cada jogador, em branco.

A figura 8.7 representa a entrada do número do jogador ganhador do ponto atual. Existem ainda telas de mensagem de erros e alertas para o usuário e facilmente poderão ser identificadas nos códigos implementados.

Jo g o de - m \

Pontos da Partida :�K

Jogador: 2)

Iniciar o Jogo

Figura 8.7 - Interface desejada para o lançamento do ponto.

Page 13: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 133

A tela, solicitando o jogador, será exibida até que um dos jogadores atinja a quantidade de pontos da partida e que tenha, no mínimo, dois pontos de diferença para o seu adversário. Ao final, é exibido o placar final do jogo, destacando o placar do vencedor.

m

I Pontos da Partida : [5

Jogador 1 Jogador 2

3

NovoJoqo |____ I

Figura 8.8 - Interface desejada para a resolução do exercício.

8.6.1.3 Sobre a Implementação

Note que a interface desse exercício utiliza dois formulários. Para a resolução deste e dos demais, que utilizam multiformulários. Siga os passos:

1. Crie uma nova aplicação.

2. Salve seu projeto, informe untPingPong como nome da unit PingPong para o nome do projeto.

3. Desenhe nesse formulário a representação da figura 8.9 e altere a propriedade Name para frmPingPong.

4. Crie um novo formulário através do menu File/New/Form, re-presentado na figura 8.9. Dimensione e posicione o novo formu-lário da forma apresentada na interface sugerida.

Eilej__

New ► ■H U n it -C ++B u ilder

l&) Open... (0i Package - C++Builder

£j? Open Project... C trl+F11 Q ÿCL Forms Application - C++Builder 1

Reopen ► □ Form - C++Builder

■ Save Ctrl+S Qther...

0 : Save As... Customize...

0 Save A ll Shift+Ctrl+S

Dose

5b Close All

■0 Use U n it. A lt+ F ll

« Erint...

i ' Exit

Figura 8.9 - Opção New no item Project do menu principal.

Page 14: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

134 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

5. Insira os componentes Panei, Edit e Labei conforme apresentado na figura 8.7. Altere a propriedade Name para frmLancaPonto. Grave esse novo formulário, dando a ele o nome (da unit) untLancaPonto.

8.6.1.4 Esclarecimentos quanto ao uso de mais de um

Formulário em uma Aplicação

Quando se tem uma aplicação que faz uso de vários formulários, é preciso ponderar o seguinte: a aplicação se encarrega de criar todos os formulários no momento em que ela inicializar ("startar") ou o desenvolvedor se encarrega disso?

Na primeira opção, é necessário saber que todos os recursos (com-ponentes, variáveis e arquivos, dentre outros) que estiverem nos for-mulários, solicitarão, ao sistema operacional, recursos (memória e processamento) para que os formulários possam ser criados e, além disso, é preciso avaliar se a aplicação usará sempre todos os formulári-os que foram criados quando a aplicação inicializou.

O ideal é que as janelas sejam criadas sempre que requisitadas e não no momento em que a aplicação é inicializada. Cabe um estudo sobre o objetivo de cada aplicação para avaliar o melhor custo/benefício, no que diz respeito ao processamento.

Implementação 8.1 - Unit de projeto que representa a criação

automática de dois formulários em um único

projeto

//----------------------------------------------------------------------------------------#include <vcl.h>

#pragma hdrstop

//----------------------------------------------------------------------------------------USEFORM("untPingPong.cpp", frmPingPong);

USEFORM("untLancaPonto.cpp", frmLancaPonto);

//----------------------------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{try

Application->Initialize();

/* Veja agora a criação dos formulários (pela aplicação). Isso quer dizer, que todos os formulários criados aqui podem ser acessados sem nenhum

problema por sua aplicação e, como visto anteriormente, cabe um estudo

para verificar a viabilidade dessa situação. */Application->CreateForm(__classid(TfrmPingPong), &frmPingPong);

Application->CreateForm(__classid(TfrmLancaPonto), &frmLancaPonto);

Application->Run();

>

Page 15: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 135

catch (Exception &exception)

{Application->ShowException(&exception);

>catch (...)

{try

throw Exception("");

>catch (Exception &exception)

{Application->ShowException(&exception);

>>return 0;

}//--------------------------------------------------------------------------------

Veja o trecho de código da unit do projeto nas implementações 8.1, que tem os dois formulários criados automaticamente pela aplicação no momento em que ela inicializa.

8.6.1.5 Impedindo que todos os Formulários de uma

Aplicação sejam Criados Automaticamente

Para determinar qual(ais) formulário(s) deverá(ão) ser criado(s) au-tomaticamente, o IDE oferece uma forma mais elegante e correta de fazer isso do que apagar as linhas no código mostrado anterior mente. Vá ao menu Project/ Options e selecione a opção Forms no lado esquer-do da janela. Veja as figuras 8.10 e 8.11.

Project

li) Add to Project... Shift+Fll

l£) Remove from Project..,

ft? Add to Repository...

3 View Source

#fe Add New Project...

oS Add Existing Project...

Compile Unit Alt+F9

Compile Projectl Ctrl+F9

Build Projectl Shift+F9

Information for [none]

Make All Projects

Build all projects

; Dependencies...

Build Configurations.,.

Figura 8.10 - Opção Options no item Project do menu principal.

Page 16: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

136 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

Note na figura 8.11 que todos os formulários criados ou adicionados aparecem na listagem AutoCreate forms automaticamente, ou seja, todos serão criados e estarão disponíveis quando a aplicação for executada. Para que o formulário seja criado e esteja disponível para aplicação ape-nas no momento em que o desenvolvedor precise, selecione o nome do formulário que está na listagem AutoCreate e, em seguida, o botão que tem o sinal de > (maior), que representa uma seta para a direita.

Figura 8.11 - Interface com o usuário para a opção Options do item Project no menu principal. Verificação dos Formulários existentes no projeto.

Veja a figura 8.12 com a alteração concluída para esse exercício e também o novo código para o projeto (implementação 8.3).

8.6.1.6 Criando Formulários em Tempo de Execução

O termo "criar formulário" pode ser confundido em alguns casos com a situação de se "desenhar" o formulário. É importante deixar claro que, nesse momento, o verbo "criar" implica na execução do for-mulário e não no ato de desenhá-lo, que nesse contexto seria montar seu formulário.

Quando se desenha/monta um formulário, o que ocorre na realida-de é a definição de um novo tipo de dado, que é um tipo de formulário. A esse novo tipo de dado (formulário) são descritos todos os compo-nentes que farão parte dele, os quais são relacionados com o nome atribuído através do Object Inspector e seu respectivo tipo. Após a defi-nição do tipo, com seus componentes, uma nova variável desse tipo criado é declarada também na unit. Veja a implementação 8.2, onde os comentários dizem respeito a isso.

Page 17: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 137

Figura 8.12 - Definição da unit a ser criada automaticamente no Project Options.

Implementação 8.2 - Unit de projeto que representa a criação de

formulários de forma seletiva, criando apenas os

desejados no momento da inicialização da

aplicação

//-------------------------------------------------------------------------------------------#include <vcl.h>

#pragma hdrstop//-------------------------------------------------------------------------------------------USEFORM("untPingPong.cpp", frmPingPong);

USEFORM(”untLancaPonto.cpp", frmLancaPonto);//-------------------------------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

{try

{Application->Initialize();

/* Veja agora a criação dos formulários (pela aplicação). Isso quer dizer, que todos os formulários criados aqui, podem ser acessados sem nenhum

problema pela sua aplicação e, como visto anteriormente, cabe um estudo

para verificar a viabilidade desta situação. */

Application->CreateForm(__classid(TfrmPingPong), &frmPingPong);

Application->Run();

>catch (Exception &exception)

{Application->ShowException(&exception);

>catch (...)

{try

{

Page 18: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

138 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

throw Exception("");

}catch (Exception &exception)

{Application->ShowException(&exception);

}}return 0;

>//-----------------------------------------------------------------------------------

Bem, agora o que falta é realmente criar um formulário em tempo de execução para que possa ser usado. Deve-se saber que, para se referenciar um formulário, é utilizada a variável que o representa. Ela receberá um endereço (uma referência), pois é tratada como um objeto e não uma variável primitiva, como Integer/bit. Veja a implementação 8.3, que traz essa situação comentada.

Implementação 8.3 - Referência à variável que representa o novo tipo

de dado, para a instanciação de um formulário

//-----------------------------------------------------------------------------------#include <vcl.h>

#pragma hdrstop

#include "untPingPong.h"

#include "untLancaPonto.h"//-------------------------------------------------------------------------------------------#pragma package(smart_init)

#pragma resource "*.dfm"

/* Observe aqui a criação da variável que representará o novo tipo de dados, ou

seja, o formulário que é criado pelo header. */

TfrmPingPong *frmPingPong;

/* A linha abaixo trás o momento exato em que a variável que representa o tipo do formulário solicita a criação de um objeto e o aloca (reserva recursos) para a variável de seu tipo. */

frmLancaPonto = new TfrmLancaPonto(Application);

while ((pnlJogadorl->Tag == 0 && pnlJogador2->Tag == 0))

/* A linha seguinte já utiliza a variável que representa o formulário e chama a(o) função/método ShowModal. Note que não foi criada(o) tal função/método na unit do formulário, porém, como o formulário criado é um tipo herdado de TForm, essa função/método está lá, então todos que estenderem TForm o terão. */

frmLancaPonto->ShowModal();

/* A linha seguinte é responsável por liberar os recursos (memória) requisitados e utilizados no momento em que o formulário foi criado. Esse procedimento deve ser feito sempre que não se desejar mais usar o formulário, pois caso a(o) função/método Free tenha sido chamada, para usar novamente o formulário, ele deverá ser criado. */

_____ frmLancaPonto->Free();________________

Page 19: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 139

Observe que a variável frmLancaPonto não existe no formulário atual, que é o formulário que chamará o frmLancaPonto. Dessa forma, é preciso que ele o conheça. Isso é possível através da im-portação de units na cláusula uses, porém, para esse caso, utili-za-se a uses de implementation e não de interface. Verifique a implementação 8.5.

É possível a digitação diretamente no código, porém a IDE ofe-rece um recurso que auxilia muito esse trabalho. Selecione o menu File/U se unit (figura 8.13) e aparecerá uma janela com todas as units de seu projeto e que ainda não sejam visíveis pela unit atual (figura 8.14). Basta, então, selecionar a unit desejada e clicar no botão OK.

Implementação 8.4 - Inclusão de uma unit referenciada

//------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "untPingPong.h"

/* Essa Unha faz com que a unit atual possa acessar ou visualizar os componen-tes pertencentes ao formulário que existe na unit untLancaProduto. */#include "untLancaPonto.h"

8.6.1.7 Alguns Esclarecimentos

Nos textos anteriores e nos códigos com seus comentários, termos novos apareceram, "herança" e "estender" são alguns deles. Esses ter-mos são referentes ao paradigma da Orientação a Objetos, que será tratada com mais detalhes no capítulo 13.

Uma outra situação nova que surgiu é quanto ao uso de mais de um formulário em uma aplicação. Até agora foram apresentados apenas exemplos ditos SDP e aplicações MDP. Ainda existem aplicações Modal4 (que é esse exemplo) e não-modal5.

2 Single Document Interface - Interface de Documentos Simples.3 Multiple Document Interface - Interface de vários documentos. Significa que uma

janela principal terá outras janelas secundárias (p. ex.: processador de texto e planilhas). A janela principal é chamada de formulário-pai ou "Container MDI" e as janelas se-cundárias, de "janela-filho". Estas, normalmente, estão "confinadas" à janela-pai, não sendo possível arrastá-la para fora desta.

4 Um formulário é modal quando este deve ser explicitamente fechado pelo usuário para prosseguir com outro formulário. A maioria das caixas de diálogo é modal.

5 Um formulário é não-modal (modeless) quando é possível ir para outros forms sem ter fechar o form anterior.

Page 20: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

140 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

File 1

New �

Open...

& Open Project... Ctrl+F 11

Reopen �

0 Save Ctrl+S

'& Save As...

CR Save Project As...

0 Save All Shift+Ctrl+S

m,W-r Close

o„ Close All

a Use Unit... Alt+Fll

# Print...

i i l Exit

Figura 8.13 - Opção Use Unit no item File do menu principal.

Figura 8.14 - Interface da opção Use Unit onde é selecionada a Unit a ser utilizada.

8.6.1.8 Codificação Completa

Resolução 8.4.1 - Inclusão de variáveis públicas no formulário principal

(chamador)

Em algumas situações, valores atribuídos às variáveis ou aos componentes que façam parte de um formulário (ou uma unit) são necessários que sejam visíveis a outros formulários (ou units), quer seja para simples verificação condicional, no sentido de flag, quer seja para manipulação direta dos dados (atribuição). A partir desse ponto, cada enunciado trabalhará com dois formulários, onde um pode precisar acessar os dados de outro.

Page 21: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 141

/* Definição de um novo tipo de dado, que na realidade é o formulário que se está desenhando, porém todo novo formulário é extendido de um tipo conhe-cido pelo C++ Builder, nesse caso, o formulário pai, ou que dá origem aos formulários que você desenha, é o TForm. Este é um princípio de ORIENTAÇÃO A OBJETOS. */

class TfrmPingPong : public TForm

{__published: // IDE-managed Components

/* /4s linhas até a cláusula private representam todos os componentes perten-centes ao formulário, assim como os cabeçalhos de todos os eventos (de qual-quer componente) trabalhado no formulário. */

TBitBtn *btnlniciar;

TPanel *Panell;

TPanel *Panel3;

TLabel *Label2;

TPanel *Panel2;

TLabel *Labell;

TPanel *pnlJogadorl;

TPanel *pnlJogador2;

TGroupBox *pnlLancamento;

TLabel *Label3;

TEdit *edtQuantidade;

void __fastcall btnIniciarClick(TObject *Sender);

private: // User declarations

public: // User declarations

__fastcall TfrmPingPong(TComponent* Owner);

/* A variável nQuantidade pertence, com essa declaração, ao formulário (tipo de

dado) TfrmPingPong e só poderá ser usada fora do formulário que a possui (nesse caso o definido nessa unit) tendo o nome de seu dono (frmPingPong -

Objeto/Variávei que representa esse novo tipo de dado. */

int nQuantidade;

>;//-------------------------------------------------------------------------------------------

/* Variável declarada na seção de interface, possibilitando assim que qualquer unit que inclua essa unit (import) possa visualizá-la. Essa variável é de visibilitade

global nessa unit (visibilidades de variáveis são tratadas com mais detalhe no capítulo 12) e ela representa o tipo de dado definido acima. Ou seja, sempre que se quiser executar o formulário criado nesse unit, deve-se fazê-lo através

dessa variável. Você pode verificar, além do código a seguir, o código da unit de projeto para ver essa implementação. */

extern PACKAGE TfrmPingPong *frmPingPong;_____________________________

Resolução 8.4.2 - Evento OnCHckáo botão Iniciar Jogoáo formulário

principal

void __fastcall TfrmPingPong: :btnIniciarClick(TObject *Sender)

{/* A propriedade Tag dos Paneis que pertencem aos jogadores serão os flags

para dizer quem ganhou através do valor 1. Estando os dois Paneis com valor zero nessa propriedade, significa que o jogo ainda não começou e então esse

if será executado. }

Page 22: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

142 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

if ((pnüogadorl->Tag == 0 && pnlJogador2->Tag == 0)) {

try {

nQuantidade = StrToInt(edtQuantidade->Text);

>catch(...) {

MessageDlg("Valor informado como quantidade de pontos para partida in válido",

mtError, TMsgDlgButtons() << mbOK, 0);

AbortO;

>

if (nQuantidade < 5 || nQuantidade > 21) {

MessageDlg("A quantidade de pontos informadas para a partida está fora + "dos limites. Mínimo de 5 e máximo de 21", mtWarning, TMsgDlgButtons()

<< mbOK, 0);

Abort();

>

frmLancaPonto = new TfrmLancaPonto(Application);

/* Estrutura de repetição onde a condição para término é que um jogador ganhe. Isso é identificado no formulário chamado - frmLancaPonto - através da atri-buição do valor 1 à Tag do Panei do jogador vencedor. O que ocorre realmente

é que o formulário é exibido e, quando o seu processo é concluído, ele é

fechado e a condição avaliada. Em caso de falsidade (alguém ganhou) o laço termina. */

while ((pnlJogadorl->Tag == 0 && pnlJogador2->Tag == 0))

frmLancaPonto->ShowModal();

frmLancaPonto->Free();

/* A seguir as estruturas que verificam o jogador vencedor e mudam a aparên-cia do respectivo Panei. */

if (pnlJogadorl->Tag == 1) {

pnüogadorl->Color = cIBlue;

pnlJogadorl->Font->Color = clYellow;

}else {

pnlJogador2->Color = cIBlue;

pnlJogador2->Font->Color = clYellow;

>/* Uma vez concluído o jogo, o Caption do botão deverá exibir outra mensagem. */

btnIniciar->Caption = "Novo Jogo";

}/* Este bloco de código é executado para o caso de o jogo ter terminado e o

usuário optar por um novo. Ele é responsável por restaurar a aparência inicial do formulário. */

else {

if (pnüogadorl->Tag == 1) {pnlJogadorl->Color = OxOOCCFFFF;

pnüogadorl->Font->Color = cIWindowText;

pnüogadorl->Tag = 0;

>

Page 23: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 143

else {

pnüogador2->Color = OxOOCCFFFF;

pnlJogador2->Font->Color = cIWindowText;

pnlJogador2->Tag = 0;

> 'btnIniciar->Caption = "Iniciar Jogo";

pnüogadorl->Caption =

pnlJogador2->Caption =

>}_________________________________________

Resolução 8.4.3 - Evento OnKeyDownâo Editque recebe o número do

jogador ganhador do ponto disputado do formulário

chamado

void __fastcall TfrmLancaPonto::edtJogadorKeyDown(TObject *Sender,

WORD &Key, TShiftState Shift)

{int nJogador, nJogadorOl, nJogador02;

/* Para o caso de a tecla pressionada ter sido a Enter (tem o valor ASCII 13, porém é representada pela constante VK_RETURN), o processamento do ponto

é feito. */

if (Key == VK_RETURN) {

try {

nJogador = StrToInt(edüogador->Text);

>catch(...) {

MessageDlg("Valor informado como número do jogador inválido", mtError,

TMsgDIgButtonsQ << mbOK, 0);

AbortQ;

>/* Verifica se o número do jogador informado é um número válido. Em caso

negativo, uma mensagem é exibida, caso contrário o Panei que está no formu-lário principal que representa os pontos do jogador informado tem seu valor incrementado. */

if (nJogador < 1 11 nJogador > 2)

MessageDlg("Atenção, apenas os valores 1 e 2 são aceitos", mtWarning,

TMsgDlgButtons() << mbOK, 0);

else if (nJogador == 1)

frmPingPong->pnlJogadorl->Caption =

IntToStr(StrToInt(frmPingPong->pnlJogadorl->Caption) + 1);

else

frmPingPong->pnlJogador2->Caption =

IntToStr(StrToInt(frmPingPong->pnlJogador2->Caption) + 1);

nJogadorOl = StrToInt(frmPingPong->pnlJogadorl->Caption);

nJogador02 = StrToInt(frmPingPong->pnlJogador2->Caption);

/* É verificado se um dos jogadores ganhou a partida. */

if (nJogadorOl >= frmPingPong->nQuantidade && (nJogadorOl - nJogador02)

>= 2)

Page 24: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

144 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

frmPingPong->pnlJogadorl->Tag = 1;

else if (nJogador02 >= frmPingPong->nQuantidade && (nJogador02 -

nJogadorOl) >= 2)

frmPingPong->pnüogador2->Tag = 1;

edüogador->Clear();

frmLancaPonto->Close();

>>____________________________________________________________

8.6.2 Problema 5: Reajuste de Salário

Enunciado 8.5

Elaborar um programa que efetue o cálculo do reajuste do salário em uma empresa. Considere que, para cada funcionário, o reajuste será de 15%, caso seu salário seja menor que 500. Se o salário for maior ou igual a 500, porém menor ou igual a 1000, seu reajuste será de 10%. Caso seja ainda maior que 1000, o reajuste deverá ser de 5%. Você deverá exibir ao final:

a) O valor total da folha de pagamento antes do reajuste;b) O valor total da folha de pagamento após o reajuste;c) O percentual de acréscimo à folha de pagamento, em relação à

folha atual.A entrada de dados finaliza quando o código do funcionário informado contiver o valor Fim.

8.6.2.1 Uma Análise sobre o Problema

Seu programa deverá receber dois valores: o código de cada funcio-nário e o valor atual de seu salário. Para cada funcionário, o cálculo de reajuste deve ser feito. Ao final, após a digitação do valor FIM, no códi-go do último funcionário, deverão ser informados os totais solicitados no enunciado.

Apesar de o enunciado parecer grande, este é um dos tipos mais fáceis de exercícios de repetição, pois devem ser calculados totais, que dependem de uma avaliação sobre o valor informado pelo usuário e o flag, para finalização desse processo, é explícito.

8.6.2.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A figura 8.15 exibe a tela para início da solicitação de dados ao usu-ário. É necessário apenas clicar no botão Iniciar o Lançamento para que a janela com o código e o salário de cada funcionário seja solicitada (figura 8.16), onde será identificado seu reajuste e, por fim, o reajuste geral da folha. Os totais solicitados são, então, exibidos ao usuário na tela inicial com o botão agora sendo Novo Lançamento.

Page 25: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 145

Figura 8.15 - Interface desejada para a resolução do exercício.

Figura 8.16 - Interface de entrada de dados para a resolução do exercício.

8.6.2.3 Sobre a Implementação

Veja que as resoluções trazem código implementado não somente para os eventos dos componentes, mas também em relação as variá-veis globais utilizadas e extremamente importantes.

8.6.2.3.1 Para o Formulário Principal

Resolução 8.5.1 - Inclusão de variáveis públicas

class TfrmReajuste : public TForm

{__published: // IDE-managed Components

TBitBtn *btnlniciar;

TPanel *Panel5;

TLabel *Label3;

TLabel *lblAntes;

TLabel *lblApos;

TLabel *Label6;

TLabel *Label7;

TLabel *lblPercentual;

private: // User declarationspublic: // User declarations

__fastcall TfrmReajuste(TComponent* Owner);

Page 26: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

146 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

/* Declaração da variável que faz parte do formulário e que deverá ter seu acesso possível pelo formulário chamado. */

int nQuantidade;

>;//----------------------------------------------------------------------------------extern PACKAGE TfrmReajuste *frmReajuste;_____________________________

Resolução 8.5.2 - Evento Ondick do botão Iniciar Lançamento

void __fastcall TfrmReajuste: :btnInidarClick(T0bject *Sender)

{double Percentual;

if (btnIniciar->Tag == 0) {

btnIniciar->Tag = 1;

frmLancaSalario = new TfrmLancaSalario(Application);

while (frmLancaSalario->edtCodigo->Text != "FIM") {

/* Antes do formulário para lançamento de valores ser exibido, são atribuídos

valores iniciais para seus componentes de interação com o usuário. */

frmLancaSalario->edtSalario->Text = "0";

frmLancaSalario->edtCodigo->Clear();

frmLancaSalario->ShowModal();

if (frmLancaSalario->nSalario < 500)

Percentual = 1.15;

else if (frmLancaSalario->nSalario <= 1000)

Percentual = 1.10;

else

Percentual = 1.05;

/* Uma vez identificado o percentual a ser aplicado, os valores para os Labeis são calculados e atribuídos. */

lblAntes->Caption = FloatToStr(StrToFloat(lblAntes->Caption) +

StrToFloat(frmLancaSalario->edtSalario->Text));

lblApos->Caption = FloatToStr(StrToFloat(lblApos->Caption) +

StrToFloat(frmLancaSalario->edtSalario->Text) * Percentual);

try {

lblPercentual->Caption = FloatToStr((StrToFloat(lblApos->Caption) -

StrToFloat(lblAntes->Caption)) * 100 / StrToFloat(lblAntes->Caption));

>catch(...) {

lblPercentual->Caption = "0";

>}

lblAntes->Font->Color = cIBlue;

lblApos->Font->Color = cIBlue;

lblPercentual->Font->Color = cIBlue;

lblAntes->Caption = FormatFloat("###,##0.00", StrToFloat(lblAntes- >Caption));

lblApos->Caption = FormatFloat("###,##0.00", StrToFloat(lblApos- >Caption));

Page 27: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 147

lblPercentual->Caption = FormatFloat("##0.00%",

StrToFloat(lblPercentual->Caption));

frmLancaSalario->Free();

btnIniciar->Caption = "Novo Lançamento";

>/* Uma vez concluída a digitação e o usuário confirmando o desejo de uma nova

rodada de lançamento de valores, os Labeis responsáveis peia informação dos valores retornam ao estado de início da aplicação. */

else {

btnIniciar->Tag = 0;

lblAntes->Font->Color = cIWindowText;

lblApos->Font->Color = cIWindowText;

lblPercentual->Font->Color = cIWindowText;

lblAntes->Caption = "0";

lblApos->Caption = "0";

lblPercentual->Caption = "0";

btnIniciar->Caption = "Iniciar Jogo";

>>__________________________________________________________________

8.6.2.3.2 Para o Formulário Secundário

Resolução 8.5.3 - Inclusão de variáveis públicas

class TfrmLancaSalario : public TForm

{__published: // IDE-managed Components

TGroupBox *pnlLancamento;

TLabel *Label3;

TLabel *Labell;

TEdit *edtCodigo;

TEdit *edtSalario;

TBitBtn *btnConfirmar;

private: // User declarationspublic: // User declarations

__fastcall TfrmLancaSalario(TComponent* Owner);

/* Declaração da variável que deverá ter seu acesso possível pelo formulário

chamador.*/

double nSalario;

>;//-------------------------------------------------------------------------------------------extern PACKAGE TfrmLancaSalario *frmLancaSalario;______________________

Resolução 8.5.4 - Evento OnShowào Form

void __fastcall TfrmLancaSalario::FormShow(TObject *Sender)

{edtCodigo->SetFocus();

_>____________________________________________________

Page 28: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

148 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

Resolução 8.5.5 - Evento Ondickáo botão Confirmaráo Formsecundário

void __fastcall TfrmLancaSalario: :btnConfirmarClick(TObject *Sender)

{try {

nSalario = StrToFloat(edtSalario->Text);

>catch(...) {

MessageDlg(”Valor informado como salário é inválido", mtError,

TMsgDIgButtonsO << mbOK, 0);

AbortO;

>/* Observe que a função Length retornará a quantidade (comprimento) de

caracteres existentes na propriedade Text do componente edtCodigo. Nesse caso se o Edit estiver em branco o usuário deverá ser alertado. >

if (edtCodigo->Text.Length() == 0) {

MessageDlg("Código não pode estar branco", mtWarning, TMsgDIgButtonsO << mbOK, 0);

Abort();

>

Close();

>_______

8.7 Repetição Condicional com Teste

no Final

Sintaxe

do {

<instruções>;

> w h ile (<condição_simples_ou_composta>);

Onde:

do...iuhile: São palavras obrigatórias da estrutura.<condição_simples_ou_composta>: Refere-se às verificações. Caso

esta(s) seja(m) verdadeira(s), a repetição das ins-truções continua. No primeiro exemplo que segue, existe uma variável que está sendo incrementada dentro da estrutura e que é responsável pela para-da. Neste caso, quando o valor de I for igual ao valor de nNumero.

Page 29: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 149

1= 2 ;

do {

nFatorial *= I;

. I + + ;

> while ( I != nNumero);

No próximo exemplo, não há uma variável contadora, mas quando a condição não for mais satisfeita, o looping pára.

edtResp->Text = "S";

do

if (edtIdade->Text) > "0" ) {

lbll->Caption = IntToStr(idade*365);

edtResp->Text = "N";

>else {

lbll->Caption = "Valor Inválido";

break;

>> while( edtResp.Text != "N");

Esclarecimentos:

Nessa estrutura, o programador, quando utilizar uma variável para controlar o número de repetições, também deverá codificar, ou seja, prever como será realizada, pois assim como na while, isso não é cal-culado automaticamente, sendo essa obrigação de inteira responsa-bilidade do programador e não da estrutura, como no caso do for. A condição de parada é testada no final de cada iteração, sendo que quando for falsa, há a parada do looping. Observe que nessa estrutu-ra a(s) instrução(ões) é(são) realizada(s) obrigatoriamente pelo me-nos uma vez.

8.8 Quebras de Laço

Em qualquer uma das estruturas de repetição mostradas anteri-ormente, é possível usar a instrução Break para cancelar a repetição e sair do laço ou, ainda, forçar a próxima iteração com a instrução Continue.

Quando se opta pelo uso da instrução Break, a estrutura é inter-rompida, independentemente da condição imposta para término ter ocorrido ou não e, quando se faz uso da instrução Continue, a condição da estrutura é reavaliada e reiniciada (ou concluída), não sendo executadas, na iteração, as instruções que estiverem após o Continue.

I

Page 30: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

150 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

Exemplos:

1 = 1 ;while (.true) {

I + +;if (I < 1000) continue; _

ShowMessage("Chegamos a mil"); break; _

1 = 1 ; do {

I + +;if (I < 100

--- continue;ShowMessage("Chegamos a mil"),break; ______

} while (true);Encerra a estrutura de repetição ignorando as

instruções que estejam após o Break.

8.9 Problemas com Resolução através

do do... while()

8.9.1 Problema 6: Reajuste de Salário de

Jogadores

Enunciado 8.6

O íbis Futebol Clube deseja aumentar o salários de seus 11 jogadores. O reajuste deve obedecer à seguinte tabela:

Salário Atual (R$) Aumento (°/<)

0,00 a 1.000,00 20%

1.000,01 a 5.000,00 10%

Acima de 5.000,00 0%

Escreva um algoritmo que:

Page 31: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 151

a) Leia o nome e o salário atual de cada jogador;b) Exiba o nome, salário atual e o salário reajustado de cada jogador;

c) Exiba o total da folha de salários do clube, antes do reajuste;d) Exiba o total da folha de salários do clube após o reajuste;e) Exiba o percentual de reajuste sobre o total da folha de salários.

8.9.1.1 Uma Análise sobre o Problema

Esse enunciado trata uma situação mais concreta, onde o cálculo para reajuste de salários de uma equipe de futebol deve ser feito. Os dados além dos salários que devem ser solicitados e os resultados espe-rados em conjunto com os reajustes fazem parte dos itens do enuncia-do. O flag, para término da execução, está ligado diretamente à quan-tidade de jogadores.

8.9.1.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A figura 8.17 apresenta a tela inicial da aplicação, a qual traz os campos que serão preenchidos a cada jogador e ao término da digitação, assim como também traz o botão responsável por iniciar a digitação. A segunda tela (figura 8.18) traz a digitação dos dados e exibe a primeira (ao fundo) atualizada.

Figura 8.17 - Interface desejada para a resolução do exercício.

Nome jogador ASDROGINDO

Salário anterior: 1 - 000 .00

Novo salário : 1 .200 .00

-------------- :--------T otal anterior 1 .000 .00

Total atual: 1 .200 .00

Variação: 0

| Iniciar o lançamento]

Figura 8.18 - Interface de entrada de dados para a resolução do exercício.

Page 32: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

152 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

8.9.1.3 A Implementação

8.9.1.3.1 Para o Formulário Principal

Resolução 8.6.1 - Inclusão de variáveis públicas

class Tfrmlbis : public TForm

{__published: // IDE-managed Components

TBitBtn *btnlniciar;

TPanel *Panel5;

TLabel *Label3;

TLabel *lbll\lome;

TLabel *Labell;

TLabel *lblAnterior;

TLabel *Label4;

TLabel *lblAtual;

TPanel *Panell;

TLabel *labell3;

TLabel *lblTotalAnterior;

TLabel *labell2;

TLabel *lblTotalAtual;

TLabel *LabellO;

TLabel *lblVariacao;

void __fastcall btnIniciarClick(TObject *Sender);

private: // User declarationspublic: // User declarations

__fastcall TfrmIbis(TComponent* Owner);

int nQuantidade;

double nTotalAnterior, nTotalAtual;

>;____________________________________________

Resolução 8.6.2 - Evento Ondickdo botão Iniciar o Lançamento

void __fastcall Tfrmlbis: :btnInidarClick(T0bject *Sender)

{double nVariacao;

if (btnIniciar->Tag == 0) {

btnIniciar->Tag = 1;

frmLancaValores = new TfrmLancaValores(Application);

nQuantidade = 0;

nTotalAnterior = 0;

nTotalAtual = 0;

do {

nQuantidade++;

frmLancaValores->edtNome->Clear();

frmLancaValores->edtSalario->Clear();

frmLancaValores->ShowModal();

nTotalAnterior += frmLancaValores->nSalarioAnterior;

nTotalAtual += frmLancaValores->nSalarioAtual;

Page 33: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 153

lblNome->Caption = frmLancaValores->edtNome->Text;

lblAnterior->Caption = FormatFloat("###,##0.00",

frmLancaValores->nSalarioAnterior);

lblAtual->Caption = FormatFloat("###,##0.00", frmLancaValores- >nSalarioAtuai);

lblTotalAnterior->Caption = FormatFloat("###,##0.00", nTotalAnterior);

lblTotalAtual->Caption = FormatFioat("###,##0.00", nTotalAtual);

} while (nQuantidade < 11);

lblNome->Caption =

lblAnterior->Caption =

lblAtual->Caption =

lblTotalAnterior->Font->Color = cIBlue;

lblTotalAtual->Font->Color = cIBlue;

nVariacao = (nTotalAtual*100/nTotalAnterior) - 100;

lblVariacao->Caption = FormatFloat("###,##0.00", nVariacao) + "%";

frmLancaValores->Free();

btn!niciar->Caption = "Novo Lançamento";

else {

btnIniciar->Tag = 0;

lblTotalAnterior->Font->Color = cIWindowText;

lblTotalAtual->Font->Color = cIWindowText;

lblNome->Caption = "não iniciado";

lblAnterior->Caption = "0";

lblAtual->Caption = "0";

lblTotalAnterior->Caption = "0";

lblTotalAtual->Caption = "0";

btnIniciar->Caption = "Iniciar o Lançamento";

}>_________________________________________

8.9.1.3.2 Para o Formulário Secundário

Resolução 8.6.3 - Inclusão de variáveis públicas

class TfrmLancaValores : public TForm

{__published: // IDE-managed Components

TGroupBox *pnlLancamento;

TLabel *Label4;

TLabel *Labell;

TEdit *edtNome;

TEdit *edtSalario;

Page 34: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

154 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

TBitBtn *btnConfirmar;

void __fastcall btnConfirmarClick(TObject *Sender);

void __fastcall FormShow(TObject *Sender);

private: // User declarationspublic: // User declarations

__fastcall TfrmLancaValores(TComponent* Owner);

double nSalarioAnterior, nSalarioAtual;

h _______________________________________________

Resolução 8.6.4 - Evento OnShowáo Form

void __fastcall TfrmLancaValores::FormShow(TObject *Sender)

{edtl\lome->SetFocus();

frmLancaValores->Caption = "Jogador " + IntToStr(frmIbis->nQuantidade) + " de 11";

}Resolução 8.6.5 - Evento OnClick do botão Confirmarvoid __fastcall TfrmLancaValores: :btnConfirmarClick(TObject *Sender)

{try {

nSalarioAnterior = StrToFloat(edtSalario->Text);

>catch(...) {

MessageDlg("Valor informado como salário é inválido", mtError,

TMsgDIgButtonsO << mbOK, 0);

Abort();

>/* Abaixo a função Trim é responsável por retirar os espaços em branco à direita

e à esquerda, para depois verificar se o tamanho da string é nulo, caso não

tenha sido digitado nada - tamanho zero - será avisado ao usuário. */

if (Trim(edtNome->Text).Length() == 0) {

MessageDlg(”Nome do jogador não pode estar vazio", mtWarning,

TMsgDIgButtonsO << mbOK, 0);

AbortQ;

>;/* Identifica qual a faixa salarial para reajustar conforme a tabela do enunciado. */

if (nSalarioAnterior <= 1000)

nSalarioAtual = (nSalarioAnterior * 1.20);

else if (nSalarioAnterior <= 5000)

nSalarioAtual = (nSalarioAnterior * 1.10);

else

nSalarioAtual = nSalarioAnterior;

CloseQ;

_>_________________________________

Page 35: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 155

8.9.2 Problema 7: Venda de Sapatos

Enunciado 8.7

Uma loja de calçados anota diariamente a quantidade de pares vendidos. Determine em que dia do mês de março ocorreu a maior venda e qual foi a quantidade de pares de calçados vendidos nesse dia.____________

8.9.2.1 Uma Análise sobre o Problema

O flag atribuído para a conclusão da execução desse algoritmo está implicitamente declarado, pois se equivale à quantidade de dias do mês de março, 31. É necessário, para se chegar ao solicitado, apenas a quantidade de pares vendidos a cada dia.

8.9.2.2 A Interface Gráfica com o Usuário (GUI) e seu

Funcionamento

A figura 8.19 apresenta a tela inicial da aplicação, a qual exibe os campos que serão preenchidos a cada dia que tenha sua quantidade de pares informada e ao término da digitação. Essa tela também mos-tra o botão responsável por iniciar a digitação. A figura 8.20. exibe a digitação da quantidade e a primeira (ao fundo) atualizada.

Figura 8.19 - Interface desejada para a resolução do exercício.

Venda J«BIü íjg l g wi rBBiP

Dia de ma

Quantidad

T otal de pQuantidade : jjÕ~

Confirmar

Figura 8.20 - Interface de entrada de dados para a resolução do exercício.

Page 36: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

156 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

8.9.2.3 Sobre a Implementação

8.9.2.3.1 Para o Formulário Principal

Resolução 8.7.1 - Inclusão de variáveis públicas

class TfrmCalcados : public TForm

{__published: // IDE-managed Components

TBitBtn *btnlniciar;

TPanel *Panel5;

TLabel *Label3;

TLabel *lblDia;

TLabel *Labell;

TLabel *lblQuantidadeDia;

TLabel *Label4;

TLabel *lblTotal;

void __fastcall btnIniciarClick(TObject *Sender);

private: // User declarationspublic: // User declarations

__fastcall TfrmCalcados(TComponent* Owner);

int nDia, nDiaMaior, nMaiorQuantidade, nTotalPares;

>;_______________________________________________

Resolução 8.7.2 - Evento Ondickáo botão Iniciar o Lançamento

void _.fastcall TfrmCalcados: :btnIniciarClick(TObject *Sender)

{// Inicia o lançamento

if (btnIniciar->Tag == 0) {

btnIniciar->Tag = 1;

frmLancaValores = new TfrmLancaValores(Application);

nDia = 0;

do {

nDia++;

frmLancaValores->edtPares->Text = "0";

frmLancaValores->ShowModal();

nTotalPares += frmLancaValores->nQuantidade;

/* Observe que a verificação em relação ao primeiro valor informado, para

tomá-lo como maior é feita agora na mesma expressão que verifica se o valor informado é maior do que se tem registrado como maior do conjunto. */

if (nDia == 1 || frmLancaValores->nQuantidade > nMaiorQuantidade) {

nDiaMaior = nDia;

nMaiorQuantidade = frmLancaValores->nQuantidade;

}

lblDia->Caption = IntToStr(nDiaMaior);

lblQuantidadeDia->Caption = IntToStr(nMaiorQuantidade);

lblTotal->Caption = IntToStr(nTotalPares);

Page 37: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

Estrutura de Repetição 157

> while (nDia != 30);

lblDia->Font->Color = cIBlue;

lblQuantidadeDia->Font->Color = cIBlue;

lblTotal->Font->Color = cIBlue;

frmLancaValores->Free();

btnIniciar->Caption = "Novo Lançamento";

// Libera para começar um novo lançamento

else {

btnIniciar->Tag = 0;

lblDia->Font->Color = cIWindowText;

lblQuantidadeDia->Font->Color = cIWindowText;

lblTotal->Font->Color = cIWindowText;

lblDia->Caption = "0";

lblQuantidadeDia->Caption = "0";

lblTotal->Caption = "0";

btnIniciar->Caption = "Iniciar o Lançamento";

>>___________________________________________

8.9.2.3.2 Para o Formulário Secundário

Resolução 8.7.3 - Inclusão de variáveis públicas

class TfrmLancaValores : public TForm

{__published: // IDE-managed Components

TGroupBox *pnlLancamento;

TLabel *Label4;

TEdit *edtPares;

TBitBtn *btnConfirmar;

void __fastcall FormShow(TObject *Sender);

void __fastcall btnConfirmarClick(TObject *Sender);

private: // User declarationspublic: // User declarations

__fastcall TfrmLancaValores(TComponent* Owner);

int nQuantidade;

>;_______________________________________________

Resolução 8.7.4- Evento OnShowdo Form

void __fastcall TfrmLancaValores: :FormShow(TObject *Sender)

{edtPares->SetFocus();

_>_____________________________________________________

Page 38: Estrutura de Repetição - eisnt.org+/manuais/08_Estruturas_repeticao.pdf · informa o número que deseja obter o valor do fatorial e, então, pressi- ona o botão Calcular, assim,

158 C++ Builder: Implementação de Algoritmos e Técnicas para Ambientes Visuais

Resolução 8.7.5 - Evento OnClickáo botão Confirmar

void __fastcall TfrmLancaValores: :btnConfirmarClick(TObject *Sender)

{try {

nQuantidade = StrToInt(edtPares->Text);

>catch(...) {

MessageDlg("Valor informado como quantidade é inválido", mtError,

TMsgDlgButtons() << mbOK, 0);

Abort();

>if (nQuantidade < 0) {

MessageDlg("Não são aceitas quantidades negativas.", mtWarning,

TMsgDlgButtons() << mbOK, 0);

AbortQ;

>

Close();

_>___________________________________________________________

8.10 Conclusão

Este capítulo apresentou informações essenciais sobre estruturas de repetição, que são muito utilizadas na programação. É preciso enten-der as três formas da estrutura, existem situações para que cada uma seja utilizada, por isso não leve dúvida para o próximo capítulo.

A elaboração de programas/algoritmos que necessite da estrutura de repetição sempre envolverá uma experiência anterior. Interessante é fazer uma versão inicial e ir aperfeiçoando ou corrigindo. Quanto mais experiência você tiver, mais rapidamente vai programar.

Foi, ainda, introduzida a utilização de mais de um formulário em apenas uma aplicação, o que será muito comum. Esses formulários podem ser definidos para que sejam criados automaticamente na cha-mada ou quando solicitados pelo usuário.

Exercícios

1. Faça um programa que gere um número aleatório (use o Randomize). O usuário deverá acertar o número gerado, sendo que o programa deverá norteá-lo para o acerto, ou seja, informar se o número encontra-se acima ou abaixo desse número aleató-rio. Informar, também, ao final, quantas vezes o usuário precisou para acertar o número. Obs.: o número a ser gerado deverá estar entre 0 e 100.