




                                CAPTULO 4              
            
                          ESTRUTURAS DE REPETIO     
            
                 A repetio    a  essncia  de  muitas  aplicaes  em
            computadores. Uma estrutura de repetio  uma estrutura que
            comanda os  processos de  repetio, por  mais  complexos  e
            complicados que sejam.
                 Uma tarefa  essencial no  projeto de qualquer estrutura
            de repetio  (tambm chamada  de "loop"  ou "lao")   como
            decidir quando  as repeties (ou iteraes) devem terminar.
            O Pascal  oferece trs  estruturas de  repetio diferentes,
            cada uma  com um esquema prprio para o controle do processo
            de repetio: os comandos FOR, WHILE e REPEAT.
            
            4.1. A ESTRUTURA DE REPETIO FOR    
            
                 O FOR especifica explicitamente a faixa de iteraes. A
            quantidade de  iteraes   controlada por  uma varivel  de
            controle que deve ser do tipo ordinal, cujo valor aumenta ou
            diminui  medida que cada repetio  executada.
                 Sua sintaxe :
            
                 FOR Varivel := ValorInicial TO ValorFinal DO
                   comando;
            ou
                 FOR Varivel := ValorInicial DOWNTO ValorFinal DO
                   comando;
            
            onde:
            
                 VARIVEL   a varivel de controle do FOR, que deve ser
            do tipo ordinal.
                 VALORINICIAL   o valor  que  a  varivel  de  controle
            assumir na  primeira iterao.  Deve ser  do mesmo  tipo da
            varivel de controle.
                 VALORFINAL    o  valor  que  a  varivel  de  controle
            assumir na  ltima iterao.  Deve ser  do  mesmo  tipo  da
            varivel de controle.
                 COMANDO     o  comando  que  ser  executado  em  cada
            iterao. Pode  ser uma  seqncia finita de outros comandos
            delimitada por BEGIN-END (comando composto).
                 Se ValorInicial  <= ValorFinal, ento deve ser usado um
            FOR-TO. Caso contrrio, deve ser usado um FOR-DOWNTO.
            
                 Um esboo da execuo do FOR  o seguinte:
            
                 (1) No  incio da  execuo,  a  varivel  de  controle
            recebe  o   valor  correspondente   ao  VALORINICIAL.  Se  o
            VALORINICIAL for  menor do  que ou  igual ao  VALORFINAL, no
            caso do  FOR-TO, ou  se o  VALORINICIAL for  maior do que ou
            igual ao VALORFINAL, no caso do FOR-DOWNTO, ento a primeira
            iterao   executada, isto , o comando escrito aps o DO 
            executado.

                                        - 42 -





                 (2) Antes  de cada  iterao subseqente, a varivel de
            controle recebe  o prximo  valor (no  caso do  FOR-TO) ou o
            valor  anterior   (no  caso   do  FOR-DOWNTO)  do  intervalo
            ValorInicial..ValorFinal (ou ValorFinal..ValorInicial).
                 (3)  O  lao  assim  criado  termina  aps  a  iterao
            corresponde ao ValorFinal.
            
            Exemplo:   FOR  i  :=  1  TO  5  DO  Writeln(Sqr(i));
            onde  i    do  tipo  inteiro,  funciona  da seguinte forma:
                 (1)   atribudo o  valor 1  a i  e,  como  1  <  5,  
            executado o  comando escrito  aps o  DO, o Writeln(Sqr(i)).
            Assim,  mostrado o quadrado de 1 na tela;
                 (2) A  varivel i  passa a  ter  o  valor  seguinte  ao
            anterior, ou  seja,  i  passa  a  valer  2  e  o  comando  
            executado.  mostrado, ento, o quadrado de 2 na tela.
                 (3) A  varivel de  controle i vai ser aumentada de uma
            em uma  unidade e  a cada  acrscimo o  WRITELN  executado.
            Esse processo acaba quando a varivel atingir o valor 5.
                 Quando esse FOR for completamente executado, teremos os
            valores 1,  4, 9,  16 e  25 mostrados  na tela,  um em  cada
            linha.
            
            Exemplo:   FOR  i  :=  5  DOWNTO  1  DO  Writeln(Sqr(i));
                 Este exemplo  funciona de  forma semelhante ao anterior
            mas com  uma diferena:  os valores de i vo variar de 5 at
            1, diminuindo  de 1  em 1.  mostrado na tela os valores 25,
            16, 9, 4 e 1, nessa ordem, um em cada linha.
            
            Exemplo: Seja  x uma  varivel do  tipo char. O FOR a seguir
            mostra na tela todas as letras maisculas ABC...XYZ.
            
                      FOR x := 'A' TO 'Z' DO Write(x);
            
            No entanto,
            
                      FOR x := 'z' DOWNTO 'a' DO Write(x);
            
            mostra o conjunto de todas as letras minsculas: zyxv...cba.
            
            Exemplo:       FOR i := 100 TO 50 DO comando;
            
                           FOR j := 1 DOWNTO 20 DO comando;
            
                 No FOR i... e no FOR j... acima, o comando escrito aps
            o DO no ser executado nenhuma vez.
            
            Exemplo: A varivel de controle do FOR, quando for numrica,
            ter de ser do tipo inteiro e s poder aumentar ou diminuir
            de 1  em 1.  Podemos multiplicar  ou dividir  essa  varivel
            todas as vezes em que ela aparecer no comando, como forma de
            aumentar ou diminuir o valor do incremento em cada iterao.
                 Por exemplo,
                         FOR i := 0 TO 100 DO Writeln(2*i)
            lista todos os pares de 0 a 100, e

                                        - 43 -





                 FOR i := 200 DOWNTO 100 DO Writeln(ArcTan(i/100))
            lista os  valores de  ArcTan(2), ArcTan(1.99), ArcTan(1.98),
            ... at ArcTan(1).
            
            Exemplo: Os  tipos pr-definidos  byte e  char ambos tm 256
            valores. As  funes que  estabelem uma  bijeo entre esses
            valores so as funes ORD e CHR, inversas uma da outra.
            
                      CHR(n) ---> n-simo caracter do tipo char;
            
                      ORD(x) ---> Ordinal do caracter x.
            
                 Os valores que o n acima podem assumir so de 0 a 255 e
            o x  desde o  primeiro ao  ltimo caracter  pr-definido  do
            computador (de um total de 256).
                 CHR(n) tambm pode ser denotado como #n.
                 Alguns valores particulares dessas funes so:
            
                 ORD('$') =  36       CHR(36)  = '$'  ou   #36 = '$'
                 ORD('+') =  43       CHR(43)  = '+'  ou   #43 = '+'
                 ORD('7') =  55       CHR(55)  = '7'  ou   #55 = '7'
                 ORD('A') =  65       CHR(65)  = 'A'  ou   #65 = 'A'
                 ORD('B') =  66       CHR(66)  = 'B'  ou   #66 = 'B'
                 ORD('C') =  67       CHR(67)  = 'C'  ou   #67 = 'C'
                 ORD('Z') =  90       CHR(90)  = 'Z'  ou   #90 = 'Z'
                 ORD('\') =  92       CHR(92)  = '\'  ou   #92 = '\'
                 ORD('a') =  97       CHR(97)  = 'a'  ou   #97 = 'a'
                 ORD('z') = 122       CHR(122) = 'z'  ou  #122 = 'z'
            
                 As tabelas  de valores  de  CHR  ou  ORD  costumam  ser
            chamadas  de  tabelas  ASCII  (American  Standard  Code  for
            Information Interchange).
                 O programa a seguir, gera na tela uma tabela ASCII.
            
            
            PROGRAM TabelaASCII;
            
            { ---------------------------------------- }
            {               TABELA ASCII               }
            { ---------------------------------------- }
            
            USES Crt;
            
            VAR
              i: byte;
            
            BEGIN
              ClrScr;
              Writeln('  n Chr(n)');
              Writeln('-----------');
            
              FOR i := 0 TO 255 DO
              BEGIN
                Writeln(i:4, Chr(i):4);

                                        - 44 -





            
                IF (i MOD 10 = 0) AND (i > 0) THEN
                BEGIN
                  Writeln;
                  Writeln('Pressione [ENTER] para continuar.');
                  Readln;
                  Writeln('  n Chr(n)');
                  Writeln('-----------');
                END; { fim do IF }
            
              END; { fim do FOR }
            
            END. { fim do programa }
            
                 No programa  acima, a  varivel inteira  i varia de 0 a
            255. Devido ao IF (i MOD 10...) , sempre que i for maior que
            0 e  mltiplo de  10 ,  o programa  far uma  pausa. Ao  ser
            pressionado a tecla ENTER, sero mostradas mais 10 linhas da
            tabela e assim o programa prossegue at chegar em i = 255.
                 Alguns caracteres  ASCII so smbolos que no podem ser
            impressos. Por exemplo, o #7  um som de bip (beep).
            
                 Ao ser  executado, ele gera na tela varios trechos como
            esse:
            
              n Chr(n)
            -----------
              61   =
              62   >
              63   ?
              64   @
              65   A
              66   B
              67   C
              68   D
              69   E
              70   F
            
            Pressione [ENTER] para continuar.
            
            Exemplo: O  programa a  seguir  gera  no  papel  uma  tabela
            trigonomtrica. O  ttulo da  tabela    escrito  em  letras
            expandidas. Para  isso, precisamos  antes consultar o manual
            da impressora  para vermos os cdigos que ativam e desativam
            o tipo  expandido das  letras. No caso da impressora RIMA XT
            180, bastante  comum na poca em que este texto foi escrito,
            o que ativa o modo expandido na impressora  um comando como
            
                           Write(Lst, Chr(27), 'W', Chr(1));
            
                 Para desativar o modo expandido deve ser executado:
            
                           Write(Lst, Chr(27), 'W', Chr(0));
            

                                        - 45 -





                 Normalmente, os  manuais das  impressoras  trazem  esse
            tipo de  informao em  BASI cuja traduo para o Pascal 
            imediata: basta trocar LPRINT (do BASIC) por WRITE(LST, CHR$
            por CHR  e trocar  aspas (")  por apstrofo.  Por exemplo, o
            comando que  ativa o modo expandido da impressora, em BASI
            
                           LPRINT CHR$(27), "W", CHR$(1)
            e   esse tipo de comando normalmente encontrado nos manuais
            de impressoras.
                 Usaremos tambm o tipo de letra negrito em duas linhas,
            o que  conseguido com os seguintes comandos:
            
                 Write(Lst, Chr(27), 'E'); ---> ativa o tipo negrito
                 Write(Lst, Chr(27), 'F'); ---> desativa o tipo negrito
            
            
            PROGRAM TabelaTrigonometrica;
            
            USES Printer;
            
            VAR
              AnguloEmGraus: byte;
              AnguloEmRadianos, seno, cosseno, tangente: real;
            
            CONST
              Traco1 =
             '----------------------------------------------------';
              Traco2 =
             '====================================================';
            
            BEGIN
              Writeln;
              Writeln('IMPRESSAO DE UMA TABELA TRIGONOMETRIC);
              Writeln;
              Writeln('Verifique se a impressora esta'' pronta e ',
                       'pressione [ENTER].');
              Readln; { pausa }
            
              Writeln(Lst, Traco2);
              Write(Lst, Chr(27), 'W', Chr(1));   { ativa o tipo de }
                                                  { letra expandido }
              Writeln(Lst, '  TABELA TRIGONOMETRICA');
              Write(Lst, Chr(27), 'W', Chr(0)); { desativa o tipo de }
                                                { letra expandido    }
              Writeln(Lst, Traco2);
              Write(Lst, Chr(27), 'E'); {ativa o tipo de letra negrito }
              Writeln(Lst, '  X      SEN(X)    COS(X)    TG(X)',
                                                        '     COTG(X)');
              Write(Lst, Chr(27), 'F');      { desativa o tipo negrito }
              Writeln(Lst, Traco1);
            
              FOR AnguloEmGraus := 1 TO 45 DO
              BEGIN
                AnguloEmRadianos := AnguloEmGraus*Pi/180;

                                        - 46 -





                seno := Sin(AnguloEmRadianos);
                cosseno := Cos(AnguloEmRadianos);
                tangente := seno/cosseno;
                Writeln(Lst, AnguloEmGraus:3, ' | ', seno:10:6,
                           cosseno:10:6, tangente:10:6, 1/tangente:10:6,
                                         ' | ', (90 - AnguloEmGraus):2);
              END;
            
              Writeln(Lst, Traco1);
              Write(Lst, Chr(27), 'E';); {ativa o tipo de letra negrito }
              Writeln(Lst, '         COS(X)    SEN(X)    COTG(X)',
                                                     '   TG(X)      X');
              Write(Lst, Chr(27), 'F');      { desativa o tipo negrito }
              Writeln(Lst, Traco2);
            END.
            
                 Este programa gera no papel a seguinte tabela:
            
            ====================================================
              TABELA TRIGONOMETRICA
            ====================================================
              X      SEN(X)    COS(X)    TG(X)     COTG(X)         
            ----------------------------------------------------
              1 |   0.017452  0.999848  0.017455 57.289962 | 89
              2 |   0.034899  0.999391  0.034921 28.636253 | 88
              3 |   0.052336  0.998630  0.052408 19.081137 | 87
             ...       ...       ...       ...       ...    ...
             45 |   0.707107  0.707107  1.000000  1.000000 | 45
            ----------------------------------------------------
                     COS(X)    SEN(X)    COTG(X)   TG(X)      X    
            ====================================================
            
            
                 Antes do  prximo exemplo,  uma observao  importante.
            Uma atribuio  bastante comum em programas  uma atribuio
            do tipo  X :=  X +  1. Essa  atribuio substitui X por X+1.
            Desse modo,  se X valia 9 antes de uma atribuio como essa,
            aps a execuo teremos X = 10.
                 Em geral,  X :=  f(X) significa  que X deve ser trocado
            por f(X).
            
            Exemplo:  Neste  exemplo,  vamos  calcular  o  valor  de  um
            somatrio.  Em  particular,  consideraremos  a  soma  dos  5
            primeiros termos da srie cujo termo geral  1/(n^2 + 1).
                 Chamaremos a  varivel  que  vai  guardar  o  valor  do
            somatrio de S. Em todo clculo de somatrio, a varivel que
            ir guardar  o valor  da soma  dever ter  um valor  inicial
            nulo. A  seguir, usamos  um FOR  com  varivel  de  controle
            fazendo o  papel do  ndice do termo geral do somatrio para
            atuar no  comando S  := S + Termo_Geral, o que neste caso, 
            S := S + 1/(n^2 + 1). Ao final da execuo do FOR, temos em S
            o valor da soma desejada.
            
            

                                        - 47 -





            PROGRAM Somatorio;
            
            { ------------------------------------------- }
            {           CALCULO DE UM SOMATORIO           }
            { ------------------------------------------- }
            
            VAR
              S: real;
              n: word;
            
            CONST
              IndiceInicial = 1;
              IndiceFinal = 5;
            
            BEGIN
              S := 0; { valor inicial de S }
            
              FOR n := IndiceInicial TO IndiceFinal DO
                S := S + 1/(Sqr(n) + 1);
            
              Writeln('Valor do somatorio = ', S:8:4);
            END.
            
                 Neste exemplo,  so feitas  as seguintes atribuies de
            valores a S:
            
                 S := 0;
                 S := 0 + 1/2;                             ( n = 1 )
                 S := 1/2 + 1/5;                           ( n = 2 )
                 S := (1/2 + 1/5) + 1/10;                  ( n = 3 )
                 S := (1/2 + 1/5 + 1/10) + 1/17;           ( n = 4 )
                 S := (1/2 + 1/5 + 1/10 + 1/17) + 1/26;    ( n = 5 )
            
            Exemplo: Neste  exemplo, queremos  calcular a soma dos 10000
            primeiros termos  das sries  cujos termos  gerais so 1/n e
            1/n^2. No  vamos nos  contentar s  com o  resultado  final,
            queremos acompanhar  o valor  do somatrio  de 1000  em 1000
            termos. A  srie 1/n^2  converge para (Pi^2)/6; logo, a raiz
            quadrada  de  6  vezes  o  somatrio  de  1/n^2  fornece  uma
            aproximao para o valor de Pi.
                 Usaremos quatro  caracteres ASCII especiais: o #227 que
             um  pi minsculo,  o #228 que  um sigma maisculo, o #253
            que   um expoente  2  e o #247 que usaremos como smbolo
            de "aproximadamente".
                 A unidade  CRT dispe  de dois comandos para alterar as
            cores de  textos da tela. So eles o TEXTCOLOR, para alterar
            a cor  do texto,  e TEXTBACKGROUND,  para alterar  a cor  de
            fundo. Suas sintaxes so:
            
                           TextColor(Nome_da_cor)
            e
                           TextBackground(Nome_da_cor)
            
            onde Nome_da_cor pode ser uma das seguintes constantes:

                                        - 48 -





            
                     Black        = 0;      Blue         = 1;
                     Green        = 2;      Cyan         = 3;
                     Red          = 4;      Magenta      = 5;
                     Brown        = 6;      LightGray    = 7;
                     DarkGray     = 8;      LightBlue    = 9;
                     LightGreen   = 10;     LightCyan    = 11;
                     LightRed     = 12;     LightMagenta = 13;
                     Yellow       = 14;     White        = 15;
                     Blink        = 128;
            
                 Em cada caso, pode ser usado o nome ou o nmero da cor.
            Deve-se somar  "blink" ou  128 ao  nome ou  nmero da cor do
            texto  para   se  ter  caracteres  piscantes.  Por  exemplo,
            TextColor(Yellow)  o mesmo que TextColor(14) e ajusta a cor
            do texto  para amarelo.  Se  somarmos  128  a  14,  como  em
            TextColor(14 + 128) teremos um amarelo piscante.
                 Usaremos esses comandos para alterar a cor do cabealho
            do programa;  queremos v-lo em vdeo reverso (letras pretas
            em fundo branco).
            
            
            PROGRAM DoisSomatorios;
            
            { =================================================== }
            {        CALCULO SIMULTANEO DE DOIS SOMATORIOS        }
            { =================================================== }
            
            USES
              Crt;
            
            VAR
              n: longint;
              Soma1, Soma2: real;
            
            BEGIN
              ClrScr;
              Writeln;
              TextColor(Black);
              TextBackground(White);
              Writeln('    ', #228, ' 1/n    ', #228,
                                        ' 1/n', #253, '   ');
              TextColor(White);
              TextBackground(Black);
              Writeln;
            
              Soma1 := 0;
              Soma2 := 0;     (* valores iniciais dos somatorios *)
            
              FOR n := 1 TO 10000 DO
              BEGIN
                Soma1 := Soma1 + 1/n;
                Soma2 := Soma2 + 1/Sqr(n);
                IF (n MOD 1000 = 0) THEN         (* Se n for multiplo *)

                                        - 49 -





                  Writeln(Soma1:10:6, Soma2:10:6);  (* de 1000, entao *)
              END;            (*  mostrada o valor da soma parcial. *)
            
              Writeln;
              Writeln('  ', #227, ' ', #247, ' ', Sqrt(6*Soma2):8:6);
            END.
            
                 Aps a  execuo, vemos  na tela  a listagem  a seguir.
            Onde  escrevemos   "S",  "Pi"   e  "=",  aparecem  na  tela,
            respectivamente,   um sigma  maisculo, um pi minsculo e um
            smbolo de aproximao.
            
                S 1/n    S 1/n^2
            
              7.485471  1.643935
              8.178368  1.644434
              8.583750  1.644601
              8.871390  1.644684
              9.094509  1.644734
              9.276814  1.644767
              9.430953  1.644791
              9.564475  1.644809
              9.682251  1.644823
              9.787606  1.644834
            
              Pi = 3.141497
            
                 Vemos na  ltima linha  da tabela acima que o valor das
            somas dos 10000 termos das sries  9.787606 e 1.644834.
            
            Exemplo: Fornecido um inteiro n, vamos construir um programa
            que fornea o fatorial de n.
            
                 Vamos chamar  a varivel  que vai  guardar o  valor  do
            produto de  P. Inicialmente,  deveremos fazer P := 1. Alis,
            para calcularmos  repetidamente  uma  determinada  operao,
            deveremos fazer  inicialmente a  varivel que  vai guardar o
            resultado final igual ao elemento nutro da operao.
                 A seguir,  usamos um  FOR com  um comando  do tipo P :=
            P*Termo_Geral, o que, neste caso,  P := P*n  ("n"  o termo
            geral do produto neste caso).
                 Como o  fatorial costuma  dar resultados grandes, vamos
            declarar P como sendo do tipo extended. S que, toda vez que
            se usar  um tipo  extended, comp,  single ou  double  em  um
            programa deve-se  colocar a  diretiva de compilao {$E+,N+}
            no  incio   do  programa.   Maiores  informaes  sobre  as
            diretivas de  compilao sero  dadas  posteriormente.  Elas
            servem para  alterar o  modo como o programa  compilado. No
            caso do tipo extended  que ele exige que o computador tenha
            um chip  chamado coprocessador  aritmtico 8087. Como apenas
            uma minoria  de computadores  possui esse  coprocessador,  a
            diretiva {$E+,N+} faz uma simulao do mesmo.
            
                 Temos ento o seguinte:

                                        - 50 -





            
            PROGRAM Fatorial;
            
            {$E+,N+}
            
            VAR
              i, n: word;
              P: extended;
            
            BEGIN
              Write('Valor de N? '); Readln(n);
            
              P := 1;
              FOR i := 2 TO n DO
                P := P * i;
            
              Writeln;
              Writeln(n, '! = ', P);
            
            END.
            
                 Neste   exemplo,    sero   executadas   as   seguintes
            atribuies:
            
                           P := 1;
                           P := 1*2;                ( i = 2 )
                           P := (1*2)*3;            ( i = 3 )
                           P := (1*2*3)*4;          ( i = 4 )
                           ...           ...           ...
                           P := (1*2*...*(n-1))*n;  ( i = n )
            
            Um exemplo de execuo desse programa:
            
            Valor de N? 1500
            
            1500! =  4.81199779677977E+4114
            
            Exemplo: Fornecido  um inteiro N, queremos agora um programa
            que diga  se N   primo  ou  no.  Nosso  algoritmo  ser  o
            seguinte: faremos  uma varivel  i variar de 2 at o inteiro
            mais prximo  da raiz  quadrada de  N. Usaremos  um FOR i...
            para isso.  Para cada  valor de  i, calculamos  o  resto  da
            diviso de  N por i, ou seja, N MOD i. Se houver algum resto
            nulo, isto  , se  N MOD  i = 0 para algum i, isto significa
            que N   divisvel  por i  e, portanto,  N nesse  caso no 
            primo. Se  no acontecer  de N MOD i = 0 com i variando de 2
            at ROUND(SQRT(N)), ento N  primo.
            
            
            PROGRAM Primo;
            
            VAR
              N, i: longint;
            

                                        - 51 -





            BEGIN
              Write('Forneca um inteiro N : '); Readln(N);
            
              IF (N < 0) THEN N := -N; { se N for negativo, ento ele }
                                       { ter seu sinal trocado       }
            
              IF (N <= 1) THEN                   { casos particulares }
                Writeln(N, ' nao e'' primo.')    { N = 0 e N = 1      }
              ELSE
              BEGIN        { caso geral }
            
                FOR i := 2 TO Round(Sqrt(N)) DO
                  IF (N MOD i = 0) THEN
                  BEGIN
                    Writeln(N, ' nao e'' primo');
                    Halt; { encerra o programa }
                  END;
            
                { No caso do FOR encerrar com N MOD i <> 0 para
                  todo i, temos que N e' primo: }
                Writeln(N, ' e'' primo.');
            
              END; { fim do IF }
            END.
            
            Como um exemplo de execuo, temos:
            
            Forneca um inteiro N : 1000000007
            1000000007 e' primo.
            
            Exemplo: A varivel de controle de um FOR tambm pode ser do
            tipo booleano. Neste exemplo faremos um programa que imprime
            uma tabela-verdade de uma determinada expresso lgica. Para
            isso, usaremos  dois FOR  encaixados  para  gerar  todas  as
            "entradas" da tabela.
                 A expresso  lgica  deste  exemplo    (X  OR  Y)  AND
             (NOT X OR NOT Y) que denotaremos por (X v Y) ^ (~X v ~Y).
            
            PROGRAM TabelaVerdade;
            
            VAR
              x, y, expressao: boolean;
            
            BEGIN
              Writeln;
              Writeln('--------------------------------');
              Writeln('  X    Y   (X v Y) ^ (~X v ~Y)');
              Writeln('--------------------------------');
            
              for x := FALSE to TRUE do
                for y := FALSE TO TRUE do
                begin
                  if x then Write('  V  ') else Write('  F  ');
                  if y then Write('  V  ') else Write('  F  ');

                                        - 52 -





                  expressao := (x OR y) AND (NOT x OR NOT y);
                  if expressao then
                    Writeln('          V')
                  else
                    Writeln('          F');
                end; (* fim do FOR y ... *)
            
              Writeln('--------------------------------')
            END.
            
                 O nico comando do FOR x ...  o FOR y ... . No caso de
            laos  FOR   encaixados,  o  FOR  mais  interno  varia  mais
            rapidamente que o mais externo.
            
                 Executando-se esse programa, temos a seguinte tabela:
            
            --------------------------------
              X    Y   (X v Y) ^ (~X v ~Y)
            --------------------------------
              F    F            F
              F    V            V
              V    F            V
              V    V            F
            --------------------------------
            
                 Observando a  tabela  acima,  podemos  concluir  que  a
            expresso (x  OR y) AND (NOT x OR NOT y)  equivalente ao ou
            exclusivo  x XOR y.
            
            Exemplo: O  i-simo caracter  de uma  constante  X  do  tipo
            string, pode  ser referenciado  como X[i] e considerado como
            sendo do tipo char. Por exemplo, se X = 'UFPB', ento X[1] =
            ', X[2] = 'F', X[3] = 'P', X[4] = 'B'. Relacionado com uma
            constante ou  varivel X  do tipo  string,  temos  a  funo
            LENGTH(X) que calcula o comprimento, ou melhor, a quantidade
            de caracteres  de X.  Por exemplo,  LENGTH('Paraib)  =  7,
            LENGTH('Joao Pesso) = 11, etc.
                 Nosso atual  programa-exemplo, pede ao usurio que seja
            digitada uma mensagem (string) com no mximo 200 caracteres.
            Uma vez  feito isso,  o programa  conta quantas  vezes  cada
            vogal aparece na mensagem.
            
            PROGRAM Vogais;
            
            VAR
              mensagem: string[200];
              QuantA, (* quantidade de "A" na mensagem *)
              QuantE, (* quantidade de "E" na mensagem *)
              QuantI, (* quantidade de "I" na mensagem *)
              QuantO, (* quantidade de "O" na mensagem *)
              QuantU, (* quantidade de "U" na mensagem *)
              QuantX, (* quantidade de outros caracteres na mensagem *)
                   i: (* varivel de controle do FOR *)
                      byte;

                                        - 53 -





            
            BEGIN
              QuantA := 0;    (* A quantidade de cada  caracter, *)
              QuantE := 0;    (* antes do incio da contagem,   *)
              QuantI := 0;    (* suposta nula.  medida que cada *)
              QuantO := 0;    (* caracter for sendo  contado,  a *)
              QuantU := 0;    (* respectiva varivel ser incre- *)
              QuantX := 0;    (* mentada de 1 em 1 unidade.      *)
            
              Writeln;
              Writeln('Escreva uma mensagem (max. 200 caracteres) : ');
              Writeln;
              Readln(mensagem);
              Writeln;
            
              FOR i := 1 to LENGTH(mensagem) do
                CASE mensagem[i] OF
                  'a', 'A' : QuantA := QuantA + 1;
                  'e', 'E' : QuantE := QuantE + 1;
                  'i', 'I' : QuantI := QuantI + 1;
                  'o', 'O' : QuantO := QuantO + 1;
                  'u', 'U' : QuantU := QuantU + 1;
                  ELSE
                             QuantX := QuantX + 1;
                END;
            
              Writeln('Total de A = ', QuantA);
              Writeln('Total de E = ', QuantE);
              Writeln('Total de I = ', QuantI);
              Writeln('Total de O = ', QuantO);
              Writeln('Total de U = ', QuantU);
              Writeln('Total de outros caracteres  = ', QuantX);
            
            END.
            
            4.2. A ESTRUTURA DE REPETIO WHILE    
            
                 Um lao  WHILE deve  ser usado  sempre que  se  desejar
            executar um  comando um  nmero varivel  ou desconhecido de
            vezes. Sua sintaxe :
                           WHILE expresso DO comando;
            onde "expresso"   uma expresso booleana e "comando"  uma
            instruo simples ou um comando composto.
                 O  WHILE  funciona  da  seguinte  maneira:  enquanto  a
            expresso booleana  for verdadeira, o comando aps o DO ser
            executado repetidamente.  A expresso  reavaliada aps cada
            execuo do  comando. O  lao WHILE  s se  encerra quando a
            expresso for  falsa. Se  a expresso  for falsa j quando o
            WHILE se  inicia, ento o comando no ser executado nenhuma
            vez.  No  comando,  deve  ter  alguma  instruo  que  possa
            modificar o  valor da expresso booleana, seno o WHILE ser
            executado indefinidamente.
            
            

                                        - 54 -





                                       WHILE
                                         |
                                        /\
                                FALSE  /  \
                                +--<--<cond>---<--+
                                |      \  /       |
                                |       \/        |
                                v       | TRUE    ^
                                |       v         |
                                |   +---------+   |
                                |   | comando |->-+
                                |   +---------+
                                v
            
            Exemplo:            ...
                                x := 11;
                                WHILE (x < 1992) DO
                                BEGIN
                                  Write(x:5);
                                  x := x + 11;
                                END;
                                ...
                 Este fragmento de programa funciona da seguinte forma:
                 (1) Aps  a atribuio  inicial (que   recomendada  em
            todo WHILE)   avaliada a expresso booleana x < 1992. Sendo
            ela verdadeira  (porque 11 < 1992), o comando composto entre
            o BEGIN  e o  END   executado. Desse modo, 11  mostrado na
            tela e  a atribuio  x :=  x +  11   executada e x passa a
            valer 11 + 11 = 22.
                 (2) A  expresso x  < 1992   reavaliada com x = 22 e 
            novamente verdadeira.  O comando  composto ento  executado
            mais uma vez e x passa a valer 22 + 11 = 33.
                 (3) A  seqncia AVALIAR  EXPRESSO -> EXECUTAR COMANDO
            -> AVALIAR  EXPRESSO ->  EXECUTAR COMANDO  -> ... se repete
            vrias vezes at que x assuma um valor maior do que ou igual
            a 1992 e a expresso passe a ser falsa.
                 (4) Quando  a expresso  for falsa,  o  lao  WHILE  se
            encerrar e  o controle  do programa  passar para o comando
            seguinte ao WHILE.
                 Assim, o  fragmento  acima  mostra  na  tela  todos  os
            mltiplos  de  11  que  so  menores  que  1992.  Assumimos,
            implicitamente, que x  inteiro. No WHILE as variveis podem
            ser de qualquer tipo: inteiro, real, string, ... .
            
            Exemplo: O  programa a  seguir conta  quantos termos do tipo
            1/n com  n inteiro  e n  >= 1  so necessrios somar para se
            obter um resultado maior do que 15.
            
            PROGRAM ContaParcelas;
            
            (*                                          1     1
               Determina a quantidade de termos de 1 + --- + --- + ...
                                                        2     3
               que  necessrio  somar  para se  ter uma  soma > 15.  *)

                                        - 55 -





            
            VAR
              n: longint;
              soma: real;
            
            BEGIN
              soma := 0;    (* Valores iniciais das variveis *)
              n := 0;       (* usadas no WHILE                *)
            
              WHILE soma <= 15 DO    (*      "ENQUANTO a soma no for *)
              BEGIN                  (*  maior que 15 ...             *)
                n := n + 1;
                soma := soma + 1/n;  (* ... some termos da forma 1/n" *)
              END;
            
              Writeln('Deve-se somar ', n, ' parcelas.');
            END.
            
                 Neste exemplo  no  h  possibilidade  de  se  usar  um
            comando como  o FOR porque no se sabe a quantidade de vezes
            que o  comando soma  := soma  + 1/n  deve ser  executado.  A
            "resposta" do  programa acima   que deve-se somar 1.835.421
            termos do tipo 1/n para se ter uma soma maior do que 15.
            
            Observao: O  comando FOR pode ser considerado como um caso
            particular  de   WHILE.    o  que  est  exemplificado  nos
            fragmentos abaixo, onde todas as variveis so inteiras.
            
                                                    i := LimInf;
            FOR i := LimInf TO LimSup DO    <-->    WHILE i <= LimSup DO
              comando;                              BEGIN
                                                      comando;
                                                      i := i + 1;
                                                    END;
            
            4.3. A ESTRUTURA DE REPETIO REPEAT-UNTIL    
            
                 A estrutura  REPEAT-UNTIL, assim  como o WHILE,  usada
            quando no  for conhecida  a priori o nmero de vezes em que
            uma seqncia de comandos vai ser repetidamente executada.
            Sua sintaxe :
                                REPEAT
                                  comando1;
                                  comando2;
                                  ...
                                UNTIL expresso;
            onde  "expresso"    uma  expresso  booleana  e  comando1,
            comando2, ...  so instrues simples ou comandos compostos.
            Neste caso  os delimitadores  BEGIN/END NO so necessrios, 
            pois  as  palavras  chave  REPEAT  e  UNTIL  funcionam  como
            delimitadores.
                 No REPEAT-UNTIL  os comandos  entre o  REPEAT e o UNTIL
            sero  executados   AT  que   a  expresso   booleana  seja

                                        - 56 -





            verdadeira. Como  a avaliao  da expresso  feita no final
            do lao, os comandos sero executados pelo menos uma vez.
            
                                  REPEAT
                                    |
                                +---------+
                                | comando |--<--+
                                +---------+     |
                                    |           |
                                  UNTIL         ^
                                   /\           |
                                  /  \ FALSE    |
                                 <cond>---->----+
                                  \  /
                                   \/
                                    | TRUE
                                    v
            
            Observao: Um  REPEAT-UNTIL tem o mesmo efeito que um WHILE
            com a expresso booleana que controla o lao negada:
            
              REPEAT               <--->     WHILE NOT expresso DO
                comando;                       comando;
              UNTIL expresso;
            
                 Uma diferena  significativa entre  o REPEAT-UNTIL  e o
            WHILE   que no  REPEAT-UNTIL o  comando sempre   executado
            pelo menos  uma vez  e no  WHILE, o  comando  pode  nem  ser
            executado, dependendo da avaliao inicial da expresso.
            
            Exemplo: Nosso  primeiro programa-exemplo com o REPEAT-UNTIL
            espera que o usurio digite vrios nomes. O aviso do usurio
            para que  o programa  encerre a  solicitao de nomes ser a
            senha  (flag)  "FIM"  ou  "fim".  O  programa  ainda  tem  a
            "sofisticao" de contar quantos nomes foram digitados.
                 Temos ento  uma situao  que se repetir ("o programa
            pedir nomes")  at que  outra ("o  usurio digitar  FIM  ou
            fim") acontea, um caso tpico de REPEAT-UNTIL.
            
            PROGRAM Nomes;
            
            (* Comentrio:
               -----------
                   Este programa  til porque ele mostra que computador
               tambm sabe contar nomes digitados. *)
            
            VAR
              nome: string;
              cont: integer;
            
            BEGIN
              cont := 0;
              REPEAT
                Write('Nome? ');

                                        - 57 -





                Readln(nome);     (* Cada vez que um nome for lido *)
                cont := cont + 1; (* o contador de  nomes  CONT   *)
                                  (* incrementado   de  1  unidade *)
              UNTIL (nome = 'FIM') OR (nome = 'fim');
            
              Writeln('Foram digitados ', cont - 1, ' nomes.');
            END.
            
                 A varivel  CONT que  conta os nomes digitados ao final
            da execuo  do REPEAT-UNTIL  ter contado a senha de parada
            ("FIM" ou  "fim") como  sendo mais  um nome.  Devido a isso,
            usamos CONT - 1, e no CONT, no Writeln final.
            
            Exemplo: Neste  exemplo,  queremos  digitar  vrios  nmeros
            maiores do  que ou  iguais a  zero e queremos que o programa
            nos d  o valor  de sua  mdia aritmtica.  A princpio, no
            temos  uma  previso  da  quantidade  de  nmeros  que  ser
            digitada. No  entanto, podemos  convencionar que  quando  se
            digitar um nmero negativo, significar que nossa relao de
            nmeros acabou.  O nmero negativo que funciona como o aviso
            do fim  da  relao,  no  deve  ser  considerado  na  mdia
            aritmtica.
                  medida  que cada  nmero positivo  for fornecido, uma
            varivel dever  ir sendo  incrementada de  1 em  1 para  se
            contar quantos  nmeros foram  digitados. Alm  disso, vamos
            calculando o  somatrio dos  valores, assim  que cada nmero
            for digitado.
                 Temos aqui  algo que  ser executado VRIAS vezes. Como
            no temos  previso inicial exata da quantidade de iteraes
            temos um  caso em  que   receitado um  WHILE ou  um REPEAT-
            UNTIL. Resta  apenas o usurio se decidir entre um dos dois.
            Neste caso,  excepcionalmente, vamos  dar duas  verses para
            este programa: a verso WHILE e a verso REPEAT-UNTIL.
            
            
            PROGRAM MediaAritmetica;   (* versao REPEAT-UNTIL *)
            
            VAR
              x, soma, media: real;
              cont: integer;
            
            BEGIN
              cont := 0; (* Quantidade inicial de nmeros digitados *)
              soma := 0; (* Soma inicial dos nmeros digitados      *)
            
              REPEAT
                Readln(x);
                if x >= 0 then
                begin
                  cont := cont + 1;
                  soma := soma + x;
                end;
              UNTIL x < 0;
            

                                        - 58 -





              media := soma/cont;
              Writeln('Media aritmetica dos numeros digitados = ',
                                                            media:8:4);
            END. (* fim do programa *)
            
            
            PROGRAM MediaAritmetica;   (* versao WHILE *)
            
            VAR
              x, soma, media: real;
              cont: integer;
            
            BEGIN
              cont := 0;  (* Quantidade inicial de nmeros digitados *)
              soma := 0;  (* Soma inicial dos nmeros digitados      *)
              x := 0;     (* Valor inicial de x. No WHILE  recomen- *)
                          (* dado se inicializar as variveis.       *)
            
              WHILE x >= 0 DO  (* a condio do WHILE  a negao da *)
              BEGIN            (* condio do REPEAT-UNTIL           *)
                Readln(x);
                if x >= 0 then
                begin
                  cont := cont + 1;
                  soma := soma + x;
                end;
              END;
            
              media := soma/cont;
              Writeln('Media aritmetica dos numeros digitados = ',
                                                            media:8:4);
            END. (* fim do programa *)
            
            Exemplo: No presente exemplo, queremos que o computador gere
            aleatoriamente um  nmero de  0 a  10000. O  usurio  dever
            tentar advinhar  o nmero  chutado pelo  computador. A  cada
            tentativa do  usurio, o programa dever informar se o chute
            do usurio foi maior ou menor que o nmero chutado no incio
            do programa.
                 O progama tambm deve contar a quantitade de tentativas
            do usurio.
            
            
            PROGRAM AdvinhacaoDeUmNumero;
            
            (*
                  chutado um numero inteiro entre 0 e 10000 que o
                 usuario deve tentar advinhar.
            *)
            
            USES Crt;
            
            VAR n, tentativa, numero: word;
            

                                        - 59 -





            BEGIN
              n := 0;
              Randomize;
              numero := Random(10001);
              Writeln('Adivinhe o numero aleatorio gerado entre 0',
                                                           ' e 10000!');
            
              REPEAT
                Write('> '); Readln(tentativa);
                n := n + 1;
                IF tentativa > numero THEN
                  Writeln('Chute muito alt)
                ELSE
                  IF tentativa < numero THEN
                    Writeln('Chute muito baix);
              UNTIL (tentativa = numero);
            
              Writeln('Acertou! (apos ter tentado ', n,  ' vezes)');
            END.
            
            Exemplo: A srie
                              1       1       1       1
                 S  =  1  -  ---  +  ---  -  ---  +  ---  -  ....
                              3^3     5^3     7^3     9^3
            converge para (Pi^3)/32.
                 Neste exemplo,  vamos elaborar  um  programa  que  some
            todos os  termos dessa  srie que, em mdulo, so maiores ou
            iguais a  10^-10. O resultado dessa soma, pode ser usado para
            se calcular Pi com 10 decimais exatas.
                 Como no sabemos quantos termos devemos somar, temos um
            caso de REPEAT-UNTIL ou, equivalentemente, de WHILE.
                 Usaremos um  comando da unidade CRT chamado GOTOXY cuja
            funo    posicionar  o  cursor  em  determinada  coluna  e
            determinada linha da tela. Sua sintaxe :
                           GOTOXY(coluna, linha);
                 Por exemplo,  GOTOXY(5, 2) posiciona o cursor na quinta
            coluna e segunda linha da tela. Em modo texto, a tela tem 25
            linhas e 80 colunas.
            
            PROGRAM Soma_Alternada_De_1_Sobre_O_Cubo_De_2n_Menos_1;
            
            USES
              Crt;
            
            (*                  ---
               Calculo de S =   \         n+1        -3
                                /     (-1)   (2n - 1)
                                ---                        *)
            
            VAR
              t, S: real;
              n: integer;
            
            BEGIN

                                        - 60 -





              S := 0;      (* Varivel que guardar a soma desejada *)
              n := 0;      (* Contador de termos  (ndice do  termo *)
              ClrScr;      (* geral)                                *)
            
              REPEAT
                n := n + 1;
                t := EXP(-3*LN(2*n - 1));   (* termo geral *)
                IF Odd(n) THEN
                  S := S + t  (* Se n for mpar,  ento soma-se *)
                ELSE          (* t a S;  caso  contrrio,  sub- *)
                  S := S - t; (* trai-se t de S.                *)
            
                GOTOXY(10, 10); (* Posiciona o cursor na 10a. coluna *)
                                (* e 10a. linha da tela              *)
            
                Write('n = ', n, '   ', t:13:10);  (* mostra o ndice *)
                                    (* atual e o valor do termo geral *)
              UNTIL t < 1E-10;
            
              Writeln; Writeln;
              Writeln('Soma = ', S:15:10);
              Writeln('Foram somados ', n, ' termos');
            END.
            
            Exemplo: A  funo booleana  KEYPRESSED da  unidade CRT pode
            ser usada  para verificar  se  em  determinado  momento  foi
            pressionada alguma  tecla. Ela  TRUE quando for pressionada
            qualquer tecla e FALSE em caso contrrio.
                 O programinha  a seguir,  gera aleatoriamente  cores  e
            caracteres do  intervalo #50..#250  e fica  mostrando-os  na
            tela at  ser pressionado  qualquer tecla. Para isso, usamos
            um RANDOM(16)  para gerar  um nmero  de cor  de 0  a 15, um
            RANDOM(201) +  50 para gerar um nmero inteiro de 50 a 250 e
            um REPEAT  ... UNTIL  KEYPRESSED para repetir o processo at
            ser pressionada alguma tecla.
                 A cor  do texto pode ser piscante ou no, dependendo de
            RANDOM(2) em cor1 gerar um 0 ou um 1.
            
            PROGRAM UsandoKeyPressed;
            
            USES
              Crt;
            
            VAR
              ch: char;
              cor1, cor2: byte;
            
            BEGIN
              ClrScr;
              Randomize;
            
              repeat
                cor1 := Random(16) + 128*Random(2);
                cor2 := Random(16);

                                        - 61 -





                TextColor(cor1);
                TextBackground(cor2);
                ch := Chr(Random(201) + 50);     (* #50 <= ch <= #250 *)
                Write(ch);
              until KEYPRESSED
            END.
            
            Exemplo: Neste  ltimo exemplo  deste captulo, vamos usar 3
            comandos da  unidade CRT  para gerar  sons com  determinadas
            freqncia e durao. So eles:
            
                 SOUND(n) ---> Emite continuamente um som de n MHz
            
                 NOSOUND  ---> Encerra a emisso do som
            
                 DELAY(t) ---> Pausa de t milisegundos
            
                 A execuo  de uma  determinada nota musical  feita da
            seguinte forma:
                 (1) Usamos o SOUND para emitir um som cuja freqncia 
            a da  nota desejada.  Para isso, devemos consultar antes uma
            tabela de freqncia de sons;
                 (2) Usamos o DELAY para determinar a durao da nota;
                 (3) Encerramos a emisso do som com o NOSOUND.
            
                 Usaremos  o  READKEY  para  verificar  qual  tecla  foi
            pressionada no  teclado e  um CASE  para emitir  um som  que
            corresponda   nota desejada.  Vamos convencionar  que o "Q"
            emite um  d, o "W" um r, ... . As teclas que no constarem
            dos alvos do CASE no emitiro sons.
                 Precisamos tambm  de um  REPEAT-UNTIL para  repetir  o
            processo de  "pressionar tecla e emitir som" at que READKEY
            retorne o caracter #27, que corresponde  tecla ESC.
            
            PROGRAM Piano;
            
            USES
              Crt;
            
            CONST
              TeclaESC = #27;
            
            VAR
              ch: char;
            
            BEGIN
              ClrScr;
              GoToXY(18, 10);
              Writeln('Toque sua musica usando as teclas QWERTYUIOP[]');
              GoToXY(18, 12);
              Writeln('Exemplo: QQWQRE QQWQTRR YYIYREW UUYRTRR');
              GoToXY(18, 14);
              Writeln('Para encerrar, pressione a tecla ESC.');
              REPEAT

                                        - 62 -





                ch := ReadKey;
                CASE ch OF
                  'Q', 'q' : Sound(262);  { d }
                  'W', 'w' : Sound(294);  { r }
                  'E', 'e' : Sound(330);  { mi  }
                  'R', 'r' : Sound(350);  { f }
                  'T', 't' : Sound(396);  { sol }
                  'Y', 'y' : Sound(440);  { l }
                  'U', 'u; : Sound(494);  { si  }
                  'I', 'i' : Sound(524);  { d }
                  'O', 'o' : Sound(558);  { r }
                  'P', 'p' : Sound(660);  { mi  }
                  '[', '{' : Sound(700);  { f }
                  ']', '}' : Sound(784);  { sol }
                END;
                DELAY(50);
            
                NOSOUND;              (* Descubra que  diferena  faz *)
              UNTIL (ch = TeclaESC)   (* se forem trocadas estas duas *)
                                      (* linhas. *)
            END.
            
            4.4. EXERCCIOS          
            
            1) Faa  um programa que calcule a soma e o produto de todos
            os nmeros pares positivos menores que 100.
            
            Observao: A  partir daqui vamos evitar usar, ficando assim
            implcitas, expresses  como "faa  um programa" ou "elabore
            um programa".  Diremos simplesmente  "Calcule... ", ao invs
            de "Elabore um programa que calcule... ".
            
            2) Calcule o somatrio S descrito em cada caso abaixo:
            
                                  3     5     7           99
                      a) S = 1 + --- + --- + --- + ... + ----
                                  2     3     4           50
            
                                  1     1     1             1
                      b) S = 1 - --- + --- - ---  + ... - -----
                                  2     3     4            100
            
            3) Calcule o valor de:
            
                            30    40
                           ----  ----
                           \     \                     1/3
                           /     /     (SEN(1/i + 1/j))
                           ----  ----
                            i=1  j=1
            
            4) a) Dado um inteiro N, mostre todos os divisores de N.
               b) Dizemos que um inteiro positivo N  perfeito quando  a

                                        - 63 -





            soma de  todos os seus divisores positivos, exceto o prprio
            N, for igual a N. Por exemplo, 6  perfeito porque
                                   1 + 2 + 3 = 6
                 Liste todos os nmeros perfeitos menores que 1000.
            
            5) O nmero 9801 tem a seguinte propriedade:
            
                                98 + 01 = 99
                                99^2    = 9801
            
                 Existem,  alm  de  9801,  dois  outros  nmeros  de  4
            algarismos que satisfazem esta propriedade. Determine-os.
            
            6)  Conte   quantos   nmeros   positivos   so   da   forma
            SEN(n/91)/COS(n/17),  onde   n     um   inteiro   tal   que
            1 <= n <= 1000.
            
            7) Elabore  um programa que leia uma linha com 4 inteiros a,
            b,   d, e interpretando-os como dois pontos do R^2 (a, b) e
            ( d) , calcule e mostre sua distncia
            
                      distncia = SQRT((a - c)^2 + (b - d)^2)
            
                 O programa dever repetir este processo de ler inteiros
            e mostrar  distncia, at  que o  usurio fornea 4 inteiros
            nulos.
            
            8) Qual  o menor  inteiro positivo que tem um fatorial maior
            do que 10 bilhes?
            
            9) Determine  um valor  para x  da forma 3 + 1/n, n inteiro,
            que satisfaa  desigualdade:
            
                 0 < | EXP(x + EXP(-x)) - EXP(3 + EXP(-3)) | < 0.001
            
            10) Uma prova com 25 questes do tipo mltipla escolha, cada
            questo com  5 alternativas A, B,  D ou E das quais apenas
            1  correta, tem como gabarito a seguinte constante string:
            
                  Gabarito_Correto := 'ACEDBCAEDABECDDACABECDEBA'
            
                 Isto significa  que na  primeira questo  a alternativa
            correta  A, na segunda   na terceira  E, etc.
                 Sendo fornecidos  vrios strings  de comprimento  25, e
            interpretando-os  como   gabaritos  de   provas  de  alunos,
            atribua uma  nota a  cada um  deles. Cada  questo acertada,
            isto , cada coincidncia entre o n-simo caracter do string
            fornecido e  o n-simo  caracter de  Gabarito_Correto,  vale
            0,4. O  ltimo string  a ser  digitado, e  que no  deve ser
            considerado no  clculo das  notas,   um string  de tamanho
            diferente de 25, como por exemplo, 'FIM'.
                 No final,  calcular a  mdia aritmtica  das notas  das
            provas.
            

                                        - 64 -
