Jump to content

Recommended Posts

Posted

Boas.

Estou a iniciar-me em programação e ando a aprender Pascal, logo ainda estou muito "verde" e com muitas dúvidas pelo que precisava que alguém me ajudasse (estou a aprender por iniciativa propria, e nao tenho aulas).

Ando a tentar criar um programa que funcionará como um cronómetro e/ou como um cronómetro inverso.

O meu problema está mesmo nos cronómetros. Como não sabia como usar tempo (em segundos) no pascal, fiz uma pesquisa na net, e após algumas experiencias resolvi usar "Delay(1000)" que provoca um atraso de 1 segundo (1000 milisegundos).

Depois começei a criar o codigo para ambos os cronómetros, mas há sempre alguma coisa que não está bem.

Já reescrevi o código duas vezes. Na primeira estava bastante extenso e no cronometro normal o tempo nao parava e no inverso (que começa a contar de determinado tempo até aos 00:00:00) só parava as vezes, outras ia para números negativos.

Depois de reescrever o codigo, ficou muito mais simplificado. Porém os problemas continuam e ainda surgiram mais alguns.

CRONOMETRO NORMAL

procedure countup;
begin
sec:=0;
min:=0;
hour:=0;
secf:=0;
minf:=0;
hourf:=0;

clrscr;
writeln;
writeln('                                  CRONOMETRO');
writeln;
writeln('                                Tempo Inicial: ');
writeln('                              Introduza as horas');
     readln(hour);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(min);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(sec);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;
writeln('                                 Tempo Final: ');
writeln('                              Introduza as horas');
     readln(hourf);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(minf);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(secf);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;writeln;
     writeln ('                              Tempo Inicial: ',hour,':',min,':',sec);
     writeln;writeln;
     writeln ('                               Tempo Final: ',hourf,':',minf,':',secf);
     repeat
           writeln;
           writeln('                   Carregue no S(start) para iniciar a contagem');
           key := readkey;
     until key = 's';
clrscr;
writeln;writeln;writeln;writeln;writeln;
writeln('                               Contagem Iniciada');

{INICIO DO CRONOMETRO}

while (sec<secf) and (min<minf) and (hour<hourf) do
begin
      while sec<60 do
      begin
            writeln;
            delay(1000);
            sec := sec+1;
            clrscr;
            writeln;writeln;writeln;writeln;
            writeln ('                                   Tempo: ',hour,':',min,':',sec);
      end;
      if min < 59 then min:=min+1
      else begin min:=0; hour:=hour+1; end;
end;

{FIM DO CRONOMETRO}

writeln;
writeln('                               Contagem Terminada');
Writeln('                            Pressione ENTER para sair.');
end;

Bugs conhecidos:

- Assim que iniciamos a contagem, esta acaba logo.

- Se em vez de

"{INICIO DO CRONOMETRO}

while (sec<secf) and (min<minf) and (hour<hourf) do"

colocarmos

"{INICIO DO CRONOMETRO}

while (sec<secf) or (min<minf) or (hour<hourf) do"

a contagem já não termina assim que começa. Porém o cronometro não para no tempo final.

- Quando termina, supostamente quando carregassemos no enter deviamos sair do programa, mas simplesmente nao acontece nada (este bug nao existia no primeiro codigo).

CRONOMETRO INVERSO

procedure countdown;
begin
clrscr;
writeln;
writeln('                              CRONOMETRO INVERSO');
writeln;
writeln('                                Tempo Inicial: ');
writeln('                              Introduza as horas');
     readln(hour);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(min);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(sec);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;writeln;
     writeln ('                              Tempo Inicial: ',hour,':',min,':',sec);
     repeat
           writeln;
           writeln('                   Carregue no S(start) para iniciar a contagem');
           key := readkey;
     until key = 's';
clrscr;
writeln;writeln;writeln;writeln;writeln;
writeln('                               Contagem Iniciada');

{INICIO DO CRONOMETRO}

while (sec>0) or (min>0) or (hour>0) do
begin
      while sec>0 do
      begin
            writeln;
            delay(1000);
            sec := sec-1;
            clrscr;
            writeln;writeln;writeln;writeln;
            writeln ('                                   Tempo: ',hour,':',min,':',sec);
      end;
      if min > 0 then min:=min-1;
end;

{FIM DO CRONOMETRO}

writeln;
writeln('                               Contagem Terminada');
Writeln('                            Pressione ENTER para sair.');
end;

Bugs conhecidos:

- O cronometro não para nos 00:00:00 quando introduzimos minutos ou horas (ex. se iniciarmos o cronometro a partir dos 00:00:10 o cronometro para nos 00:00:00, mas se iniciarmos nos 00:01:10 o cronometro nao para nos 00:00:00). Este bug já ocorria no primeiro código mas apenas quando introduziamos as horas, agora acontece com horas e minutos.

- Falta introduzir a parte em que ele subtrai 1 às horas.

- Quando termina, supostamente quando carregassemos no enter deviamos sair do programa, mas simplesmente nao acontece nada (este bug nao existia no primeiro codigo).

CÓDIGO COMPLETO

Program Cronom;
Uses crt;
var hour, min, sec, hourf, minf, secf : integer;
    key : char;


procedure countup;
begin
sec:=0;
min:=0;
hour:=0;
secf:=0;
minf:=0;
hourf:=0;

clrscr;
writeln;
writeln('                                  CRONOMETRO');
writeln;
writeln('                                Tempo Inicial: ');
writeln('                              Introduza as horas');
     readln(hour);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(min);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(sec);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;
writeln('                                 Tempo Final: ');
writeln('                              Introduza as horas');
     readln(hourf);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(minf);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(secf);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;writeln;
     writeln ('                              Tempo Inicial: ',hour,':',min,':',sec);
     writeln;writeln;
     writeln ('                               Tempo Final: ',hourf,':',minf,':',secf);
     repeat
           writeln;
           writeln('                   Carregue no S(start) para iniciar a contagem');
           key := readkey;
     until key = 's';
clrscr;
writeln;writeln;writeln;writeln;writeln;
writeln('                               Contagem Iniciada');

{INICIO DO CRONOMETRO}

while (sec<>secf) or (min<>minf) or (hour<>hourf) do
begin
      while sec<60 do
      begin
            writeln;
            delay(1000);
            sec := sec+1;
            clrscr;
            writeln;writeln;writeln;writeln;
            writeln ('                                   Tempo: ',hour,':',min,':',sec);
      end;
      if min < 59 then min:=min+1
      else begin min:=0; hour:=hour+1; end;
end;

{FIM DO CRONOMETRO}

writeln;
writeln('                               Contagem Terminada');
Writeln('                            Pressione ENTER para sair.');
end;


procedure countdown;
begin
clrscr;
writeln;
writeln('                              CRONOMETRO INVERSO');
writeln;
writeln('                                Tempo Inicial: ');
writeln('                              Introduza as horas');
     readln(hour);
     repeat
           writeln;
           writeln('                         Introduza os minutos (0 a 59)');
           readln(min);
     until (min >= 0) and (min < 60);
     repeat
           writeln;
           writeln('                         Introduza os segundos (0 a 59)');
           readln(sec);
     until (sec >= 0) and (sec < 60);

     clrscr;
     writeln;writeln;
     writeln ('                              Tempo Inicial: ',hour,':',min,':',sec);
     repeat
           writeln;
           writeln('                   Carregue no S(start) para iniciar a contagem');
           key := readkey;
     until key = 's';
clrscr;
writeln;writeln;writeln;writeln;writeln;
writeln('                               Contagem Iniciada');

{INICIO DO CRONOMETRO}

while (sec>0) or (min>0) or (hour>0) do
begin
      while sec>0 do
      begin
            writeln;
            delay(1000);
            sec := sec-1;
            clrscr;
            writeln;writeln;writeln;writeln;
            writeln ('                                   Tempo: ',hour,':',min,':',sec);
      end;
      if min > 0 then min:=min-1;
end;

{FIM DO CRONOMETRO}

writeln;
writeln('                               Contagem Terminada');
Writeln('                            Pressione ENTER para sair.');
end;


procedure about;
begin
clrscr;
writeln('');
writeln('');
writeln('                         Nome: Cronom');
writeln('                         Versao: 1');
writeln('                         Criado por: Carlos Raposo');
writeln('                         Criado em: 2006');
writeln('                         Site: http://www.crspace.net');
writeln('                         Contacto: Buttpt@gmail.com');
writeln('                         Descricao: Programa que funciona');
writeln('                         como um cronometro normal e inverso.');
repeat
writeln;writeln;
     writeln('                         ******************************* ');
     writeln('                         *      Que deseja fazer?      * ');
     writeln('                         *                             * ');
     writeln('                         *    1 - Cronometro           * ');
     writeln('                         *    2 - Cronometro Inverso   * ');
     writeln('                         *    3 - About                * ');
     writeln('                         *    4 - Sair                 * ');
     writeln('                         ******************************* ');
     key := readkey;
until (key >= '1') or (key <= '4');
repeat
     Case key of
     '1' : countup;
     '2' : countdown;
     '3' : about;
     end;
until key = '4';
end;


Procedure menu;
begin
repeat
     writeln('Cronom v.1 por Carlos Raposo');
     writeln;writeln;writeln;writeln;writeln;
     writeln('                         ******************************* ');
     writeln('                         *      Que deseja fazer?      * ');
     writeln('                         *                             * ');
     writeln('                         *    1 - Cronometro           * ');
     writeln('                         *    2 - Cronometro Inverso   * ');
     writeln('                         *    3 - About                * ');
     writeln('                         *    4 - Sair                 * ');
     writeln('                         ******************************* ');
     key := readkey;
until (key >= '1') or (key <= '4');
repeat
     Case key of
     '1' : countup;
     '2' : countdown;
     '3' : about;
     end;
until key = '4';
end;


Begin
textbackground(Blue);
     textcolor(Yellow);
     clrscr;
menu;
end.

Peço desculpa se há alguns erros óbvios ou "estúpidos", mas como já disse estou agora a iniciar-me em programação.

Quanto ao algoritmo, foi das poucas maneiras que me ocorreram para fazê-lo...deve haver uma maneira mais simples.

Desde já agradeço a vossa ajuda.

Fiquem bem

"Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV)

Posted

O problema é que estás a usar 2 whiles. Tens que verificar se o tempo já passou sempre que avances 1 segundo. Algo deste género (no que conta "para cima") :

{INICIO DO CRONOMETRO}

while (sec<>secf) or (min<>minf) or (hour<>hourf) do
begin
    writeln;
delay(1000);
sec := sec+1;
if sec = 60 then begin sec:=0; min := min+1; end;
if min = 60 then begin min:=0; hour:=hour+1; end;
clrscr;
writeln;writeln;writeln;writeln;
writeln ('                                   Tempo: ',hour,':',min,':',sec);
end;

{FIM DO CRONOMETRO}

o problema do enter é isto:

repeat
     writeln('Cronom v.1 por Carlos Raposo');
     writeln;writeln;writeln;writeln;writeln;
     writeln('                         ******************************* ');
     writeln('                         *      Que deseja fazer?      * ');
     writeln('                         *                             * ');
     writeln('                         *    1 - Cronometro           * ');
     writeln('                         *    2 - Cronometro Inverso   * ');
     writeln('                         *    3 - About                * ');
     writeln('                         *    4 - Sair                 * ');
     writeln('                         ******************************* ');
     key := readkey;
until (key >= '1') or (key <= '4');
repeat
     Case key of
     '1' : countup;
     '2' : countdown;
     '3' : about;
     end;
until key = '4';

se vires bem, o que estás a fazer é:

  1. Escrever o menu
  2. ler uma tecla
  3. regressar a 1 se a tecla não estiver entre 1 e 4
  4. verificar repetidamente se a tecla lida está entre 1 e 4.

Aquele 2º repeat é escusado, porque leste a tecla fora desse ciclo.

Por outro lado, leste de novo uma tecla para a variavel key, que ficou com 's' (quando inicia a contagem), ou seja, o ciclo repeat nao selecciona nenhuma das procedures porque key contem s, entao o programa fica ali preso para sempre. A solução é retirar o ciclo repeat, deixando só o case, e a mesma coisa na procedure about (que é código desnecessário). Devias fazer um readkey no final da about, remover o menu dessa procedure, e colocar um while true a envolver o código da procedure menu, com um break como opção 4... mas como já é tarde :🙂 vou só mostrar o código que alterei:

Procedure menu;
begin

while true do
begin
                clrscr;
	writeln('Cronom v.1 por Carlos Raposo');
	writeln;writeln;writeln;writeln;writeln;
	writeln('                         ******************************* ');
	writeln('                         *      Que deseja fazer?      * ');
	writeln('                         *                             * ');
	writeln('                         *    1 - Cronometro           * ');
	writeln('                         *    2 - Cronometro Inverso   * ');
	writeln('                         *    3 - About                * ');
	writeln('                         *    4 - Sair                 * ');
	writeln('                         ******************************* ');
	repeat		key := readkey;
	until (key >= '1') and (key <= '4');

	case key of
		'1' : countup;
		'2' : countdown;
		'3' : about;
		'4' : break;
	end;
end;

end;

Também alterei ali o until (key >= '1') and (key <= '4'); porque tinhas um or, e isso tornava a condição SEMPRE válida.

procedure about;
begin
clrscr;
writeln('');
writeln('');
writeln('                         Nome: Cronom');
writeln('                         Versao: 1');
writeln('                         Criado por: Carlos Raposo');
writeln('                         Criado em: 2006');
writeln('                         Site: http://www.crspace.net');
writeln('                         Contacto: Buttpt@gmail.com');
writeln('                         Descricao: Programa que funciona');
writeln('                         como um cronometro normal e inverso.');
readkey;
end;

...e um readkey por baixo das mensagens "Presisione Enter para sair" 🙂 Penso que não fiz mais alteraações, por isso deve funcionar assm.

Desaparecido.

Posted

Primeiro que tudo muito obrigado por teres respondido 🙂

Funcionou tudo o que disseste mas só não percebi umas coisitas...

Podias me explicar o "while true do" e o "break"? Em que condições podemos usar o break (ja experimentei usar mas deu erro e disse que o break nao era permitido)? Não tinha conhecimento disso...

E também não percebi como fizeste para quando carregamos no enter voltarmos ao menu...é que dantes saía do programa.

Mais uma vez obrigado por teres respondido 🙂

"Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV)

Posted

o "while true do" é o chamado ciclo infinito. Ou seja, o programa repete o ciclo para sempre, a menos que encontre uma instrução break no código que está no seu interior; neste caso, quando pressionas a tecla 4 no menu, o programa vai para o case onde encontra um break, e sai do ciclo while.

É essa a função da instruçao break: quebrar um ciclo de repetição, seja ele for, while ou repeat. Assim sendo, a instrução break só pode ser utilizada dentro de um destes ciclos. Quando o programa encontra um break, salta para a instrução logo a seguir ao ciclo. Exemplo:

	while true do
	begin
		key := readkey;
		case key of
			'1' : opcao1;
			'2' : opcao2;
			'3' : opcao;
			'4' : break;
			else continue;
		end;
	end;
	uma_instrucao;

faz com que o programa fique à espera de uma tecla. Se a tecla for de 1 a 3, chama um procedimento correspondente; se a tecla for 4, quebra o ciclo while e vai executar a instrução uma_instrucao; se for outra tecla qualquer, volta ao inicio do ciclo while e fica à espera de uma nova tecla (é para isso que serve o continue, voltar ao inicio do ciclo numa nova iteração).

O meu Pascal está um bocado enferrujado, e não testei esse código, por isso não me cricifiquem se não funcionar :🙂

Desaparecido.

Posted

Ok agora ja percebi tudo e já consegui por a funcionar.

O teu pascal está optimo 🙂

Um muito obrigado pela ajuda. thx

Fica bem

"Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV)

Posted

Não li isto há bocado :🙂 Não sei se já entendeste, mas vou explicar na mesma, não se perde nada 🙂

Em 02/05/2006 às 15:04, Buttpt disse:
E também não percebi como fizeste para quando carregamos no enter voltarmos ao menu...é que dantes saía do programa.

O programa volta sempre ao menu porque o procedimento menu contém um ciclo (o tal while infinito):

Procedure menu;
begin

while true do
begin
                clrscr;
	writeln('Cronom v.1 por Carlos Raposo');
	writeln;writeln;writeln;writeln;writeln;
	writeln('                         ******************************* ');
	writeln('                         *      Que deseja fazer?      * ');
	writeln('                         *                             * ');
	writeln('                         *    1 - Cronometro           * ');
	writeln('                         *    2 - Cronometro Inverso   * ');
	writeln('                         *    3 - About                * ');
	writeln('                         *    4 - Sair                 * ');
	writeln('                         ******************************* ');
	repeat		key := readkey;
	until (key >= '1') and (key <= '4');

	case key of
		'1' : countup;
		'2' : countdown;
		'3' : about;
		'4' : break;
	end;
end;

end;

O que é que acontece quando chamamos o menu?

  1. Desenha o menu;
  2. Fica à espera de uma tecla, até que essa tecla esteja entre 1 e 4;
  3. Entra no case com a certeza que a tecla lida está entre 1 e 4 (caso contrário não tinha saído do repeat anterior);
  4. conforme a tecla, entra no procedimento correcto;
  5. quando retorna do procedimento, volta ao inicio do while infinito, desenha o menu, etc (a menos que tenha sido pressionada a tecla 4, que corresponde ao break, e nesse caso sai do while e do programa).

Mais alguma dúvida, é só perguntar que alguém há de responder 🙂

Ainda bem que pude ajudar 🙂

Desaparecido.

Posted

ya eu calculei que voltassemos sempre ao menu porque era um ciclo infinito.

Mas obrigado na mesma...assim ficou mais esclarecido 🙂

Já agora deixo aqui o código do cronómetro inverso (código baseado no fornecido pelo TheDark) para o caso de haver alguem com a mesma dúvida:

{INICIO DO CRONOMETRO}

repeat
    writeln;
delay(1000);
sec := sec-1;
if sec = -1 then begin sec:=59; min := min-1; end;
if min = -1 then begin min:=59; hour:=hour-1; end;
clrscr;
writeln;writeln;writeln;writeln;
writeln ('                                   Tempo: ',hour,':',min,':',sec);
until (sec=0) and (min=0) and (hour=0);

{FIM DO CRONOMETRO}

"Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.