Introdução à Computação
Aula prática 6 - Respostas



1 e 2 . Estatísticas simples utilizando procedimentos com variáveis globais.
program calculosm;
          {----programa que calcula estatisticas num ciclo ----}
uses crt;

var
num, total, numeros, maior, menor, pares, impares: integer;
{----------------------------------------------------------------------}
procedure inicializacao;
begin
   total:= 0; pares:= 0; impares:= 0;
   maior:= -9999; menor:= 9999;
   writeln('Este programa vai calcular valores num ciclo até input=-999');
end;
{-------------------------------------------------------------------}
procedure ler_dados;
begin
   writeln('Entrar um número: '); readln(num);
end;
{-------------------------------------------------------------------}
procedure maior_menor;
begin
     if (num < menor) then
        menor:= num;
     if (num > maior) then
        maior:= num;
end;
{-----------------------------------------------------------------}
procedure media;
begin
   writeln('M‚dia dos números introduzidos: ', total / numeros:0:2);
end;
{----------------------------------------------------------------}
procedure par_impar;
begin
     if ((num mod 2) = 0) then
         pares:= pares + 1
     else
         impares:= impares + 1;
end;
{-----------------------------------------------------------------}
procedure total_numeros;
begin
        total:= total + num;
end;
{-----------------------------------------------------------------}
procedure estatisticas;
begin
   writeln(' Estatisticas ');
   writeln(' ------------ ');
   writeln('Total de números introduzidos: ', numeros);
   writeln('Números pares: ',  pares);
   writeln('Número impares: ', impares);
   writeln('Número menor: ',   menor);
   writeln('Número maior: ',   maior);
   media;
   readln;
end;
{-----------------------------------------------------------------}
begin       {secção principal do programa }

clrscr;
inicializacao;
ler_dados;

while (num <> -999) do       {ciclo do programa }
   begin
        numeros:= numeros + 1;
        total_numeros;
        maior_menor;
        par_impar;
        ler_dados;
     end;
     estatisticas;    {mostrar resultados }
end.

3.
PROGRAM Calculadora;
uses crt;

var op1, op2, c: real;
    opcao: integer;
{-------------------------------------}
PROCEDURE Somar; 
begin 
  c := op1 + op2;
  WriteLn(' ', op1:0:2 , ' + ', op2:0:2 , ' = ',c:0:2);
end;
{------------------------------------------------------------}
PROCEDURE Dividir;
begin
  c := op1 / op2;
  WriteLn(' ', op1:0:2 ,' / ', op2:0:2 , ' = ',c:0:2);
end;
{------------------------------------------------------------}
PROCEDURE Multiplicar;
begin
  c := op1 * op2;
  WriteLn( ' ', op1:0:2 , ' * ', op2:0:2 , ' = ',c:0:2);
end;
{------------------------------------------------------------}
PROCEDURE Subtrair;
begin
  c := op1 - op2;
  WriteLn(' ', op1:0:2 , ' - ', op2:0:2 , ' = ',c:0:2);
end;
{------------------------------------------------------------------------}
FUNCTION graus_radians(angulo: real): real;
         {funcao que devolve o valor em radians dum angulo em graus }
begin
     graus_radians:= (angulo * PI) / 180;
end;
{-------------------------------------------------------------------------}
PROCEDURE seno(angulo: real); {funcao trabalho com radians e nao graus}
var r : real;
begin
    r:= graus_radians(angulo); {chama funcao que converte graus em radianes}
    writeln('Seno de ',angulo:0:2, ' = ', sin(r):0:4);
end;
{-------------------------------------------------------------------------}
PROCEDURE coseno(angulo: real); {funcao trabalha com radians }
var r : real;
begin
   r:= graus_radians(angulo);
   writeln('coseno de ',angulo:0:2, ' = ', cos(r):0:4);
end;
{-----------------------------------------------------------------------}
PROCEDURE valor_absoluto( valor: real);
begin
    writeln('Valor absoluto de ',valor:0:2, ' = ', (abs(valor)):0:2);
end;
{---------------------------------------------------------------------}
PROCEDURE raiz_quadrada(valor: real);
begin
    writeln('Raiz quadrada de ', valor:0:2, ' = ',sqrt(valor):0:2);
end;
{---------------------------------------------------------------------}
PROCEDURE ler_operandos;
var OK :char;
begin
   OK:= 'x';
   repeat
       if (opcao < 5) then
           begin
              Write('favor entrar operando 1: ');    readln(op1);
              Write('favor entrar operando 2: ');    readln(op2);
           end
       else
           begin
              write('Favor entrar valor a converter: '); readln(op1);
           end;
       write(' Esta seguro(a) dos seus operandos? '); readln(OK);
   until ((OK = 's') or (OK = 'S'));
end;


end;
{--------------------------------------------------------------------}
begin              { programa principal }
{--------------------------------------------------------------------}
  Repeat
    clrscr;
    WriteLn('            Escolhe uma opcao:');
    WriteLn('(1) adicionar             (2) multiplicar');
    WriteLn('(3) dividir               (4) subtrair');
    WriteLn('(5) valor absoluto        (6) raiz quadrada');
    WriteLn('(7) seno dum angulo       (8) coseno dum angulo');
    Writeln('(0) sair');
    write('              Qual ‚ a sua op‡Æo?: ');
    ReadLn(opcao);
    if (opcao <> 0) then
      begin
        ler_operandos;
        Case opcao of
              1: Somar;
              2: Multiplicar;
              3: Dividir;
              4: Subtrair;
              5: valor_absoluto(op1);
              6: raiz_quadrada(op1);
              7: seno(op1);
              8: coseno(op1);
        else
              writeln('Erro no input. Repeta s.f.f.');
        end;
      readln;
      end;
  until (opcao = 0);

  WriteLn('Obrigado e bom dia');
  readln;
end.

4. Números primos: são aqueles divisíveis por 1 e por eles próprios.
 Um numero é divisível pelo outro número se o resto da divisão é zero. (Na aula teórica 7 foram explicados os operadores para divisões, Div e Mod.) Um número n é primo se não for divisível por todos os números entre 2 e  (n-1). Com estes duas ideas vamos resolver o problema. Sabemos exactamento quantas vezes temos de executar o ciclo: Então, utilizamos o ciclo For.

PROGRAM DeterminePrimo;
Var i, n: integer;
    primo: boolean;
begin
  Write('numero: ');
  ReadLn(n);
  primo := TRUE;
  For i := 2 To n-1 Do
       if (n Mod i) = 0 then  (* a Mod b = 0 significa que a variavel a e divisivel pela variavel b *)
       primo := FALSE;
      (* fim do ciclo For *)
  if  (primo) then
       WriteLn(n, ' e primo')
  else
    WriteLn(n, ' nao e primo');
end.
 Para os especialistas: Existem algorítmos muito mais inteligentes para determinar se um número é primo. O programa acima é o mais simples. É relativamente fácil melhorar a eficiência do algoritmo: se encontramos uma vez que o resultado do (n Mod i)=0, não precisamos de continuar com o ciclo até verificar todos os números entre 0 e (n-1) Não é ?. Imagine vamos determinar se o número 10000 é primo. Só calculando 10000 Mod 2 sabemos que o número não é primo e podemos acabar com os cálculos. Vamos implementar esta idea.
Temos duas condições para sair do ciclo
  1) chegamos ao fim com os números (i = (n-1)) ou
  2) encontrámos um resultado do Mod que deu 0. Vamos combinar estas duas condições e temos de usar um outro tipo do ciclo (com ciclos For não é possivel combinar condições):
PROGRAM MelhorPrimo;
Var i, n: integer;     primo: boolean;
begin
Write('numero: ');   ReadLn(n);
primo := TRUE;   i := 2;

While ((i <= (n-1)) AND (primo = TRUE)) Do
    begin
        if  (n Mod i) = 0 then
            primo := FALSE;
        i := i + 1;     end;
        if (primo) then
            WriteLn(n, ' e primo')
       else
           WriteLn(n, ' nao e primo');
     end;
end.

A notar que na condição " if (primo) ...", em vez de primo=TRUE podemos escrever só primo, porque esta já uma variável do tipo boleana. Assim o código acima fica mais legível.

4a. Agora vamos por tudo num (outro) ciclo for:
PROGRAM DeterminePrimo;
Var i, n: integer;
    primo: boolean;
begin
  WriteLn('Numeros primos ate 10000:');
  for n := 3 to 10000 do
    begin
      primo := TRUE;
      for i := 2 to n-1 do
        if (n Mod i) = 0 then
          primo := FALSE;
      (* aqui acaba o ciclo For i *)
      if primo then
        Write(n,'   ');
    (* aqui acaba o ciclo For n *)
    end;
end.


5. Enquanto a soma total duma série de números introduzidos pelo utilizador(a) não seja superior a 1000, continue a executar um programa que adiciona os números introduzidos pelo utilizador, e que mostra no ecrã o valor da adição parcial deles.
program chegar_1000;
uses crt;

var
total, num: real;
n : integer;
begin
   clrscr;
   total:= 0; n:= 0;
   write('entrar um numero s.f.f: '); readln(num);
   if (num > 1000) then
      begin
         total:= num;   {situacao especial para primeira vez, caso o primeiro número > 1000 }
         n:= 1;
      end
   else
   repeat                    {também podia ser implementado com o ciclo while ...do }
        total:= total + num;
        if (total <= 1000) then
            begin
                n:= n + 1;
                writeln('---- Total parcial: ', total:0:2);
                if (total < 1000) then
                   begin
                      write('numero: '); readln(num);
                   end;
            end;
   until (total >= 1000);

   writeln('Chegamos ao numero ', total:0:2);
   writeln('Numero de valores introduzidos: ', n);
   readln;
end.