Jump to content
thoga31

Introdução ao Pascal

Recommended Posts

thoga31

Introdução ao Pascal – Parte 2

(1ª parte)

(3ª Parte)

Após tanto tempo de ter lançado um tutorial básico sobre Pascal, chega a altura de começar a pôr em prática os conhecimentos adquiridos anteriormente.

Nesta continuação será dada ênfase à parte prática da programação em Pascal. Serão colocados igualmente Propostas de Exercícios.

Esta parte do tutorial não terá constantes explicações dos códigos para poder exercitar a leitura lógica de um programa em Pascal. Contudo, qualquer dúvida deverá ser colocada, pois não quero ninguém com dúvidas.

Qualquer erro neste tutorial, por exemplo em programas com erros ao executar ou ao compilar, por favor avisem-me para poder ser corrigido.

Índice

1. Hello World!

2. A primeira calculadora – uso do If… Then… Else…

3. Avaliações 1 – uso do Case… Of…

4. Avaliações 2 – uso do Repeat… Until…

5. Ordenação crescente de uma lista – uso do ciclo For… To… Do…

6. Contagem de espaços e palavras numa frase – uso de string

7. Cálculo da tangente – uso de uma função

1. Hello World!

Como em qualquer linguagem, onde se começa regra geral com o famoso “Olá Mundo!”, vamo-lo realizar em Pascal.

Primeiramente, há que saber que, neste programa, apenas será escrita uma mensagem, pelo que bibliotecas não são necessárias. Esta parte é, então, omitida nas declarações iniciais:

program hello_world;  // Declara-se o programa, no geral.
// bibliotecas não são necessárias
// não são necessárias variáveis

begin
     writeln('Hello World!');  // escreve o texto “Hello World!”
     readln;  // sem isto, o programa é encerrado repentinamente: é necessário pressionar ENTER.
end.

Vamos, então, “embelezar” o programa, onde já vamos pedir nome do utilizador e dar uma mensagem final.

program hello_world;  // Declara-se o programa, no geral.
uses crt;  // dependendo do IDE/compilador, este biblioteca será necessária ou não neste exemplo
var nome:string;

begin
     write('Introduza o seu nome: ');  // escreve o texto, e o cursor fica à frente deste, pois falta o sufixo LN (LiNe)
     readln(nome);
     writeln;  // faz mais um parágrafo sem escrever texto
     writeln('Hello World!');
     writeln('Seja bem-vindo, Sr.(a) ',nome);  // escreve o texto, seguido do conteúdo da variável NOME
     readln;
end.

2. A primeira calculadora – uso do If… Then… Else…

Vamos criar a nossa primeira calculadora. O utilizador não vai escolher o operador. Simplesmente o utilizador introduz os dois valores e aparecem os resultados das quatro operações básicas.

Necessitaremos de uma condição If… Then… Else… por causa da divisão. Se o denominador for 0 (zero), o programa, ao tentar fazer a conta, irá abaixo: a condição vai evitar este bug.

program primeira_calculadora;
uses crt;
var num1,num2:real;

Ou seja, vamos utilizar duas variáveis reais que alojarão os dois valores necessários.

program primeira_calculadora;
uses crt;
var num1,num2:real;

begin
     writeln('CALCULADORA SIMPLES');
     write('Primeiro valor: ');
     readln(num1);
     write('Segundo valor: ');
     readln(num2);
end.

Neste momento, o utilizador é convidado a introduzir os dois valores que farão parte das quatro operações.

Resta-nos, então, realizar os cálculos e mostrá-los ao utilizador:

program primeira_calculadora;
uses crt;
var num1,num2:real;

begin
     writeln('CALCULADORA SIMPLES');
     write('Primeiro valor: ');
     readln(num1);
     write('Segundo valor: ');
     readln(num2);
     writeln;
     writeln(num1:0:3,' + ',num2:0:3,' = ',num1+num2:0:3);
     {a cláusula “:0:3” dá duas indicações: ocupar o espaço mínimo de 0 caracteres, arredondando o número a 3 casas decimais}
     writeln(num1:0:3,' - ',num2:0:3,' = ',num1-num2:0:3);
     writeln(num1:0:3,' * ',num2:0:3,' = ',num1*num2:0:3);
end.

Contudo, chega a altura de antever a situação de num2 = 0 por causa da divisão.

Criaremos, então, a condição à parte.

write(num1:0:3,' / ',num2:0:3,' = ');
if (num2 = 0) then begin  // SE num2=0 ENTÃO
   write('Infinito');  // escrever “INFINITO”
end
else begin  // SE NÃO
     writeln(num1/num2:0:3);  // escrever resultado
end;

Vamos incluir isto no código do programa:

program primeira_calculadora;
uses crt;
var num1,num2:real;

begin
     writeln('CALCULADORA SIMPLES');
     write('Primeiro valor: ');
     readln(num1);
     write('Segundo valor: ');
     readln(num2);
     writeln;
     writeln(num1:0:3,' + ',num2:0:3,' = ',num1+num2:0:3);
     {a cláusula “:0:3” dá duas indicações: ocupar o espaço mínimo de 0 caracteres, arredondando o número a 3 casas decimais}
     writeln(num1:0:3,' - ',num2:0:3,' = ',num1-num2:0:3);
     writeln(num1:0:3,' * ',num2:0:3,' = ',num1*num2:0:3);
     write(num1:0:3,' / ',num2:0:3,' = ');
     if (num2 = 0) then begin  // SE num2=0 ENTÃO
        writeln('Infinito');  // escrever “INFINITO”
     end
     else begin  // SE NÃO
          writeln(num1/num2:0:3);  // escrever resultado
     end;
     readln;  // esperar pelo ENTER
end.

3. Avaliações 1 – uso do Case… Of…

Consideremos uma escala de avaliações, numa escola, de 0 a 20 (de zero a vinte) valores. Consideremos a negativa uma avaliação abaixo de 10 e a positiva acima deste valor, inclusive. Utilizaremos apenas e tão-somente, neste exemplo, avaliações inteiras (números inteiros).

program avaliacoes;
uses crt;
var nota : integer;

begin
     write('Escreva a avaliacao, inteira, de 0 a 20: ');
     readln(nota);
     case nota of
          // falta a selecção de casos
     end else writeln('Nota invalida');
     readln;
end.

Para seleccionarmos os casos, podemos utilizar a noção de intervalo, existente no Pascal. Evitamos escrever o caso de ser 0, de ser 1, 2, 3 e por aí adiante. Se quisermos que o caso de a avaliação ser “FRACO” seja no intervalo de 0 a 3, inclusive, podemos escrever este intervalo assim: 0..3

Então, façamos a selecção de casos no nosso programa:

program avaliacoes;
uses crt;
var nota : integer;

begin
     write('Escreva a avaliacao, inteira, de 0 a 20: ');
     readln(nota);
     case nota of
          0..3 : writeln('Fraco');
          4..9 : writeln('Insuficiente');
          10..12 : writeln('Pouco Suficiente');
          13..15 : writeln('Suficiente');
          16..18 : writeln('Bom');
          19..20 : writeln('Excelente');
     end else writeln('Nota invalida');
     readln;
end.

4. Avaliações 2 – uso do Repeat… Until…

Vamos pegar no programa anterior e acrescentar-lhe dois ciclos Repeat… Until…. Um para analisar a nota assim que é introduzida, e outro para controlar o fecho do programa: caso o utilizador escreva “1” o programa volta a pedir uma avaliação, caso contrário fecha o programa.

A estrutura para analisar a introdução da avaliação terá de ser a seguinte:

repeat
      write('Escreva a avaliacao, inteira, de 0 a 20: ');
      readln(nota);
until (nota>=0) and (nota<=20);

Podemos ainda avisar o utilizador caso falhe a introdução da avaliação com uma estrutura de decisão:

repeat
      write('Escreva a avaliacao, inteira, de 0 a 20: ');
      readln(nota);
      if not ((nota>=0) and (nota<=20)) then begin
         writeln('Erro! Nao esta no intervalo 0 a 20!');
         writeln;
      end;
until (nota>=0) and (nota<=20);

Para controlar o fecho do programa, necessitamos de uma variável de controlo, à qual chamaremos fecho e será do tipo integer.

repeat
      // programa todo
      write('“1” para reiniciar, outro número para sair: ');
      readln(fecho);
until (fecho<>1);

Implementemos agora estas duas estruturas no programa:

program avaliacoes;
uses crt;
var nota, fecho : integer;

begin
     repeat
           repeat
                 write('Escreva a avaliacao, inteira, de 0 a 20: ');
                 readln(nota);
                 if not ((nota>=0) and (nota<=20)) then begin
                   writeln('Erro! Nao esta no intervalo 0 a 20!');
                   writeln;
                 end;
           until (nota>=0) and (nota<=20);
           case nota of
                0..3 : writeln('Fraco');
                4..9 : writeln('Insuficiente');
                10..12 : writeln('Pouco Suficiente');
                13..15 : writeln('Suficiente');
                16..18 : writeln('Bom');
                19..20 : writeln('Excelente');
           end else writeln('Nota invalida');
           writeln;
           write('“1” para reiniciar, outro número para sair: ');
           readln(fecho);
     until (fecho<>1);
end.


Propostas de Exercícios

1. Crie a sua própria calculadora. Contudo, o utilizador terá de escolher a operação a realizar e, no caso de esta ser a divisão, o programa terá de impedir o utilizador de introduzir denominador 0 (zero), obrigando-o a introduzir outro valor para tornar a divisão possível. Mostre uma mensagem de erro neste caso.

As variáveis para os valores das operações a realizar terão de ser reais, e a que selecciona a operação deverá ser uma string.

Mostre ao utilizador o maior número de informações possíveis sobre a calculadora. Mas não sobre o que o programa está a processar no momento, como “A realizar a soma”.

Normas:

  • Limite máximo de linhas de código (exclusive comentários e linhas em branco): 40 linhas.


5. Ordenação crescente de uma lista – uso do ciclo For… To… Do…

Vamos pedir ao utilizador para criar uma lista de dez números inteiros, e de seguida vamos mostrar a lista por ordem crescente.

Comecemos por definir as variáveis necessárias:

program crescente;
var lista : array [1..10] of integer;  // lista de 10 inteiros
    i, j : integer;  // dois contadores para os ciclos FOR

begin

end.

Façamos o programa por partes.

Comecemos por pedir os 10 valores da lista ao utilizador:

     writeln('INTRODUZA OS 10 VALORES DA LISTA:');
     for i:=1 to 10 do begin
         write('Valor nº', i, ': ');
         readln(lista[i]);
     end;

Agora, começa a parte complicada deste exercício. Para ordenar a lista pode-se utilizar o seguinte método.

Pegamos no primeiro valor e analisamos com todos os restantes valores da lista. Caso encontre um menor que este, trocam-se directamente. De seguida, analisa o segundo valor, e compara-o com os seguintes, mas NÃO com os anteriores (neste caso, o primeiro). O processo repete-se até ao último valor da lista.

Exemplo:

Lista: 7 » 9 » 5 » 2

Processo:

1. “Pega” no primeiro valor da lista e compara:

9 < 7 – falso:  7 » 9 » 5 » 2

5 < 7 – verdade:  5 » 9 » 7 » 2

Agora o primeiro valor é o 5, e a análise continua:

2 < 5 – verdade:  2 » 9 » 7 » 5

Como se verifica, o número mais baixo da lista ficou em primeiro lugar.

2. Compara com o segundo valor da lista:

7 < 9 – verdade:  2 » 7 » 9 » 5

Agora o segundo valor é o 7.

5 < 7 – verdade:  2 » 5 » 9 » 7

3. Agora, com o terceiro valor:

7 < 9 – verdade:  2 » 5 » 7 » 9

E terminou aqui a análise. Como se verifica, este processo coloca a lista toda por ordem crescente.

Em código, necessitar-se-á de uma variável auxiliar para realizar a troca, chamada aux:

     for i:=1 to 10 do begin
         for j:=i to 10 do begin
             if (lista[j]<lista[i]) then begin
                aux:=lista[j];
                lista[j]:=lista[i];
                lista[i]:=aux;
             end;
         end;
     end;

Só nos resta mostrar a lista por ordem crescente obtida:

     write('Lista por ordem crescente: ');
     for i:=1 to 10 do begin
         write(lista[i],'; ');
     end;

Implementemos estas partes no programa final:

program crescente;
var lista : array [1..10] of integer;  // lista de 10 inteiros
    i, j : integer;  // dois contadores para os ciclos FOR
    aux : integer;  // auxiliar para troca de valores em lista

begin
     writeln('INTRODUZA OS 10 VALORES DA LISTA:');
     for i:=1 to 10 do begin  // lê a lista
         write('Valor nº', i, ': ');
         readln(lista[i]);
     end;

     for i:=1 to 10 do begin  // coloca a lista por ordem crescente
         for j:=i to 10 do begin
             if (lista[j]<lista[i]) then begin
                aux:=lista[j];
                lista[j]:=lista[i];
                lista[i]:=aux;
             end;
         end;
     end;

     write('Lista por ordem crescente: ');
     for i:=1 to 10 do begin  // mostra a lista, agora ordenada
         write(lista[i],'; ');
     end;
     writeln;
     write('ENTER para sair. . .');
     readln;
end.


Propostas de Exercícios

2. Crie um contador de avaliações positivas de uma turma.

O utilizador deverá introduzir o número de alunos que a turma tem, e de seguida o programa pedirá a avaliação de cada aluno. Para tal, o programa deverá ter um controlo da avaliação introduzida, para que esta esteja dentro de intervalo 0 a 20 valores. No final, o programa irá devolver quantas avaliações positivas existem, apresentando a percentagem, arredondada às décimas.

Normas:

  • O programa não deverá ter mais do que um ciclo for;
  • Limite máximo de linhas de código (exclusive comentários e linhas em branco): 20 linhas.

3. Crie um programa que debite o maior de todos os n valores introduzidos pelo utilizador, sendo os n números a introduzir definidos pelo utilizador. O limite mínimo é 5 e o máximo é 50.

Normas:

  • O programa não deverá ter nenhum ciclo for;
  • Limite máximo de linhas de código (exclusive comentários e linhas em branco): 25 linhas.


6. Contagem de espaços e palavras numa frase – uso de string

Vamos agora criar um programa que conte o número de espaços que se encontra numa frase.

Pede-se ao utilizador para escrever uma frase, e o programa dirá o número de espaços e de palavras que encontrou.

Primeiro, o contador de espaços:

program contador;
uses crt;
var frase : string;
    i, contaespacos, contapalavras : integer;

begin
     write('Introduza uma frase a sua escolha: ');
     readln(frase);
     for i:=1 to length(frase) do begin  // contador de espaços
         if (frase[i]=' ') then contaespacos:=contaespacos+1;
     end;
end.

Ora, uma palavra está entre espaços, e esta é a base para a análise de palavras neste programa:

program contador;
uses crt;
var frase : string;
    i, contaespacos, contapalavras : integer;

begin
     write('Introduza uma frase a sua escolha: ');
     readln(frase);

     contaespacos:=0;
     for i:=1 to length(frase) do begin  // contador de espaços
         if (frase[i]=' ') then contaespacos:=contaespacos+1;
     end;

     contapalavras:=0;
     if (frase[1]=' ') and (frase[2]<>' ') then contapalavras:=1;
     // Poderá haver um espaço a começar a string "frase". Este código prevê esta situação.
     if frase[1]<>' ' then contapalavras:=1;
     // verifica igualmente se o primeiro caracter NÃO é um espaço, contando então uma palavra.
     for i:=2 to length(s) do begin  // análise da restante string, já com a existência da primeira palavra prevista
         if (frase[i]=' ') and (upcase(s[i+1]) in ['A'..'Z']) then contapalavras:=contapalavras+1;
         {se o actual caracter da frase é um espaço e o próximo é uma letra, então acabou a palavra – soma 1 ao contador}
     end;

     writeln('A frase contem ',contapalavras,' palavras, assim como ',contaespacos,' espacos');
     readln;
end.


Propostas de Exercícios

4. Crie um programa que elimine os espaços a mais.

O utilizador introduz uma frase à sua escolha, e o programa irá eliminar os espaços a mais, reduzindo-os a um só, entre cada palavra.

Normas:

  • Terá de utilizar somente ciclos for;
  • Limite máximo de linhas de código (exclusive comentários e linhas em branco): 30 linhas.


7. Cálculo da tangente – uso de uma função

Vamos criar uma função que calcule a tangente de um número (ângulo), já que o Pascal não tem uma.

Ter-se-á de ter em atenção que cos(a) não pode ser 0 (zero), pois:

tg(a) = sen(a) / cos(a)

Nesse caso, o programa dirá que a tangente não é possível. Para saber se é possível, criaremos outra função que nos diz tal.

Vejamos:

program tangente;
uses crt;
var a : real;

function tan(angulo:real):real;  // tangent = seno / co-seno
begin
     tan:=sin(angulo)/cos(angulo);
end;

function tangente_possivel(angulo:real):boolean;  // a tangente é possível se o co-seno for diferente de zero
begin
     if (cos(angulo)=0) then tangent_possivel:=false
     else tangent_possivel:=true;
end;

begin
     write('Introduza angulo, em radianos: ');
     readln(a);
     if tangente_possivel then writeln('Tangente de ',a:0:10,': ',tan(a):0:10)
     else writeln('Tangente de ',a:0:10,': infinito');
     readln;
end.


Propostas de Exercícios

5. Crie um programa que calcule o factorial de um número. O programa deverá analisar se o valor introduzido é inteiro ou não, e se é positivo, ou seja, a variável que lê o número é real. Deverá prever a situação especial do factorial de zero.

Normas:

  • Terá de utilizar uma função para cálculo do factorial;
  • Limite máximo de linhas de código (exclusive comentários e linhas em branco): 30 linhas.


(1ª parte)

(3ª Parte)


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Partes seguintes

Aceito sugestões sobre o que devo escrever nos seguintes tutoriais. :(

Este é o tutorial de todos, e não só meu.

A minha proposta baseia-se no seguinte:

  • Códigos para trabalhar com string
  • Data e hora
  • Coloração de texto e fundo
  • Exemplos de programas mais complexos

Aceito igualmente Propostas de Exercícios, por PM, para colocar nas próximas partes, explicitando normas e o que é que cada exercício se propõe a treinar (por exemplo: uso de estruturas de repetição).

Os exercícios, quando colocados em novas partes do tutorial, terão o nome do seu autor (nick no P@P e, se pretender, o seu nome próprio) devidamente identificado. Por exemplo:

3. Crie a sua própria calculadora (...)

Exercício criado por: thoga31.

Espero a vossa participação. ;)

Obrigado.

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Parte 3

Devido ao repentino "esticar" de tempo livre, já consegui terminar a 3ª parte deste tutorial, e já tenho a 4ª parte a ser preparada.

Desta vez, a 3º parte do tutorial trará para vós, entre outros:

  • Princípios em optimização
  • Operações numéricas
  • Utilização mais aprofundada de funções
  • Coloração de texto e fundo

São, novamente, 7 capítulos, incluindo um programa completo, 2 Propostas de Exercícios e 4 Desafios.

Contudo, espero, antes, opiniões sobre a 2ª parte, antes de "descarregar" mais 2000 palavras... :(

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

People?? :P

I'm feeling alone, here!

Espero sugestões vossas, propostas vossas! A época da abstenção já lá vai, que isto não são as Eleições!


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

thoga31,

Já sabes que o pessoal da parte do Pascal não costuma ser muito activo neste fórum :)

De qualquer das formas, estive a ler a tua segunda parte e acho que agora está na altura de partires para algo mais complexo.

A tua primeira parte fez uma extensa introdução à linguagem e a segunda complementou-a com exercícios para os utilizadores aplicarem os novos conhecimentos.

Sei que provavelmente esperavas uma crítica mais aprofundada a este teu segundo post, mas realmente, se pensarmos bem, não há muito a dizer pois são essencialmente exercícios. O primeiro post era mais discutível porque falava dos fundamentos da linguagem ;)

Há no entanto exercícios que gostaria de ver aqui... Nada de muito específico, mas seria engraçado ver alguma coisa que envolvesse leitura e escrita de/para ficheiros; outro tema interessante seriam as excepções, e no final, um pouco de Programação Orientada a Objectos.

Ah! Antes de falares na POO, e até mesmo no contexto de leitura/escrita de ficheiros, podes fazer um desvio pelos Records, um tipo de dados composto essencial a qualquer programa mais complexo :)

E no fim de tudo, pointers :P

De resto, já sabes, estás de parabéns pelo esforço e intenção destes tutoriais.

Dá gosto ver ;)

Share this post


Link to post
Share on other sites
thoga31

Obrigado, pedro!

Pelo contrário, são opiniões simples as que mais gosto! :P

Vou lançar a 3ª parte, e vou escrever na 4ª parte, então, a utilização de variáveis Record e Text.

Pascal não suporta POO, excepto, possivelmente, alguma nova "versão" da qual não tenha conhecimento.

Ainda não estudei excepções em Pascal, mas pergunto-me: existe um bloco parecido ao Try Catch do VB, por exemplo?

E obrigado, mais uma vez, pela tua disponibilidade em responder! :P


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Introdução ao Pascal – Parte 3

(2ª Parte)

(4ª parte)

Desta vez, após uma introdução básica e uma parte essencialmente prática e de desenvolvimento da leitura lógica de um programa em Pascal, é altura de continuar com uma nova parte novamente teórica, mas com Desafios e Propostas de Exercícios.

Os Desafios pretendem ser exercícios mais complexos que levam o “aprendiz” a pensar mais para poder chegar à conclusão.

Nesta parte do tutorial, dar-se-á ênfase à utilização de operadores para realização de cálculos, recorrendo sempre que possível a procedimentos e funções para que estes sejam treinados e seja entendida a sua importância na estruturação de um bom programa.

Esta parte também começará a dar ênfase às boas práticas no acto da programação para a fácil leitura e interpretação de um programa Pascal.

Começar-se-á igualmente com Optimização, nível básico, e com comandos de coloração e de string.

Índice

1. Operações numéricas gerais

2. Optimização básica

3. Facilitação da leitura de um programa

4. A fórmula resolvente – programa completo – uso de funções

5. Conversão de variáveis

    5.1. Real/Integer – String

    5.2. Real – Integer

6. Coloração de texto e fundo

7.Caracteres ASCII

1. Operações numéricas gerais

Para além das quarto operações básicas, existem outras suportadas pelo Pascal. Seguem-se alguns exemplos.

SIN, COS e ARCTAN

program operacoes_01;
uses crt;
var a : real;

begin
     write('Introduza angulo em RADIANOS: ');
     readln(a);
     write('Seno do angulo: ',SIN(a):0:3); // valor arredondado a 3 casas decimais
     write('Co-seno do ângulo: ',COS(a):0:3);
     write('Arco-tangente: ',ARCTAN(a):0:3);
     readln;
end.

ROUND, TRUNC e ABS

  • round – arredonda o número às unidades – útil para converter um Real em Integer;
  • trunc – obtém o valor inteiro no número, sem o arredondar – valor truncado;
  • abs – devolve o valor absoluto do número.

Exemplo da sua utilização:

program operacoes_02;
var r : real;
    i : integer;

begin
     write('Introduza numero real: ');
     readln(r);
     write('Arredondado às unidades: ',ROUND(r));
     //equivale a “r:0:0”. Contudo, poderá gravar o valor arredondado numa variável, e “r:0:0” não o faz – tal não é permitido.
     write('Parte inteira: ',TRUNC(r));
     write('Parte fraccionaria: ',ABS(r-TRUNC(r)));
     // considera-se a parte fraccionária sempre POSITIVA, daí a utilização da função ABS.
     write('Valor absoluto: ',ABS(r));
     write('Absoluto da parte inteira: ',ABS(TRUNC(r)));
     readln;
end.

DIV e MOD

Estas são operações muito úteis, relacionadas com a divisão. Relembrando a Parte 1 do tutorial:

  • DIV – devolve o resultado de uma divisão, em número inteiro, truncado: só permite a utilização de variáveis Integer;
  • MOD – devolve o resto de uma divisão: só permite a utilização de variáveis Integer;

program operacoes_03;
uses crt;
var r, s : real;

begin
     write('Introduza dois valores reais: ');
     readln(r, s);
     write('Divisao “normal”: ',r/s);
     // não é prevista a situação de s=0, para simplificação da leitura do programa.
     write('Div. Inteira: ',ROUND(r) DIV ROUND(s));
     write('Resto: ',ROUND(r) MOD ROUND(s));
     readln;
end.

2. Optimização básica

Optimização é o processo que permite reduzir o número de linhas de código, onde o programa realiza exactamente as mesmas operações com menos código, ou seja, o executável terá um tamanho menor, e poderá ser, porventura, ser mais rápido de ser processado.

As primeiras optimizações que vamos fazer será na estrutura de decisão If… Then… Else…. A regra desta estrutura, como já foi visto, é a seguinte:

if (condição) then begin
   comandosA;
end
else begin
     comandosB;
end;

No caso de comandosA ou comandosB serem um e um só código, optimizaremos a estrutura das seguintes formas:

// comandosA é uma só linha:
if (condição) then comandoA
else begin 
     comandosB;
end;

// comandosB é uma só linha:
if (condição) then begin
   comandosA;
end
else comandoB;

// comandosA e comandosB são uma só linha:
if (condição) then comandoA
else comandoB;

Por exemplo:

readln(numero);
if (numero<0) then write('Numero negative.')
else begin
     if (numero>0) then write('Numero positivo')
     else write('Numero nulo');
end;

Agora, o mesmo se aplica a qualquer ciclo de repetição. No caso de os comandos a executar forem tão-somente um código, ficarão assim:

// ciclo WHILE
while (condição) do comandoA;

// Ciclo FOR
for i:=1 to 10 do comandoB;
for i:=1 downto 10 do comandoC;

Ou seja, begin e end são as palavras reservadas omitidas.

A única estrutura que não tem optimização possível é o ciclo Repeat… Until….

3. Facilitação da leitura de um programa

Imaginemos o seguinte caso. Queremos que o utilizador de um programa nosso introduza um número real, em frente à mensagem que lhe colocarmos. Por exemplo, algo como:

write('Introduza um numero real: ');
readln(numero);

Como o cursor fica à frente da mensagem e o número será introduzido em frente deste, o próprio código poderá dar a entender esta facto da seguinte forma:

write('Introduza um numero real: '); readln(numero);
                                 // o cursor fica à frente da mensagem

Ou seja, o código em si dá a entender que o programa esperará o valor real (variável numero) à frente da mensagem. Isto é possível pois o ponto e vírgula (“ ; ”) é o símbolo que faz a separação dos códigos.

Por esta razão é que, no código que antecede um else nunca é precedido de “;”, pois o programa só assim fica a saber que a condição if ainda não acabou e que encontrará imediatamente a seguir um senão (else).

A própria optimização estudada anteriormente facilita em muito a leitura de um programa, pois há menos “poluição visual” com uma série de begin’s e end’s desnecessários. A leitura torna-se mais clara.

O uso de procedimentos e funções facilitará igualmente a leitura do código, para além de o optimizar. As seguintes duas linhas de código fazem exactamente o mesmo, contudo uma utiliza funções e outra não:

NB: As funções aqui apresentadas estão programadas na 2ª parte do tutorial.

// sem recurso a funções:
if (COS(a)<>0) then writeln('A tangente e: ',SIN(a)/COS(a):0:3)
else writeln('Tangente impossivel');

// com recurso a funções:
if tangente_possivel(a) then writeln('A tangente e: ',tan(a):0:3);
else writeln('Tangente impossivel');

Com recurso a funções, conseguimos ler directamente o seguinte:

Se a tangente de “a” é possível então calcula-a, se não diz que é impossível.

Compare-se com o caso em que não há recurso a funções. A leitura é dificultada.

Este é meramente um caso simplista. Casos mais complexos revelarão melhor a importância das funções e dos procedimentos na leitura fácil de um programa, mas tais casos não estão no âmbito deste tutorial devido à sua complexidade (número de linhas de código envolvidas – o foco desta parte seria desviada para o entendimento do programa em si).

4. A fórmula resolvente – programa completo – uso de funções

Vamos criar então um programa que realize a Fórmula Resolvente, recorrendo a Procedimentos e Funções variados.

Tópicos para o programa:

  • Função para o cálculo do Binómio Discriminante;
  • Função para o cálculo de ambos os X (soluções da equação quadrática);

Cumprindo os variados tópicos, vamos definir como funcionará cada Função e cada Procedimento.

program formula_resolvente;
var a, b, c : real;
    i : integer;

function resolucao_possivel(d1:real) : boolean;  // verifica se há solução real
begin
     
end;

function d(a1:real; b1:real;c1:real) : real; // calcula o binómio discriminante
begin
     
end;

function x(i:integer;a1:real;b1:real;c1:real) : real; // calcula o X nº “i”.
begin
     
end;

begin
     writeln('Ax^2 + Bx + C = 0');
     writeln('Introduza os tres coeficientes por ordem: ');
     readln(a, b, c);
end.

Agora que temos o esqueleto do programa, resta-nos programá-lo de acordo com as funções de que dispomos.

Para treinar a leitura lógica de um programa que utilize funções, a explicação não será alongada. Claro que o exemplo seguinte tem funções utilizadas com um certo abuso, mas tal foi propositado.

program formula_resolvente;
var a, b, c : real;
    i : integer;

function resolucao_possivel(d1:real) : boolean;  // verifica se há solução real
begin
     if (d1>=0) then resolucao_possivel := true  // se o Bin. Disc. For maior ou igual que zero, há soluções reais
     else resolucao_possivel := false;
end;

function d(a1:real; b1:real; c1:real) : real;  // calcula o binómio discriminante
begin
     d:=SQR(b1) – 4*a1*c1;
end;

function x(j:integer; a1:real; b1:real; c1:real) : real; // calcula o X nº “j”.
begin
     case j of
          1 : x := (-b1 + SQRT( d(a1, b1, c1) )) / (2*a1);
          2 : x := (-b1 - SQRT( d(a1, b1, c1) )) / (2*a1);
     end;
end;

begin
     writeln('Ax^2 + Bx + C = 0');
     writeln('Introduza os tres coeficientes por ordem: ');
     readln(a, b, c);
     if resolucao_possivel( d(a, b, c) ) then begin
     // se a resolução é possível (sabendo-se tal pelo Discriminante), então…
        for i:=1 to 2 do write('Solucao ',i,': ', x(i, a, b, c):0:3 );
     end else begin
              write('Impossivel em R.');
     end;
     readln;
end.


Desafio 1

Crie um programa que leia o nome do utilizador e apresenta-o com os caracteres por ordem inversa. Por exemplo:

“Thoga 31” passará a ser “13 agohT”

Contudo, terá de criar uma função para:

  • Ler uma variável string, denominada ler;
  • Escrever um texto, denominada escrever;

Normas: livre


5. Conversão de variáveis

Existem, claro está, funções que nos permitem converter as variáveis de uns tipos para outros.

É possível converter de Real para String, de String para Real, de Integer para Real e de Real para Integer. Existem outras variáveis, contudo, que não são abordadas de momento.

5.1. Real/Integer – String

Sejam dadas as variáveis r, Real, e s, String. Sejam igualmente as variáveiserro e i, Integer.

str(s, r, erro);
// Converter a string “s” para real, “r”.
// Se tal não for possível, indicar a posição do erro, em “erro”.

A posição do erro consiste no índice da string no qual existe o erro. Exemplo:

574P5 – o erro está na posição 4: “P”.

str(s, i, erro);
// Converter a string “s” para integer, “i”.
// Se tal não for possível, indicar a posição do erro, em “erro”.

A posição do erro consiste no índice da string no qual existe o erro. Exemplo:

5.915 – o erro está na posição 2: “.”: um Integer não tem parte decimal.

val(r, s);
// Converter o real “r” para string, “s”.
val(i, s);
// Converter o integer “i” para string, “s”.

A conversão de real/integer para string não implicará erro nenhum, caso o processo seja correctamente efectuado na CPU, o que não é previsto o contrário.

5.2. Real – Integer

Considerando as mesmas variáveis:

r := i;

Não são necessárias normas para esta conversão, visto que um número inteiro (Integer) não passa de um caso especial do universo dos reais (Real). Logo são intimamente compatíveis nesta, e só nesta, conversão.

Já o inverso não se verifica, pois um número real pode não pertencer ao universo dos inteiros. Para esta conversão, é necessário arredondar o Real, e o Pascal só reconhece esta operação com um de dois operadores: ROUND e TRUNC, cujas diferenças já foram previamente explicadas.

i := ROUND(r);
i := TRUNC(r);

6. Coloração de texto e fundo

O sistema de cores que o pascal suporta é o seguinte:

  • Para cor do texto: 4 bits (16 cores);
  • Para a cor do fundo: 3 bits (8 cores);

Os códigos que permitem a aplicação de cores são os seguintes:

  • Para cor do texto: textcolor;
  • Para a cor do fundo: textbackground;

A cor predefinida do texto é a nº 7, e a de fundo é a nº 8.

textcolor(7);
textbackground(8);

Para conhecer as cores do Pascal, pode-se construir o seguinte programa:

program cores;
uses crt;
var i : integer;

begin
     writeln('Cores de TEXTO:');
     for i:=1 to 16 do begin
         textcolor(i);
         write(' Cor ',i,' ');
     end;
     writeln;
     writeln('Cores do FUNDO:');
     textcolor(15); // branco
     for i:=1 to 8 do begin
         textbackground(i);
         write(' Cor ',i,' ');
     end;
     writeln;
end.


Desafio 2

Crie um programa que construa uma tabela em que, em cada coluna, fica uma cor de fundo, e em cada linha uma cor de texto, para que possam ser analisadas todas as combinações fundo/texto possíveis.

Normas: livre


7. Caracteres ASCII

O sistema de caracteres do Pascal é o ASCII. Dependendo de cada país e/ou sistema, a tabela pode sofrer algumas modificações, as quais o Pascal é sensível pois ele recorre ao sistema ASCII do próprio computador e não a uma tabela ASCII própria.

Para se conhecer a tabela ASCII de cada programa, é possível criar um programa que a debite.

Para saber o caracter de ordem i da tabela ASCII:

write( CHAR(i) );

Já para saber a ordem de um caracter:

write( ORD(caracter) );

Sendo caracter uma variável do tipo char.

No caso de string, para se saber a ordem de cada carácter dever-se-á realizar o seguinte ciclo:

for i:=1 to length(s) do write(ORD(s[i]),' ');

(i – variável Integer)

Só com o método CHAR é possível escrever acentuações em determinados IDEs/compiladores.


Desafio 3

Crie um programa que construa uma tabela ASCII, indicando a ordem seguida do carácter correspondente.

Normas: livre

Desafio 4

Crie, num programa, tão-somente duas funções que façam uma conversão especial.

Muitas vezes, o valor booleano True é associado ao número 1, e False ao número 0. Então, uma das funções converte um booleano no seu correspondente numérico. A outra função realizará o inverso.

Normas: livre



Propostas de Exercícios

6. Crie uma calculadora que realize as quatro operações básicas, com previsão de erros, como o da divisão. Estes deverão ser escritos a vermelho vivo. Os textos deverão ser a branco e os resultados a amarelo vivo.

Faça um programa em que, no fim, se possa optar se se deseja realizar novo cálculo ou se se deseja sair.

Normas:

  • Limite de linhas de código (exclusive comentários e linhas em branco): 70 linhas.

7.Um programa deverá desenhar a bandeira da França. Utilize ciclos for.

Faça um procedimento para desenhar a bandeira, onde as variáveis de entrada serão a cor a utilizar, o número de colunas e o número de linhas a desenhar.

Normas:

  • Limite de linhas de código (exclusive comentários e linhas em branco): 30 linhas.


Na próxima parte, será dada ênfase aos códigos que permitem trabalhar com uma string, e alguns códigos úteis sobre o cursor e o teclado. Será igualmente realizada uma introdução a variáveis Record.

De seguida, abordar-se-á as variáveis para escrita de dados num ficheiro de texto simples, e obtenção da data e hora do sistema.

(2ª Parte)

(4ª parte)



Knowledge is free!

Share this post


Link to post
Share on other sites
nunopicado

heheheh O Pedro e os ponteiros! :P

Sem dúvida importantes, embora confesse que nunca tive muita paciencia para os estudar mais a fundo! Fiquei traumatizado quando os comecei a estudar em C e nunca mais quis ouvir falar deles!  :wallbash:

Thoga31: Não tive ainda tempo de ler tudo a fundo, porque estou aqui com uma time table apertada, mas do que li assim de fugida, pareceu-me muito bem, tanto a 2ª parte (que como o Pedro disse são exercícios e não há muito a falar) como a 3ª parte.

Os records também me parecem essenciais, e logo de seguida os ficheiros! Quando puderes... :)

Este tópico está rapidamente a transformar-se numa bíblia que recomendo a quem quer começar em Pascal, e já o tenho feito a alguns!

Há por aí livros comerciais sobre o assunto que não são tão bons!

Como tal, parabéns!  :P


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
thoga31

heheheh O Pedro e os ponteiros! :)

Sem dúvida importantes, embora confesse que nunca tive muita paciencia para os estudar mais a fundo! Fiquei traumatizado quando os comecei a estudar em C e nunca mais quis ouvir falar deles!  :wallbash:

Em Pascal até me parecem ser simples. São denominadas de Variáveis Dinâmicas, e, em vez de serem declaradas como estamos habituados, acrescenta-se um acento circunflexo: a^ : Real;. Depois é utilizar dois códigos a mais.

A 4ª parte será mesmo sobre record e text :P

Não prometo datas.

Thoga31: Não tive ainda tempo de ler tudo a fundo, porque estou aqui com uma time table apertada, mas do que li assim de fugida, pareceu-me muito bem, tanto a 2ª parte (que como o Pedro disse são exercícios e não há muito a falar) como a 3ª parte.

(...)

Este tópico está rapidamente a transformar-se numa bíblia que recomendo a quem quer começar em Pascal, e já o tenho feito a alguns!

Há por aí livros comerciais sobre o assunto que não são tão bons!

Como tal, parabéns!  :P

Uhh... Obrigado... 😳

É bom saber que há quem aprecie o meu trabalho :)

Cumpz.


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

@nunopicado: há razões para insistir nos ponteiros :P

Eu sei que podem parecer chatos, especialmente porque em C há aquele preconceito de que os ponteiros são uma coisa terrível, mas é apenas uma questão de parar para pensar neles um pouco... São mesmo muito úteis.

É verdade que usá-los é quase estar a pedir erros em runtime, mas há coisas que pura e simplesmente não se fazem sem eles, e com alguma prática conseguimos programar de forma segura mesmo com eles.

@thoga31: ainda não li a 3ª parte, mas fá-lo-ei assim que puder :)

Quanto aos ponteiros, há algo mais além de teres que os declarar com um ^... Mas um dia vais descobrir. Eu usei-os aí num post qualquer em conjunto com records, se não estou em erro. Acho que o nunopicado tb participou nessa thread

Share this post


Link to post
Share on other sites
thoga31

Parte 4

Está terminada! Em suma:

  • Variáveis Record;
  • Variáveis Text - parte 1;
  • Códigos úteis sobre teclado, cursor e string.

Desta vez é uma parte um pouco mais pequena (4 capítulos) devido ao aumento da complexidade. Servirá como "transição" para as partes seguintes, muito mais "puxadas".

Estou só a reler e a alterar alguns pormenores...

Inclui ainda 3 Propostas de Exercícios e 1 Desafio, o qual prometo ser mesmo um desafio - ou se adquiriu os conhecimentos anteriores e se experimentou por auto-recriação (método de auto-aprendizagem) ou será uma dor de cabeça, apesar de aparentemente simples (para não-principiantes). :)

Cumpz,

Até já! :D


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Introdução ao Pascal – Parte 4

Actualizado

(3ª parte)

(5ª parte)

Seguimos agora para uma parte do Pascal mais complexa e que começa a mostrar novas potencialidades do Pascal. Vamos trabalhar com variáveis do tipo Record e daremos as bases sobre as variáveis Text.

Serão dados códigos úteis sobre strings e sobre o teclado e o cursor.

Esta parte é mais pequena por revelar um maior nível de complexidade – é uma parte de “transição” para as futuras partes, que prometem ser mais complexas.

Índice

1. A variável Record

1.1. A cláusula With

2. Códigos úteis sobre o teclado e o cursor

2.1. Posição do cursor

2.2. Determinação da tecla premida

3. A variável Text – escrita e leitura de ficheiros de texto simples – parte 1

4. Códigos úteis sobre string

5. Aleatoriedade

1. A variável Record

Estas variáveis são extremamente úteis para, por exemplo, programas de registos. Uma variável Record tem várias “subvariáveis”, geralmente designadas por campos. a sua utilização faz lembrar a utilização de métodos e propriedades do Visual Basic. Eis um exemplo da declaração de uma variável Record:

var registo : record
              nome : string;
              idade : integer;
              sexo : char;
    end;

Para pedir ao utilizador, por exemplo, para registar a idade, fá-lo-á do seguinte modo:

writeln('Registe a idade: '); readln(registo.idade);

Ou seja, a variável Record faz-nos lembrar um formulário onde devemos preencher os vários campos, por exemplo num CV.

A variável Record é um formulário, e as suas várias “subvariáveis” (campos) são os campos desse formulário.

É possível criar uma “resma” de formulários sob a forma de um array de Record – isto revela que é possível criar milhares de campos em memória, organizados por grupos individuais, de uma forma muito simples e eficaz, sem recorrer a milhares de variáveis. Ou seja, em vez de termos as variáveis nome1, nome2, nome3, idade1, idade2, idade3, sexo1, sexo2 e sexo3, temos três registos (Record), cada um com os seus campos idade, nome e sexo. Em código:

type tipo_reg = record
              nome : string;
              idade : integer;
              sexo : char;
     end;

var registo : array [1..3] of tipo_reg;

Então, pode-se preencher os 3 formulários (array [1..3]) recorrendo a um ciclo for.

for i:=1 to 3 do begin
    writeln('A FAZER REGISTO NUMERO ',i);
    write('Nome: '); readln(registo[i].nome);
    repeat
          write('Sexo (M/F): '); readln(registo[i].sexo);
    //só aceita os caracteres “M” e “F”:
    until (upcase(registo[i].sexo) = 'M') or (upcase(registo[i].sexo) = 'F');
    repeat
          write('Idade: '); readln(registo[i].idade);
    // a idade é positiva ou nula:
    until (registo[i].idade >= 0);
    writeln('REGISTO ',i,' DE 3 EFECTUADO.');
    writeln;
end;

Da mesma forma, estes registos podem ser escritos com um ciclo for:

for i:=1 to 3 do begin
    writeln('A VER REGISTO NUMERO ',i);
    writeln('Nome: ',upcase(registo[i].nome));
    writeln('Sexo: ',upcase(registo[i].sexo));
    writeln('Idade: ',registo[i].idade);
    writeln;
end;

Assim acabámos por criar um programa completo que realiza um registo básico de 3 pessoas, escrevendo o que foi introduzido no final. Este fica, então, como um programa exemplo sobre este tipo de variáveis, essenciais em Pascal:

program variavel_record;
uses crt;

type tipo_reg = record
              nome : string;
              idade : integer;
              sexo : char;
     end;

var registo : array [1..3] of tipo_reg;
    i : integer;

begin
     for i:=1 to 3 do begin  // REGISTO
         writeln('A FAZER REGISTO NUMERO ',i);

         write('Nome: '); readln(registo[i].nome);  // registo do NOME

         repeat  // registo controlado do SEXO
               write('Sexo (M/F): '); readln(registo[i].sexo);
         until (upcase(registo[i].sexo) = 'M') or (upcase(registo[i].sexo) = 'F');

         repeat  // registo controlado da IDADE
               write('Idade: '); readln(registo[i].idade);
         until (registo[i].idade >= 0);

         writeln('REGISTO ',i,' DE 3 EFECTUADO.');
         writeln;
     end;

     writeln;
     writeln;

     for i:=1 to 3 do begin  // ESCRITA
         writeln('A VER REGISTO NUMERO ',i);
         writeln('Nome: ',upcase(registo[i].nome));
         writeln('Sexo: ',upcase(registo[i].sexo));
         writeln('Idade: ',registo[i].idade);
         writeln;
     end;

     readln;  // pausa até ENTER
end.


Propostas de Exercícios

8. Crie um programa que registe os dados sobre uma turma inteira e faça a estatística básica.

Serão pedidos o número de alunos, e o nome e as avaliações a Matemática e a Português de cada um.

No final, o programa faz a estatística e diz quais os alunos aptos a ir a Exame Nacional (média igual ou superior a 9,5) de cada disciplina, qual a média da turma a Matemática e a média a Português.

Normas:

  • Deverá ser utilizado um só Record, que inclua todos os campos;
  • Recorra a ciclos for para percorrer os campos;
  • No máximo, só poderão existir 30 alunos;
  • Limite de linhas de código (exclusive comentários e linhas em branco): 100 linhas.


1.1. A cláusula With

Existe um código, também denominado, neste caso, de cláusula, que permite “pegar” num Record e trabalhar com ele, sem que se tenha de escrever constantemente o nome do registo. Por exemplo:

with registo[2] do begin
     nome := 'Thoga31';
     idade := 0;
     sexo := 'M';
end;

Substitui:

registo[2].nome := 'Thoga31';
registo[2].idade := 0;
registo[2].sexo := 'M';

Ou seja, simplifica muito a escrita de código, e permite maior legibilidade.

2. Códigos úteis sobre o teclado e o cursor

2.1. Posição do cursor

Como hão-de ter reparado, os programas têm sido direccionados para as consolas DOS. (E não, não vamos entrar em ambientes visuais :) )

Como se sabe, a consola DOS tem sempre o cursor a piscar, numa determinada posição. Ora, em Pascal é possível controlar esta posição através de um comando extremamente simples.

Considere-se a janela um gráfico cartesiano, só de valores inteiros. Seja X a abcissa (horizontal) e Y a ordenada (vertical). A posição inicial do cursor na consola é no canto superior esquerdo: X=1 e Y=1. Ande-se duas linhas para baixo: X=1 e Y=3. Ande-se com o cursor nove colunas para a frente (direita): X=10 e Y=3.

Se quisermos posicionar o cursor nesta última posição:

gotoxy(10, 3);

CÓDIGO: posicionamento do cursor na consola DOS


gotoxy(x, y)


2.2. Determinação da tecla premida

É possível gravar a qualquer altura qual a tecla premida por um utilizador. Esta função é extremamente útil na criação de menus apelativos. O utilizador em vez de escrever, por exemplo, “1” e, de seguida, premir ENTER, bastar-lhe-á premir a tecla “1” e, se for uma opção válida do menu apresentado, avança imediatamente, sem ser necessário premir ENTER. Por exemplo:

uses crt;  // biblioteca OBRIGATÓRIA
var tecla : char;

// (. . .)

writeln('MENU');
writeln('1 > Repetir operacao');
writeln('2 > Sair');

repeat
      tecla := readkey;
      // grava na variável TECLA qual a tecla (key) premida pelo utilizador
until (char(tecla) = '1') or (char(tecla) = '2');


O código

readkey determina a tecla premida pelo utilizador, gravando-a numa variável char.

Este código só é utilizável quando declarada a biblioteca crt. Caso contrário, é um código não declarado.



Propostas de Exercícios

9. Crie uma calculadora que grave num Record, em campos distintos, os dois termos da operação, e o operador.

O utilizador deverá escolher o operador sem ter de premir ENTER, segundo uma lista dos operadores disponíveis (soma, subtracção, multiplicação e divisão). Preveja situações de erro, e permita que o utilizador as corrija.

O utilizador, com um novo menu, sem recurso ao ENTER, irá escolher se deseja sair do programa ou realizar novo cálculo.

Utilize coloração de texto variada, e não de fundo. O ecrã deverá ter fundo cinza claro.

Normas:

  • Deverá ser utilizado um só Record;
  • Limite de linhas de código (exclusive comentários e linhas em branco): 100 linhas.


3. A variável Text – escrita e leitura de ficheiros de texto simples – parte 1

O Pascal tem a capacidade de trabalhar com ficheiros. Existem duas variáveis para o fazer, contudo vamos abordar apenas aquela que permite escrever e ler ficheiros de texto simples, ou seja, ficheiros cujo conteúdo não passa de texto simples, não formatado: é a variável Text, cujo nome denuncia o tipo de ficheiros que vai trabalhar.

O funcionamento desta variável é em tudo diferente das variáveis com que já trabalhámos até agora.

Vamos, então, estudar esta variável por partes e com exemplos práticos.

O primeiro programa apresentado cria um ficheiro TXT e grava nele o texto “Hello World! For Pascal TEXT!”. O ficheiro é nomeado de texto.txt.

program escrever_ficheiro;
var ficheiro : text;

begin
     assign(ficheiro, 'texto.txt');
     // “assina” em memória o ficheiro de texto simples, e cria-o junto do executável
     rewrite(ficheiro);
     // ordena a re-escrita do ficheiro – caso o ficheiro já exista e contenha texto, este será eliminado
     write(ficheiro, 'Hello World! For Pascal TEXT!');
     // escreve no ficheiro o texto
     close(ficheiro);
     // “encerra” o ficheiro em memória
end.

Quando se tenta aceder a um ficheiro de texto simples que esteja “assinado” em memória por um programa deste género, aparecerá a famosa Message Box a dizer que o ficheiro está a ser utilizado por outro processo. Isto ajuda a explicar o que acontece no sistema aquando o código assign.

Agora, vamos criar um novo programa, que ficará no mesmo directório, e que vai abrir o ficheiro anterior e contar o número de espaços do texto que contém:

program ler_ficheiro;
var ficheiro : text;
     s : string;
     contador, i : integer;

begin
     assign(ficheiro, 'texto.txt');
     reset(ficheiro);
     // “reinicia” o ficheiro, ou seja, acede-lhe mas não pode re-escrever dados nele, só pode ler
     readln(ficheiro, s);
     contador := 0;
     for i:=1 to length(s) do  if s[i] = ' ' then contador += 1;
     // a linha de código anterior recorre à Optimização
     writeln('Existem ',contador,' espacos no ficheiro.');
     close(ficheiro);
     readln;
end.


Desafio 5

Investigue sobre os CV (Curriculum Vitae) europeu – o Europass.

Crie um programa que crie um CV deste modelo, cumprindo todos os campos, excepto o da Fotografia.

O programa irá registar os dados do utilizador e, de seguida, irá mostrar por passos o que o utilizador introduziu. No caso de confirmação, deverá gravar o CV num ficheiro TXT cujo nome será “CV_nome”, onde “nome” é o nome do utilizador, sem espaços. Os campos não preenchidos não deverão aparecer no ficheiro.

Caso o utilizador pretenda alterar um campo, tal deverá ser permitido sem que, para tal, seja necessário refazer o CV todo.

Normas:

  • O CV deverá estar registado num só Record, que inclua todos os campos;
  • O CV só será gravado em ficheiro no fim, aquando a confirmação final por parte do utilizador;
  • O utilizador poderá cancelar o CV a qualquer altura, escrevendo “<cancelar>”;
  • Limite de linhas de código (exclusive comentários e linhas em branco): livre


4. Códigos úteis sobre string

Seja a variável s uma String com o seguinte texto:

BEM VINDO

pos('M', s);

Determina a posição do primeiro “M” que encontrar: neste caso, 3.

Devolve um valor Integer, a ser gravado numa variável deste tipo.

delete(s, 7, 3);

Elimina 3 caracteres a partir da posição 7, inclusive.

A string passa a ser “BEM VI”.

insert('- ', s, 4);

Insere, na posição 4, o texto “- ”.

A string passa a ser: “BEM – VINDO”.


Propostas de Exercícios

10. Crie um programa em que o utilizador introduza uma string e possa realizar testes variados com ela. A original deverá manter-se intacta, sendo uma string auxiliar a utilizada para as operações.

O utilizador poderá escolher a posição, os caracteres e textos, entre outros, relacionados com os códigos anteriores.

Normas: livre.


5. Aleatoriedade

Uma das capacidade do computador é o cálculo de números aleatórios. Estes números não são propriamente aleatórios - chama-se a este processo pseudo-aleatoriedade, isto porque o computador não tem a capacidade de "pensar" num número aleatoriamente. Existem diversos algoritmos, praticamente todos baseados no tempo. Este princípio baseia-se, geralmente, num Timer do computador em que, quando é requerido um número pseudo-aleatório, este calcula-o segundo uma fórmula que inclui os limites mínimo e máximo do conjunto no qual deve estar o número, e o Timer. É devolvido então o resultado de um cálculo, e não um número totalmente aleatório.

Em Pascal, é necessário, na generalidade dos compiladores, "activar" este Timer para que possam ser debitados valores pseudo-aleatórios.

randomize;

Não existe nenhum procedimento que "pare" o Timer. Contudo, esta última instrução pode ser constantemente utilizada sem "efeitos".

O Pascal só admite conjuntos de 0 a maxint (i.e., o número máximo inteiro positivo suportado), inclusive.

Para requerer um número pseudo-aleatório que pertença a um conjunto de 0 a n, inclusive:

random(n);

Esta função devolve um número real.

Crie-se, então, um pequeno programa que debite em toda a consola um código binário aleatório:

program binario;
uses crt;
var i, j : integer;

begin
     randomize;
     for i:=1 to 20 do begin
         for j:=1 to 80 do begin
             gotoxy(j,i);
             write(TRUNC(RANDOM(2)));
         end;
     end;
     readln;
end.

É utilizada a função Trunc devido ao facto de Random devolver números tais como, por exemplo, 0.365, 1.845 (aqui abreviados). Assim, apenas é mostrado o valor inteiro do número, não arredondado - ou 0 ou 1, tal como desejado.


Propostas de Exercícios

11. Simule a Lei dos Grandes Números num programa que irá "lançar" um dado cúbico regular um milhão (1.000.000) de vezes. O programa só deverá gerar como output o número de vezes que "saiu" cada face. Tenha em conta que não existe a face 0 (zero), isto por causa do "defeito" do comando Random - neste caso, o computador deverá calcular nova face, sem que conte como um lançamento.

Normas: livre.


(3ª parte)

(5ª parte)


Knowledge is free!

Share this post


Link to post
Share on other sites
jpaulino

thoga31 está um excelente trabalho, mas mete lá isto tudo na wiki :)

Fica mais organizado e não várias partes espalhadas pelo post.

Parabéns :confused:

Share this post


Link to post
Share on other sites
thoga31

thoga31 está um excelente trabalho, mas mete lá isto tudo na wiki :)

Fica mais organizado e não várias partes espalhadas pelo post.

Parabéns :)

Boas, jpaulino!

Infelizmente, o meu tempo está a voltar a encurtar, de tal forma que ainda nem consegui iniciar a 5ª parte do Tutorial...

Por isso, nos próximos tempos, não será fácil organizar tudo e colocar na Wiki.

Se alguém tiver a disponibilidade, até agradeço bastante! Não é por "preguicite", a época de Exames está-me a queimar o tempo quase todo, e logo a seguir vai começar o 2º semestre! :)

thoga31 está um excelente trabalho

Obrigado! :)

Cumprimentos! :confused:


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Parte 5

E pronto, mais uma parte terminada! :D

A 5ª parte vai encerrar a parte básica do Pascal. Planeio escrever mais, pelo menos, duas três partes, que serão muito mais complexas, e que, por isso, exigirão muito mais de mim para que consiga manter a mesma simplicidade, clareza e objectividade que tenho vindo a tentar imprimir neste tutorial.

Segue-se uma síntese dos conteúdos desta parte:

  • Conjuntos;
  • Estruturação de um programa Pascal;
  • Data e Hora do Sistema.

Estou a terminar a revisão desta última parte.

Espero publicar ainda hoje esta parte. :P

Espero, igualmente, o vosso feedback.

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Olá pessoal!

Ainda não publiquei a Parte 5 do tutorial porque ontem adoeci repentinamente e com alguma "gravidade": não aguentei mais ver as letras do computador com 38,3ºC de febre :D

Hoje estou aqui a falar-vos com algum custo, mas acho que era mau não vir aqui cumprir o prometido. Rezo para que seja ainda hoje que termine a revisão da 5ª parte para a publicar: é mais demorada porque é muito extensa: cerca de 3500 palavras. :D

De igual forma, gostaria de vos pedir uma opinião, incluindo ao staff que ver esta mensagem, e espero mesmo uma resposta. :)

Reparei que o Tutorial do deathseeker ainda não foi terminado, passados 5 anos que começou, e que já começa a estar um pouco "desactualizado" não no que toca a conteúdos mas sim à "estruturação" do tutorial 😳

E perguntei-me se este meu tópico não ficaria melhor no quadro dos Tutoriais, ou, pelo menos, ser criado lá um tópico de redireccionamento para este.

É que este tutorial ainda não foi muito visto, e o do dethseeker, no mesmo período de tempo, pareceu-me ter tido umas milhares de visitas: acaba por ser natural - está no quadro de tutoriais, que é o que o ppl procura.

Ao mesmo tempo, estou a pensar em "actualizar" o título deste post, pois isto já nem é bem uma "introdução", já vai muito além das minhas ideias iniciais, e confesso que estou a adorar a experiência de dar a conhecer aquilo que eu sei :)

Espero o vosso feedback :(

Cumprimentos,

thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Introdução ao Pascal – Parte 5

(4ª parte)

(6ª parte)

Agora as coisas vão complicar um pouco. Vamos entrar nas estruturas mais complexas do Pascal, que foram deixadas propositadamente para o fim.

Nesta parte são abordados os Conjuntos, que são uma estrutura constituível pelo programador, isto é, uma colecção. É abordada mais a fundo uma forma simples de estruturar um programa recorrendo à estrutura Begin/End. E, por fim, para terminar a iniciação ao Pascal, é dado, por curiosidade, três procedimentos padrão de uma nova biblioteca que permitem determinar a data e a hora do sistema, e obrigar o programa a parar durante um certo tempo antes de avançar.

As próximas partes serão de programação mais avançada, a qual terá de ser tratada com mais cuidado da minha parte.

Índice

1. Conjuntos

    1.1. Declaração e utilização

    1.2. Operações com conjuntos

    1.3. Comparação de conjuntos

    1.4. Análise de uma linha de texto

2. Estruturação de um programa em Pascal

    2.1. Estrutura Begin… End

    2.2. A cláusula Exit

    2.3. Características desejáveis num programa

3. Data e hora do sistema

1. Conjuntos

Parte deste capítulo foi baseado em: GOTTFRIED, Byron S., Programação em Pascal, McGraw-Hill, 1994

Algumas frases poderão ser iguais às do livro. Parte dos exemplos é retirado igualmente deste livro.

Isto deve-se ao facto de este livro estar muito bem conseguido no que toca a Conjuntos, tornando-se inigualavelmente claro.

Um conjunto é uma colecção de elementos simples ordenados, todos do mesmo tipo.

Um conjunto não é fácil de se declarar, mas, anteriormente, já os utilizámos de forma inconsciente, aquando a escrita, por exemplo, de:

while not A in [0..9] do

[0..9] é um conjunto de reais, que começa em 0 (zero), inclusive, e termina em 9 (nove), inclusive.

Já no programa que analisava as avaliações dos alunos, utilizámos a seguinte notação:

case avaliacao of
     0..3 : writeln('Fraco');
     // etc.
end;

0..3 representa o intervalo de números reais entre zero e três, inclusive.

1.1. Declaração e utilização

Podemos criar um conjunto, nomeado (com nome), de uma certa natureza. Teoricamente, há que declarar o conjunto pela seguinte ordem:

[*]Declarar os elementos base como Type;

[*]Declarar o conjunto em termos de elementos base, como Type;

[*]Declarar o nome de conjunto, como Var, sendo do tipo conjunto.

Parece um processo complicado, e com passos sem sentido. Contudo, esta organização faz parte da estruturação do Pascal como linguagem estruturada – podemos dizer que “as coisas não aparecem do nada nem por milagre”.

Vejamos a declaração do conjunto em termos teóricos:



type elementos_base = (dado1, dado2, …, dado n);
    conjunto = set of elementos_base;
var nome_de_conjunto : conjunto;

Agora aplique-se a teoria num exemplo prático:



type medidas = (pequeno, medio, grande);
    medidas_camisa = set of medidas;
var manga : medidas_camisa;

Podemos definir um conjunto com dados padrão, tal como, por exemplo:



type algarismos = set of 0..9;
    minusculas = set of 'a'..'z';

Contudo, um conjunto pode ser construído.

Imaginemos uma calculadora, tal como já foi dada como exercício anteriormente, onde o utilizador pode escolher o operador. Podíamos declarar um conjunto dos operadores, e, no código, simplificar a escrita do programa:



program calculadora;
uses crt;

type conjunto_operadores = set of char;

var operadores : conjunto_operadores;
    oper : char;

begin
    oper := ['+', '-', '*', '/'];
    // …
    repeat
          oper := readkey;
    until char(oper) in operadores;
    // …
end.

Como se constata, oper foi declarado como uma variável. Contudo, podia ser declarado como uma constante, não sendo necessário declarar dois tipos.



program calculadora;
uses crt;

const operadores = ['+', '-', '*', '/'];
var oper : char;

begin
    // …
    repeat
          oper := readkey;
    until char(oper) in operadores;
    // …
end.

O primeiro exemplo é um excelente exemplar da declaração de um conjunto através de tipos, e o segundo exemplo mostra a criação de um conjunto, constante, através de um conjunto individual de elementos ordenados e definidos, inalteráveis.

A utilização deste conjunto simplifica na medida em que, na estrutura Repeat… Until…, torna-se mais legível, ao invés de:



repeat
      oper := readkey;
until (char(oper)='+') or (char(oper)='-') or (char(oper)='*') or (char(oper)='/');

Os conjuntos são úteis na medida em que criamos uma colecção de elementos ordenados, irrepetíveis, como sendo um grupo. Para quem é conhecedor de VB, pode-se fazer a analogia óbvia de que uma colecção em Pascal é o mesmo que uma enumeração (Enum) em VB. Por exemplo, a colecção de operadores criada anteriormente em Pascal seria, em VB, algo como:



Private Enum operadores As Char
    "+"
    "-"
    "*"
    "/"
End Enum

Seguem-se pequenos exemplos de subconjuntos, aplicando o exemplo das medidas:



type medidas = (pequeno, medio, grande);
    medidas_camisa = set of medidas;

var manga_curta, manga_comprida, outra_manga : medidas_camisa;

begin
    // …
    manga_curta := [pequeno, grande];
    manga_comprida := [pequeno..grande];
    outra_manga := [grande];
    // …
end.

Não é fácil visualizar certas utilizações “muito” práticas dos conjuntos, em Pascal. Contudo, será construído, mais à frente, um programa para exemplificar a sua utilidade.

Para já, vamos aprender a realizar operações com conjuntos.

1.2. Operações com conjuntos

Ao operar com conjuntos, estamos a falar de três operações básicas, familiares da Teoria de Conjuntos na Matemática:

  • Intersecção;
  • União;
  • Diferença.

Vamos abordar cada uma delas, por ordem, através de exemplos práticos, todos seguindo a colecção criada anteriormente sobre medidas de camisas.

INTERSECÇÃO

A intersecção baseia-se no princípio de obter os elementos que estão em comum entre dois ou mais conjuntos. Por exemplo, a intersecção entre o conjunto de números {1, 2, 3, 4, 5} e o conjunto {0, 3, 4, 6} é o conjunto {3, 4}. Na matemática, esta operação representa-se por uma “multiplicação”. Assim o é em Pascal:



manga_curta := [pequeno, medio] * [medio, grande];

Neste caso, manga-curta será, por fim, o conjunto [medio].

Já no seguinte caso:



manga_comprida := [pequeno] * [grande];

manga_comprida será o conjunto vazio, [ ].

Como constatamos, existe o conjunto vazio em Pascal. Ora, isto leva-nos já a uma propriedade da intersecção.


A intersecção entre um conjunto e o conjunto vazio é o próprio conjunto vazio.


UNIÃO (ou REUNIÃO)

A união, ou reunião, de dois ou mais conjuntos resulta num novo conjunto que contenha todos os elementos, sem excepção, de todos os conjuntos envolvidos na operação, sem que haja elementos repetido. Por exemplo, a reunião entre os conjuntos {1, 2, 3, 4} e {0, 3, 4, 6} é o conjunto {0, 1, 2, 3, 4, 6}, e não o conjunto {0, 1, 2, 3, 3, 4, 4, 6}.

Regra geral, na matemática esta operação representa-se como sendo uma “soma”. Em Pascal:



manga_curta := [pequeno] + [grande];

Neste caso, resulta o conjunto [pequeno, grande].



manga_comprida := [pequeno, grande] + [medio, grande];

Agora, resulta o conjunto [pequeno, medio, grande],


A união entre um conjunto e o conjunto vazio é o próprio primeiro conjunto.


DIFERENÇA

Pegando em dois conjuntos, a diferença do primeiro pelo segundo resulta num conjunto constituído pelos elementos do primeiro excepto os do segundo. Por exemplo, {1, 2, 3, 4} – {0, 3, 4, 6} dará o conjunto {1, 2}. Já no caso da operação {0, 3, 4, 6} – {1, 2, 3, 4}, o resultado será o conjunto {0, 6}.

A diferença de conjuntos é feita, na matemática, exactamente pela operação da subtracção. Em pascal, o mesmo acontece:



manga_curta := [pequeno, medio] – [pequeno, grande];

Neste caso, o conjunto solução é [medio].



manga_comprida := [pequeno, medio, grande] – [medio];

Já neste caso, o conjunto solução é [pequeno, grande].


A diferença de um conjunto pelo conjunto vazio é o próprio primeiro conjunto.



A diferença do conjunto vazio por outro conjunto é o próprio conjunto vazio.


Segue-se um exemplo de atribuição de conjuntos, com operações:



manga_curta := [pequeno, medio, grande];
manga_comprida := manga_curta – [pequeno];
// manga_comprida = [medio, grande]
manga_curta := manga_curta * (manga_comprida – [grande]);
// manga_curta = [medio]

1.3. Comparação de conjuntos

Após as operações de conjuntos, passemos então à comparação. Em matemática, isto resume-se em expressões como “pertence a”, “está contido em” ou “não está contido em”. O Pascal tem a capacidade de realizar estas comparações, tendo, para tal, quatro operadores. O resultado resultante destas comparações é sempre e tão-somente um valor booleano.

  • =Igualdade – ambos os conjuntos contêm os mesmos membros, independentemente da ordem;
  • <>Desigualdade – os conjuntos não contêm exactamente os mesmos membros;
  • <=Inclusão – cada membro do primeiro conjunto está contido no segundo conjunto;
  • >=Inclusão – cada membro do segundo conjunto está contido no primeiro conjunto.

Analisemos então uma série de comparações entre conjuntos, e o resultado retornado por cada uma:

  • [pequeno, grande] = [pequeno, medio, grande], falso;
  • [pequeno, grande] = [grande, pequeno], verdadeiro;
  • [pequeno, médio, grande] <> [pequeno..grande], falso;
  • [pequeno, grande] <> [grande], verdadeiro;
  • [pequeno] <= [pequeno..grande], verdadeiro;
  • [pequeno..grande] <= [grande], falso;
  • [] <= [pequeno, grande], verdadeiro;
  • [pequeno..grande] >= [pequeno, medio], verdadeiro;
  • [grande] >= [pequeno, grande], falso.


O conjunto vazio está sempre contido em qualquer outro conjunto.


1.4. Análise de uma linha de texto

O programa que se segue é um programa completo, explicado através de comentários ao longo deste. Isto serve para treinar a leitura lógico-formal de um programa em Pascal.



program letras_usadas;
(* Programa que determina quais as letras utilizadas numa linha de texto *)
uses crt;
type cartas = set of char;
var usada, naousada : cartas;  // letras usadas e não usadas
    contador, caractcontador : 0..80;  // contadores
    alfa : char;
    linha : string[80];  // linha de texto, com um máximo de 80 caracteres

procedure ler;
(* Lê uma linha de texto *)
begin
    for contador := 1 to 80 do linha[contador] := ' ';  // “limpa” a linha de texto
    writeln('Introduza uma linha de texto');
    readln(linha);
    caractcontador := length(linha);
    {para o contador de caracteres vai o comprimento da string LINHA.}
end;

procedure mostrar;
(* Mostra a análise realizada *)
begin
    writeln;
    write('Letras utilizadas:');
    for alfa := 'A' to 'z' do  if [alfa] <= usada then write(' ', alfa);
    {Se o caracter ALPHA está contido no conjunto de letras usadas, então escreve-se esse carácter,
      uma vez que é uma letra usada na linha de texto.}
    writeln;
    writeln;
end;

begin  (* Bloco principal *)
    ler;  // lê a primeira linha de texto
    while not (upcase(linha) = 'FIM') do begin  // analisa a linha de texto introduzida
    {termina o programa quando de tiver escrito “FIM”.}
          usada := [];  // define, no início, que nenhuma letra está utilizada
          naousada := ['A'..'Z', 'a'..'z'];  // define, no incício, que todas as letras não foram utilizadas
          for contador := 1 to caractcontador do begin  // analisa a linha de texto, caracter a caracter.
              if [linha[contador]] <= naousada then begin
              {se o conjunto definido pelo caracter nº CONTADOR da linha de texto
                está contido no conjunto das letras não usada, então…}
                  usada += [linha[contador]];  // essa tal letra passa a pertencer ao conjunto das letras usadas…
                  naousada -= [linha[contador]];  // e deixa de pertencer às não usadas.
              end;
          end;
          mostrar;  // mostra o resultado
          ler;  // volta a ler nova linha de texto
    end;
end.


Propostas de Exercícios

12. Crie um programa que analise uma linha de texto e diga ao utilizador quantas e quais as vogais, bem como as consoantes, utilizadas nessa mesma linha, de forma separada.

Normas:

  • Devem ser utilizados conjuntos;
  • Dever-se-á recorrer a um ou mais Record para organizar os vários dados necessários;
  • Limite de linhas de código (exclusive comentários e linhas em branco): livre.



Desafio 6

Existe um método de determinar os números primos de 2 até n conhecido como Crivo de Eratosthenes. O método é o seguinte:

[*]Gerar uma lista ordenada de números inteiros, de 2 até n;

[*]Para um dado número i, da lista, fazê-lo sair da lista e introduzi-lo na de números primos, e, na lista original, eliminar todos os múltiplos de i

[*]Repetir o passo número 2, para cada número sucessivo de i, começando em i=2.

Escreva um programa que utilize este método para determinar os números primos de 2 até n, sendo n um valor dado pelo utilizador. Recorra a conjuntos para resolver este problema.

Normas:

  • Limite de linhas de código (exclusive comentários e linhas em branco): livre


2. Estruturação de um programa em Pascal

Muitas vezes, e regra geral, as bases da estruturação de um programa em pascal são dadas no início. Contudo, eu coloco este método em questão, e deixei-o mais para o fim. Para quê aprender princípios em estruturação se mal se conhece a linguagem e mal se sabe programar em Pascal? Pode-se abordar tal antes de se aprender a linguagem, mas não vai passar de pura teoria. É necessária uma componente prática, penso.

Agora, após as grandes bases sobre Pascal, chega a altura de dar umas noções básicas sobre a boa estruturação de um programa nesta linguagem de programação.

2.1. Estrutura Begin… End

Um procedimento, uma função, uma estrutura de decisão, uma estrutura de repetição e o bloco principal de um programa são todos delimitados pelas palavras Begin e End. Contudo, é possível criar partes de um programa, estruturando-o em blocos individuais, utilizando estas palavras reservadas. Segue-se um exemplo muito simples.



program hello_world;

begin  (* BLOCO PRINCIPAL *)
    begin  (* Bloco de Escrita *)
          writeln('Hello World!');
    end;
    begin  (* Bloco de Pausa *)
          readln;
    end;
end.

Ou seja, podemos criar blocos com uma ou mais linhas de código delimitados por estas duas palavras reservadas.

Estas palavras reservadas não têm de ser obrigatoriamente usadas somente nas situações referidas no início deste subcapítulo.

2.2. A cláusula Exit

Este é um procedimento padrão do Pascal, que permite que o programa saia de um bloco delimitado por Begin e End, sem que tenha de executar as restantes linhas de código. Isto não se aplica à estrutura Begin… End que delimita estruturas de decisão e de repetição, apesar de existirem raros compiladores que aceitem esta cláusula dentro destas estruturas – regra geral, aquando um Exit dentro de uma destas estruturas, e que esta esteja no bloco principal, o programa encerra:



program hello_world;
var i : integer;

begin  (* BLOCO PRINCIPAL *)
    // …
    for i := 1 to 10 do begin
        if i = 4 then exit;
        writeln('Hello World!');
    end;
    // …
end.

Devido ao facto de a estrutura de repetição For estar dentro do Bloco Principal, regra geral, a cláusula Exit obriga o programa a sair do bloco principal, ou seja, encerra-o. Contudo, se este ciclo se encontrasse dentro de um “sub-bloco”, então o programa apenas sairia do ciclo For e continuava no Bloco Principal:



program hello_world;
var i : integer;

begin  (* BLOCO PRINCIPAL *)
    // …
    begin
          for i := 1 to 10 do begin
              if i = 4 then exit;
              writeln('Hello World!');
          end;
    end;
    writeln('Continuando…');
    // …
end.

Neste caso, quando i=4, o programa “saltaria” para fora do ciclo For e recomeçava na linha de código writeln('Continuando…');.

Vejamos, então, um exemplo muito simples da utilização da cláusula Exit:



program hello_world;
uses crt;
var i:integer;

procedure escrever;
(* Bloco de Escrita *)
begin
    if i>=3 then exit;
    writeln('Hello World!');
end;

begin  (* BLOCO PRINCIPAL *)
    for i:=1 to 5 do escrever;
    readln;
end.

O output gerado por este programa é tão-somente o seguinte:


Hello World!

Hello World!


Isto porque, quando i >= 3, é “executada” a cláusula Exit, que obriga o programa a “saltar” do procedimento escrever, não executando a linha de código seguinte, que é a que faz escrever o texto.

2.3. Etiquetas

Assim que surgiu a programação, surgiu a ideia básica de redireccionamento do programa para certos pontos deste, de forma a que o programa não fosse tão-somente linear, mas sim dinâmico. Existem linguagens de programação, hoje em dia em muito arcaicas, como FORTRAN ou BASIC, que utilizam abusivamente deste princípio.

Normalmente, em qualquer linguagem de programação, o programa é redireccionado com a palavra reservada GOTO, obrigando o programa a dirigir-se a um ponto nomeado (com um nome).

O Pascal também suporta este paradigma. Contudo, devido ao facto de possuir estruturas de repetição, estruturas estas que antes não existiam, a utilização de etiquetas torna-se desaconselhada quando a intenção é recorrer a elas de forma abusiva.

Contudo, pode contribuir para parte da boa organização de um programa se utilizada de forma pouca e simples. Por exemplo, pode-se criar, num programa que necessite de Menu, uma Label (i.e., etiqueta) denominada menu, e que evite que TODO o programa esteja dentro de uma estrutura Repeat… Until ou While….

Pegando nesta situação, vamos exemplificar a declaração de uma Label, o seu “posicionamento” no programa e a forma de se lhe aceder a certa altura.



program exemplo;
uses crt;

label menu;

begin  (* bloco principal *)
    // …
    ;menu:  // ponto do programa denominado “menu”: é a etiqueta.
    // …
    goto menu;
    // …
end.

Este é considerado o método universal, pois, regra geral, funciona em qualquer compilador. Há muitos anos atrás houve breves versões do pascal que nem sequer possuía a palavra reservada label, pois bastava colocar a meio do programa, por exemplo, Menu:.

Esta forma de declarar etiquetas cumpre melhor o princípio de “linguagem estruturada” que o Pascal segue, pois tudo é declarado no início, incluindo as etiquetas, de forma a que o computador já esteja “preparado” para todas as situações “que derem e vierem”, falando segundo a gíria popular portuguesa.

NÃO utilizem abusivamente as etiquetas. Dão péssimos hábitos de programação quando utilizadas de tal forma!

2.4. Características desejáveis num programa

Lista das características básicas:

  • Integridade – precisão dos cálculos;
  • Clareza – facilidade da leitura do programa (código-fonte);
  • Simplicidade – o programa deve-se focar no seu objectivo;
  • Eficiência – Velocidade de execução o mais reduzida possível, com resultados exactos, e correcta utilização da memória;
  • Modularidade – programas complexos podem ser decompostos em módulos, sendo eles procedimentos, funções ou simples blocos Begin… End. Deve-se evitar o uso de Labels pois podem criar maus vícios de programação, embora sejam igualmente um método.

3. Data e hora do sistema

Antes de dar por terminada esta introdução ao nível básico sobre a linguagem de programação Pascal, acho pertinente terminar com uma ferramenta que muitos gostam de utilizar para personalizar os seus programas – mostrar qual a data e a hora do sistema onde o programa corre.

Para tal, é necessário declarar variáveis do tipo Word e utilizar a bibliotecas dos, pois, como o nome da biblioteca indica, a obtenção destes dados implica o acesso ao sistema do computador, que não é mais do que uma função que o DOS realiza constantemente.



program relogio_sistema;
uses crt, dos;

var tempo : record
          relogio : record
                  hora : word;
                  minuto : word;
                  segundo : word;
                  centesimo_segundo : word;
          end;
          data : record
              ano : word;
              mes : word;
              dia : word;
              dia_semana : word;
          end;
    end;

begin
    with tempo do begin
          with relogio do begin
              gettime(hora, minuto, segundo, centesimo_segundo);
              // determina a hora do sistema
          end;
          with data do begin
              getdate(ano, mes, dia, dia_semana);
              // determina a data do sistema
          end;
    end;
    // …
end.

Este exemplo explica muito bem por si só como funcionam estes comandos, devido à legibilidade das variáveis utilizadas, e organizadas em Record.

Outra ferramenta a saber é a Delay, que obriga o programa a esperar um determinado tempo, dito em milissegundos, antes de avançar. Vejamos:



// …
write('Pausa de 5 segundos… ');
delay(5000);
// …

Pode ser útil para a construção de um cronómetro muito simples, ou para evitar que o programa encerre imediatamente assim que lhe é ordenado tal, podendo obrigar a janela ficar em “branco” durante, por exemplo, meio segundo – torna o encerrar do programa mais suave e, possivelmente, agradável.

Termina aqui a parte básica do Pascal.

A partir daqui, um principiante deverá ser capaz de desenhar soluções eficientes aos seus problemas, mais simples, claro, recorrendo à linguagem de programação estruturada Pascal.

Está programada a edição de mais partes deste tutorial. Contudo, o tempo volta-me a ser muito limitado, e decidi terminar e editar esta 5ª parte antes de ficar definitivamente “limitado”.

Espero que, até agora, este tutorial tenha sido do vosso agrado.

Esforcei-me para tornar o Pascal simples, recorrendo sempre que possível à simplicidade e a palavras claras, objectivas e concisas, tentando ir contra a linguagem demasiadamente técnica de muitos livros do mercado ou para download.

Atenção!: este tutorial não dispensa a possível e provável consulta de bibliografia extra.

(4ª parte)

(6ª parte)


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Próximas partes

Olá camaradas.

Já recebi uma resposta ao meu pedido de opiniões e sugestões para as próximas partes do tutorial.

Assim, posso-vos garantir que falarei sobre os assuntos que se seguem assim que tiver tempo e disponibilidade, pois são assuntos mais difíceis de serem explicados: necessitarei de muita "genica" para manter a clareza e simplicidade que até agora tentei imprimir neste tutorial.

  • Recursividade;
  • Variáveis Text - Parte 2 - Componente mais prática;
  • Preliminares em variáveis File;
  • Apontadores (pointers) e listas ligadas;
  • Estrutura de tentativa - Try... Except... Finally...;
  • Lista de palavras reservadas, funções e procedimentos padrão;
  • Breve introdução ao Object Pascal - Pascal com OOP.

Espero opiniões vossas, sugestões de temas e exercícios, e afins. :(

Espero que apreciem, já agora, a Parte 5 do tutorial.

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Parte 6

Loucura das loucuras, sentindo-me melhor da febre, meti-me no computador e, quando dei por mim... Parte 6 escrita. Tempo recorde! 😲

Nunca escrevi tanto em tão pouco tempo.

Esta parte é um final (definitivo) da introdução ao Pascal. As partes seguintes (duas, em princípio) serão dos assuntos mais complexos que até eu próprio preciso de (re)estudar com "olhos de ver". :P

Na Parte 6:

  • Recursividade
  • Variáveis Text - parte 2 (última)
  • Estrutura de decisão - Try... Except... Finally...
  • Lista padrão do Pascal

Espero que seja igualmente do vosso agrado. :)

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
nunopicado

Parabéns Thoga... Muito bom trabalho!


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
thoga31

Parabéns Thoga... Muito bom trabalho!

Obrigado, nunopicado :)

Fico feliz por saber que apreciam o meu trabalho. :P

Vou agora mesmo publicar a nova parte.


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Introdução ao Pascal – Parte 6

(5ª parte)

Esta parte vai dar mais uns toques sobre Pascal, abordando a recursividade, uma capacidade muito importante do Pascal, terminar as variáveis Text com um exemplo prático sobre escrita, leitura e análise de ficheiros de texto simples, e a estrutura de tentativa, extremamente importante.

Índice

1. Recursividade

2. Variáveis Text – parte 2

3. Sucessor e predecessor

4. Estrutura de decisão – Try… Except… Finally…

5. Lista padrão do Pascal

    5.1. Palavras reservadas

    5.2. Funções e identificadores padrão

    5.3. Procedimentos padrão

    5.4. Operadores

    5.5. Tipos de dados

    5.6. Tabela ASCII

1. Recursividade

Uma das características mais curiosas e impressionantes do Pascal é o facto de as funções e os procedimentos poderem chamar-se a si mesmos. isto é, para realizar um processo ou um cálculo podem-se chamar a si mesmos para auxiliar ou completar tal acção.

O exemplo mais famoso é, sem dúvida, o do cálculo do factorial de um número. Até agora, colocando um problema destes, utilizar-se-ia quase de certeza uma estrutura de repetição For… Downto… para resolver o problema. Contudo, existe uma forma que, até certa medida, é mais intuitivo. Aplicando-se o postulado matemático de que n! = n * (n-1)!, verifica-se que pode-se utilizar a capacidade da recursividade. Contudo, qualquer estrutura recursiva deve incluir uma estrutura de finalização, que mais não é, geralmente, uma estrutura de decisão If… Then… Else…. Vejamos a resolução do problema do factorial:

program factorial_recursivo;
uses crt;
var numero : integer;  // Só um número inteiro positivo “tem” factorial

function factorial(n : integer) : integer;
(* Função Recursiva *)
begin
     if n<0 then factorial := 0
     // se não é positivo, não há factorial: a função devolve um Integer, logo devolveremos “0”.
     else begin
          if n<=1 then factorial := 1  // Se é 0 ou 1, o factorial é 1 (0! = 1 por postulado matemático)
          else factorial := n * factorial(n-1);  // Restantes casos, aplica a fórmula n! = n * (n-1)!
     end;
end;

begin  (* BLOCO PRINCIPAL *)
     write('Introduza numero inteiro: ');
     readln(numero);
     writeln;
     writeln('O factorial de ', numero, ' e: ', factorial(numero));
     readln;
end.
 

Caso a função fosse tão-somente

function factorial(n : integer) : integer;
begin
     factorial := n * factorial(n-1);  // Restantes casos, aplica a fórmula n! = n * (n-1)!
end;
 

O computador entraria num processo infinito, pois não há nada que lhe indique que o factorial é calculado por n! = n * (n-1) * (n-2) * … * 3 * 2 * 1. O programa iria abaixo quase instantaneamente.

2. Variáveis Text – parte 2

Após terem sido dadas as bases sobre ficheiros de texto simples e outros novos conhecimentos, vamos criar, para terminar este tipo de dado, dois programas distintos: um cria um ficheiro com dados do utilizador, e outro abre o ficheiro, analisa-o, e diz quais esses dados.

Seja o nome do ficheiro, com extensão, dados.txt.

O programa que escreve dados no ficheiro é simples, aplicando os conhecimentos adquiridos na Parte 4, somado aos exemplos.

Neste programa, para distinguir algumas variáveis de constantes, as últimas estarão realçadas com maiúsculas.

program guarda;
(* Programa que guarda dados num ficheiro *)
var fich : text;  // variável TEXT
    dados : record   // Registo de dados
          nome : string[40];
          idade : 0..100;
          sexo : char;
          profissao : string[40];
    end;

const nome_fich = 'dados.txt';  // nome do ficheiro
      SEXOS = ['M', 'F'];   // dois sexos possíveis
      IDADES = [0..100];  // idade aceites

begin (* BLOCO PRINCIPAL *)
     assign(fich, nome_fich);
     rewrite(fich);
     writeln('Ficheiro aberto.');
     writeln;
     writeln('Introduza os seguintes dados...');

     begin (* LEITURA DOS DADOS *)
          with dados do begin
               write('   Nome: '); readln(nome);
               repeat
                     write('   Idade (0-100): '); readln(idade);
               until idade in IDADES;
               repeat
                     write('   Sexo (M/F): '); readln(sexo);
               until upcase(char(sexo)) in SEXOS;
               write('   Profissao: '); readln(profissao);
          end;
     end;

     begin (* GRAVAÇÃO DOS DADOS *)
          with dados do begin
               writeln(fich, 'DADOS');
               writeln(fich, 'Nome: ', nome);
               writeln(fich, 'Idade: ',idade);
               writeln(fich, 'Sexo: ',sexo);
               writeln(fich, 'Profissao: ',profissao);
          end;
     end;
     close(fich);
     writeln;
     write('Dados gravados. Ficheiro encerrado.');
     readln;
end.
 

Como se verifica, o programa lê os dados e só de seguida os grava no ficheiro. Para melhor estruturação, estas duas funções diferentes foram inseridas dentro de blocos Begin… End.

O programa que e analisa os dados é o mais complicado. O método abordado irá permitir entender como ler o ficheiro e obter dele certas informações de forma individualizada. Por exemplo, ao ler no ficheiro Nome: Thoga31, poderá, num outro programa, ser de interesse gravar somente o nome em si, e não a linha de texto toda. Para tal, o programa que se segue, apesar de não utilizar os dados para nada em especial, vai abordar o método geral que permite esta diferenciação. Isto tornar-se-á útil no caso de se criar um programa com opções e, para que o utilizador não esteja sempre a redefini-las, possas definir de uma vez e ficar gravado num ficheiro que é acedido pelo programa para que este se “personalize” conforme as preferências ditadas pelo utilizador numa anterior utilização.

Antes de apresentar o programa, há que saber a função padrão eof: retorna um booleano, e será True quando atinge o fim de um ficheiro.

program analisa;
(* Programa que analisa os dados do ficheiro *)
uses crt;
var fich : text;
    linha : string;  // uma linha do conteúdo do ficheiro
    conteudo : array[1..2] of string;  // diferentes conteúdos do ficheiro:
    // e.g.: "NOME: Thoga31" - conteudo[1] = "NOME:"; conteudo[2] = "Thoga31".
    i, j : integer; // contadores

const nome_fich = 'dados.txt';

begin (* BLOCO PRINCIPAL *)
     assign(fich, nome_fich);
     reset(fich);
     writeln('Ficheiro aberto.');
     writeln;

     while not eof(fich) do begin  (* ANALISA CONTEÚDO *)
     (* Enquanto não chega ao fim do ficheiro de texto FICH... *)
           readln(fich, linha); // lê a presente linha.
           conteudo[1] := ''; // no início, não há conteúdo.
           conteudo[2] := ''; // idem.
           j := 1; // começa pelo conteúdo nº1.
           for i:=1 to length(linha) do begin
           // analisa LINHA, caracter a caracter.
               if linha[i]=' ' then j += 1
               // se é espaço, o conteúdo muda (aumenta 1).
               else begin
                    if j in [1, 2] then conteudo[j] += linha[i];
                    // o array só tem 2 elemento. Logo, se, por erro, j>2, nada é feito;
                    // o caracter lido é adicionado a conteudo[j].
               end;
           end;
           if linha <> 'DADOS' then write('   ');
           // faz "tabulação" aos dados em si, não ao título do ficheiro
           writeln(conteudo[1],' ',conteudo[2]);
     end;

     close(fich);
     writeln;
     write('Ficheiro encerrado.');
     readln;
end.
 

Neste programa, como o ficheiro a analisar tem no máximo um espaço em cada linha (excepto em possível alteração feita fora do programa), definiu-se um array unidimensional com somente dois conteúdos: o conteúdo da linha nº 1 – antes do espaço, e o nº 2 – depois do espaço. Como explicado em comentário, caso o programa leia, por exemplo, Nome: Thoga31, ele irá definir que conteúdo[1] = “Nome:”, que é o texto que está antes do espaço, e conteúdo[2] = “Thoga31”, que é o texto depois do espaço, e que seria o dado de destaque em toda a linha lida.

O método utilizado é exagerado para este caso particular, pois bastava ler a linha e escrevê-la na janela do programa. Contudo, como explicado, este método pretende mostrar ao mesmo tempo como separar exemplarmente o conteúdo de uma linha para fins já exemplificados e referidos.

3. Sucessor e predecessor

Em muitos tipos de dados pode ser definido o conceito de successor e predecessor

  • Sucessor – elemento que se segue;
  • Predecessor – elemento que antecede.

Por exemplo, o predecessor de “C” é “B”, e o sucessor é “D”. O predecessor de “6” é “5”, e o sucessor é “7”.

Os comandos que nos dão o sucessor e o predecessor de um elemento são:

succ(elemento);  // Sucessor
pred(elemento);  // Predecessor
 

4. Estrutura de decisão – Try… Except… Finally…

Aquando a sua origem, o Pascal não fazia estruturas de tentativa. Contudo, com o evoluir do mundo da programação, o Pascal também o teve de fazer, e, hoje em dia, qualquer compilador moderno reconhece e compila a estrutura de tentativa.

Teoricamente, esta estrutura permite que o programa tente realizar uma operação de forma segura, que, de outra forma, poderia criar um erro inesperado e encerrar o programa instantaneamente.

O exemplo típico é o da divisão de um número por zero:


Tentar

      Dividir uma variável por outra

Em erro

      Realizar uma série de acções


Caso a “outra variável” seja zero, a tentativa falha, pois tal não é suportado, pelo que realiza os códigos seguintes. Ou seja, caso as acções a tentar falhem, ocorre uma Excepção (except).

Em Pascal, ainda é suportado o seguinte: independentemente da tentativa falhar ou não, pode-se “acrescentar” algo para além da futura excepção – para este “acrescento” existem várias designações a circular. Contudo, uma boa designação será, porventura, sufixo – o “acrescento” acaba por ser um sufixo (mensagem) da tentativa, quer tenha sucesso quer não.

Para utilizar esta estrutura, é necessária uma nova biblioteca: a sysutils – utilidades do sistema.

Então, a estrutura básica é a seguinte:

try
   comandosA;
except
      comandosB;
end;
 

No caso de se querer fazer o “acrescento” à tentativa:

try
   try
      comandosA;
   finally
          comandosB;
   end;
except
   comandosC;
end;
 

Vejamos a aplicação do exemplo da divisão por zero, onde esta operação se torna obrigatória:

program tentativa;
uses crt, sysutils;
var i, j, resultado : integer;

begin
     i := 5;
     j := 0;  // o denominador vale zero
     write('A tentar dividir, de forma segura, 5 por 0... ');
     try  (* ESTRUTURA DE TENTATIVA *)
        resultado := i DIV j;
        write(resultado);
     except  (* No caso de excepção *)
           ON E:Exception do begin
           // EXCEPTION é um tipo de dado que indica o tipo de erro ocorrido
              writeln('Falhou');
           end;
     end;
     readln;
end.
 

Por exemplo, para aplicarmos aqui a estrutura Finally, podemos indicar ao utilizador que a operação se realizou. Desta vez perguntamos os valores ao utilizador:

program tentativa;
uses crt, sysutils;
var i, j, resultado : integer;

begin
     write('Introduza numerador: '); readln(i);
     write('Introduza denominador: '); readln(j);
     writeln;
     write('A tentar dividir, de forma segura, ',i,' por ',j,'... ');

     try  (* ESTRUTURA DE TENTATIVA *)
        try  // Tentativa com “sufixo”
           resultado := i DIV j;
           write(resultado);
        finally  // …“FINALMENTE” – sufixo
               write(' [Terminado]');
     end;
     except  (* EXCEPÇÃO *)
           ON E:Exception do begin
              write('[Falhou]');
           end;
     end;  (* FIM DA ESTRUTURA *)

     writeln;
     readln;
end.
 

Vejamos dois diferentes outputs (dados do utilizador sublinhados):


 

Introduza numerador: 32

Introduza denominador: 4

A tentar dividir, de forma segura, 32 por 4... 8 [Terminado]



 

Introduza numerador: 375

Introduza denominador: 0

A tentar dividir, de forma segura, 375 por 0...  [Terminado][Falhou]


A estrutura Finally serviu, neste caso, para nos indicar quando a tentativa terminou. Em caso de excepção, mostra a mensagem adicional “Falhou”. Caso tenha sucesso, antes da mensagem “Terminado”, é mostrado o resultado da divisão.

Qualquer processo que seja susceptível de ocorrer um erro pode ser encaixado numa estrutura de tentativa, pois evita sistemas complicados de análise e de segurança: quando ocorre o erro, o programa nada mais faz do que, após ter tentado, anunciar a excepção ocorrida.

Alguns procedimentos padrão já têm “imbuído” em si uma espécie de estrutura de tentativa, como é o caso de val – o terceiro parâmetro, quando declarado, armazena a localização do primeiro erro que não permitiu a conversão de uma string em valor numérico. Este procedimento, por defeito, e quando utilizado o terceiro parâmetro, não necessita de uma estrutura Try… Except.

5. Lista padrão do Pascal

Como qualquer linguagem de programação, existe uma lista padrão dos procedimentos e das funções padrão e das palavras reservadas.

5.1. Palavras reservadas

As palavras reservadas são aquelas que não podem ser redefinidas e fazem os pilares da sintaxe de uma linguagem de programação. Realizam acções e/ou processos bem definidos. A lista que se segue apenas contém as palavras reservadas abordadas até agora – existem outras.

Palavras Reservadas originárias

  • AND
  • ARRAY
  • BEGIN
  • CASE
  • CONST
  • DIV
  • DO
  • DOWNTO
  • ELSE
  • END
  • FOR
  • FUNCTION
  • GOTO
  • IF
  • IN
  • LABEL
  • MOD
  • NOT
  • OF
  • OR
  • PROCEDURE
  • PROGRAM
  • RECORD
  • REPEAT
  • SET
  • STRING
  • THEN
  • TO
  • TYPE
  • UNTIL
  • VAR
  • WHILE
  • WITH

Palavras Reservadas modernas

  • EXCEPT
  • FINALLY
  • TRY

5.2. Funções e identificadores padrão

As funções padrão são aquelas que já estão incluídas nas bibliotecas: algumas pré-existem mesmo sem qualquer biblioteca definida. Algumas destas funções são, de igual forma, identificadores, que são palavras que fazem a identificação, por exemplo, de tipos de dados pré-existentes – por exemplo, char é um identificador do tipo de variável caracter, bem como é a função que devolve o caracter de uma certa ordem na tabela ASCII.

Segue-se a lista com as funções e identificadores:

  • abs
  • arctan
  • boolean
  • char
  • chr (nos compiladores que não suportam char como função, utilizam esta função)
  • cos
  • eof
  • false
  • integer
  • ln
  • maxint*
  • ord
  • pred
  • readln
  • real
  • reset
  • rewrite
  • round
  • sin
  • sqr
  • sqrt
  • succ
  • text
  • true
  • trunc
  • write
  • writeln

É de referir que maxint é o identificador que dá o valor inteiro (Integer) máximo suportado pelo Pascal. Pode ser usado em qualquer altura.

5.3. Procedimentos padrão

O que foi dito sobre as funções padrão aplicam-se aos procedimentos padrão.

  • assign
  • close
  • read
  • readln
  • reset
  • rewrite
  • write
  • writeln

5.4. Operadores

Os operadores têm uma ordem pela qual são executados. Por exemplo, nas quatro operações básicas, a multiplicação e a divisão são executadas antes que a soma e a subtracção.

Segue-se a lista com os operadores ordenados na sua precedência natural, do mais alto (1) para o mais baixo (4):

[*]NOT

[*]* / DIV MOD AND

[*]+ - OR

[*]= <> < <= > >= IN

5.5. Tipos de dados

Um sumário dos tipos de dados abordados até agora:

  • array
  • boolean
  • char
  • integer
  • real
  • record
  • set
  • string

5.6. Tabela ASCII

De computador para computador, a tabela ASCII pode sofrer alterações. Contudo, segue-se uma tabela ASCII completa, geralmente sendo designada por tabela padrão, a mais comum de se ver.

ASCII1.GIF

ascii2.gif

(5ª parte)


Knowledge is free!

Share this post


Link to post
Share on other sites
Colector Boy

Muito boa iniciativa.

Obrigado.

Podias se calhar era criar um pdf com as 6 partes e criavas um índice geral.

Ficava tipo livro.

E podia-se levar para qualquer lado.

Claro que é apenas uma sugestão.

Só não sei se dá para por no pdf o código tão bonito como está aqui no fórum.

:P

Share this post


Link to post
Share on other sites
thoga31

Muito boa iniciativa.

Obrigado.

Podias se calhar era criar um pdf com as 6 partes e criavas um índice geral.

Ficava tipo livro.

E podia-se levar para qualquer lado.

Claro que é apenas uma sugestão.

Só não sei se dá para por no pdf o código tão bonito como está aqui no fórum.

:D

Olá Colector Boy! :P

Claro que é possível colocar tudo num PDF com código bonito. Já experimentei fazê-lo com a Parte 1, quando a publiquei, e ficou tudo certinho: claro que é preciso algum trabalho para que perca a formatação Net e passe a ser Doc. :)

Ando a fazer a compilação das 6 partes num só tópico para ir para o quadro de Tutoriais e, por sugestão de vários users e por proposta recente do staff, vou estudar um pouco o sistema da Wiki para lá colocar. :)

Gostei dessa sugestão, admito :)

Vou necessitar é de tempo para conciliar tudo o que tenho para fazer com este Tutorial :P

Cumprimentos,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites
thoga31

Notícia

Olá, camaradas!

É com gosto que vos dou mais novidades!

  • O tutorial foi actualizado na Parte 4 com um novo capítulo cujo tema eu, admito, me esqueci de referir, que é a aleatoriedade.
  • Mais, estou a compilar todas as 6 partes num só tópico a ser publicado no quadro de Tutoriais.
  • De referir ainda, estou a estudar a formatação da Wiki para adaptar o Tutorial e publicá-lo lá.
  • Também de anunciar ( uffa que não acaba :) ), após a publicação no quadro de Tutoriais, vou adaptá-lo a um pequeno "livro de bolso" em PDF!
  • E estou, por fim, a pensar em, ao mesmo tempo que realizar este último ponto, adaptar igualmente para um artigo para a Revista PROGRAMAR, por proposta do nosso camarada M6 :)

Agradeço o (ténue) apoio que tenho recebido :) (ténue, mas construtivo, incentivando-me a continuar e a melhorar :) )

Agradeço também ao staff que esteve em contacto comigo acerca deste Tutorial e que me deu um novo incentivo para pegar neste tópico e "levá-lo avante". :)

Cumprimentos sinceros,

Thoga31


Knowledge is free!

Share this post


Link to post
Share on other sites

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.