Pascal Essencial |
Capítulo 2 |
Antes que entremos no assunto de escrever instruções em Pascal, é importante destacar alguns elementos de estilo de codificação. A questão à qual me refiro é a seguinte: Além das regras de sintaxe, como você deve escrever o código? Não há uma só resposta para esta pergunta, uma vez que o gosto pessoal pode ditar diferentes estilos. Entretanto, há alguns princípios que você precisa conhecer com relação a comentários, maiúsculas, espacos, e o chamado "pretty-printing". Em geral, o objetivo de qualquer estilo de codificação é a clareza. As decisões que você faz sobre estilo e formatação são uma forma de taquigrafia que indica o propósito de um certo pedaço de código. Uma ferramenta essencial para a clareza é a consistência--qualquer que seja o estilo de sua escolha, certifique-se de segui-lo por todo um projeto.
Em Pascal, os comentários são delimitados ou por chaves ou parênteses seguido de asterisco. O Delphi também aceita os comentários no estilo C++, que se estendem até o fim da linha:
{ isto é um comentário } (* isto é outro comentário *) // isto é um comentário até o fim da linha
A primeira forma é mais curta e mais comumente usada. A segunda forma é preferida na Europa porque muitos teclados europeus não possuem o símbolo da chave. A terceira forma de comentários foi emprestada do C++ e está disponível apenas nas versões 32-bit do Delphi. Comentários até o fim da linha são muito úteis para comentários curtos e para fazer com que o compilador ignore determinada linha de código.
Nas listagens do livro, tentarei marcar os comentários em itálico (e as palavras-chave em negrito), para ser coerente com o syntax highlighting padrão do Delphi.
Ter três formas diferentes de comentário pode ser útil para fazer comentários aninhados. Se você quiser transformar várias linhas de código em comentários, a fim de desabilitá-las, e estas linhas contêm alguns comentários reais, você não pode usar o mesmo identificador de comentário:
{ ... código {comentário que cria problemas...} ... código }
Com um segundo identificador de comentário, você pode escrever o seguinte código, que está correto:
{ ... código //este comentário está OK ... código }
Note que, se a chave de abertura (ou parêntese-asterisco) é seguida por um cifrão ($), o comentário se torna uma diretiva de compilação, como em {$X+}.
Na verdade, diretivas de compilação ainda são comentários. Por exemplo, {$X+ Isto é um comentário} é válido. É, ao mesmo tempo, uma diretiva válida e um comentário, embora programadores sãos provavelmente tendem a separar diretivas de comentários.
O compilador Pascal (ao contrário de outras linguagens) ignora a caixa (forma maiúscula / minúscula) dos caracteres. Logo, os identificadores Meunome, MeuNome, meunome, meuNome, e MEUNOME são todos exatamente equivalentes. No geral, isto é definitivamente um aspecto positivo, já que, em linguagens sensíveis à caixa, muitos erros de sintaxe são causados pelo uso incorreto das maiúsculas e minúsculas.
Nota: Há apenas uma exceção a esta regra da Pascal: o procedimento Register do pacote de um componente tem que iniciar com R maiúsculo, para garantir a compatibilidade com o C++Builder.
Há algumas armadilhas sutis, no entanto: Primeiro, você precisa estar ciente de que estes identificadores são realmente o mesmo, para evitar usá-los como elementos diferentes. Segundo, você precisa tentar ser coerente no uso das maiúsculas, para melhorar a legibilidade do código.
Um uso coerente das maiúsculas não é forçado pelo compilador, mas é um bom hábito para se adquirir. Uma abordagem comum é colocar em miúscula apenas a primeira letra de cada identificador. Quando um identificador é feito de várias palavras consecutivas (não se pode inserir espaços em identificadores), cada inicial de cada palavra deve ser maiúscula:
MeuIdentificadorComprido MeuIdentificadorMuitoCompridoEQuaseEstupido
Outros elementos completamente ignorados pelo compilador são os espaços, saltos de linha e tabulações que se adiciona ao código-fonte. Todos estes elementos são coletivamente conhecidos como espaço em branco. O espaço em branco é usado apenas para melhorar a legibilidade do código, não afetando a compilação.
Diferentemente de BASIC, Pascal permite que se escreva uma instrução em várias linhas de código, separando uma instrução longa em duas ou mais linhas. A desvantagem (ao menos para muitos programadores BASIC) de se permitir instruções divididas em mais de uma linha é que você tem que lembrar de adicionar um ponto-e-vírgula para indicar o fim de uma instrução, ou, mais precisamente, para separar uma instrução da próxima. Note que a única restrição a este recurso é que uma literal de string não pode se estender por múltiplas linhas.
Não há regras fixas quanto ao uso de espaços e instruções em múltiplas linhas; há apenas algumas regras práticas:
A última sugestão quanto ao uso de espaços refere-se ao estilo de formatação típico da linguagem Pascal, conhecido como pretty-printing. Esta regra é simples: Sempre que se precisar escrever uma instrução composta, indente-a em dois espaços à direita do resto da instrução corrente. Uma instrução composta dentro de outra instrução composta é indentada em quatro espaços, e assim por diante:
if ... then instrução; if ... then begin instrução1; instrução2; end; if ... then begin if ... then instrução1; instrução2; end;
A formatação acima é baseada na pretty-printing, mas os programadores têm diferentes interpretações desta regra geral. Alguns programadores indentam as instruções begin e end ao nível do código interno; alguns indentam begin e end e então indentam novamente o código interno; já outros colocam o begin na linha da condição if. Isto é mais uma questão de gosto pessoal.
Um formato de indentação semelhante é constantemente usado para listas de variáveis ou tipos de dados, e para continuar uma instrução de uma linha anterior:
type Letras = set of Char; var Nome: string; begin {Comentário e instrução longos, continuando na linha seguinte, e indentados em dois espaços } MessageDlg ('Isto é uma mensagem', mtInformation, [mbOk], 0);
É claro que quaisquer destas convenções são apenas convenções para tornar o código mais legível para outros programadores, e são completamente ignoradas pelo compilador. Tentei usar esta regra consistentemente em todos os exemplos e fragmentos de código deste livro. Os códigos-fonte, manuais, e exemplos da ajuda do Delphi usam um estilo de formatação semelhante.
Para facilitar a leitura e escrita de código Pascal, o editor do Delphi possui um recurso chamado color syntax highlighting. Dependendo do significado, em Pascal, das palavras que se digita no editor, elas são exibidas em cores diferentes. Por default, as palavras-chave em negrito, strings e comentários são coloridos (e geralmente em itálico), e assim por diante.
As palavras reservadas, comentários e strings são provavelmente os três elementos que mais se beneficiam deste recurso. Pode-se ver, em uma olhada rápida, uma palavra-chave escrita incorretamente, uma string não terminada, e a extensão de um comentário de múltiplas linhas.
Você pode facilmente personalizar as configurações de syntax highlight, usando a página Editor Colors da caixa de diálogo Environment Options (ver Figura 2.1). Se você trabalha sozinho, escolha as cores que preferir. Se você trabalha em conjunto com outros programadores, todos devem concordar em um esquema de cores padrão. Eu acho que trabalhar em um computador com uma coloração de sintaxe diferente da que estou acostumado é realmente difícil.
FIGURA 2.1: A caixa de diálogo usada para configurar o syntax highlighting.
Nota: Neste livro, eu tentei aplicar uma espécie de syntax highlighting às listagens de código-fonte. Espero que isto as torne mais legíveis.
O Delphi 3 introduziu uma nova característica, no que diz respeito à edição de código-fonte. Devido ao fato de ter de repetir constantemente a mesma seqüência de palavras-chave ao escrever código em Pascal, a Borland resolveu criar uma nova ferramenta chamada "modelos de código" (Code Templates). Um modelo de código é simplesmente um pedaço de código relacionado a uma forma abreviada. Você digita a abreviação, tecla Ctrl+J, e o código completo aparece. Por exemplo: se você digitar arrayd, e pressionar Ctrl+J, o editor do Delphi irá expandir seu texto para:
array [0..] of ;
Já que os modelos de código predefinidos geralmente possuem diversas versões da mesma construção, a abreviação geralmente termina com uma letra que indica a versão. Entretanto, também se pode digitar apenas a parte inicial da abreviação. Por exemplo: se você digitar ar e pressionar Ctrl+J, o editor mostrará um menu local com uma lista das escolhas disponíveis, com uma curta descrição, como se pode ver na Figura 2.2.
Figura 2.2: Seleção de modelos de código
Você pode personalizar completamente os modelos de código, seja pela modificação dos existentes, ou pela adição de seus próprios pedaços de código. se fizer isto, lembre-se que o texto de um modelo de código geralmente inclui o caractere '|', para indicar a posição para onde o cursor deve saltar após a operação; isto é, onde você começa a digitar para completar o código.
Uma vez que tenha definido alguns identificadores, você pode usá-los em instruções e nas expresões que são parte de algumas instruções. Pascal oferece diversas instruções e expressões. Vejamos as palavras-chave, expresões e operadores, primeiramente.
Palavras-chave são todos os identificadores reservados do Object Pascal; elas desempenham um papel central na linguagem. A ajuda do Delphi distingue "palavras reservadas" e "diretivas": as palavras reservadas não podem ser usedas como identificadores, enquanto as diretivas não devem ser usadas como tais, mesmo que o compilador as aceite. Na prática, você não deve usar nehuma palavra-chave como identificador.
Na tabela 2.1 você pode ver uma lista completa dos identificadores que têm um significado especial na linguagem Object Pascal (do Delphi 4), inclusive palavras-chave e outras palavras reservadas.
Tabela 2.1: Palavras-chave e outras palavras reservadas na linguagem Object Pascal
Palavra-chave | Papel |
---|---|
absolute | diretiva (variáveis) |
abstract | diretiva (métodos) |
and | operador (booleano) |
array | tipo |
as | operador (RTTI) |
asm | instrução |
assembler | compatibilidade retroativa (asm) |
at | instrução (exceções) |
automated | especificador de acesso (classe) |
begin | marcador de bloco |
case | instrução |
cdecl | convenção de chamada de função |
class | tipo |
const | declaração ou diretiva (parâmetros) |
constructor | método especial |
contains | operador (conjunto) |
default | diretiva (propriedade) |
destructor | método especial |
dispid | especificador de interface |
dispinterface | tipo |
div | operador |
do | instrução |
downto | instrução (parte do for) |
dynamic | diretiva (método) |
else | instrução (parte do if ou case) |
end | marcador de bloco |
except | instrução (exceções) |
export | compatibilidade retroativa (classe) |
exports | declaração |
external | diretiva (funções) |
far | compatibilidade retroativa (classe) |
file | tipo |
finalization | estrutura de unidade |
finally | instrução (exceções) |
for | instrução |
forward | diretiva de função |
function | declaração |
goto | instrução |
if | instrução |
implementation | estrutura de unidade |
implements | diretiva (propriedade) |
in | operador (conjunto) - estrutura de projeto |
index | diretiva (interface) |
inherited | instrução |
initialization | estrutura de unidade |
inline | compatibilidade retroativa (ver asm) |
interface | tipo |
is | operador (RTTI) |
label | declaração |
library | estrutura de programa |
message | diretiva (método) |
mod | operador (matemático) |
name | diretiva (função) |
near | compatibilidade retroativa (classe) |
nil | valor |
nodefault | diretiva (propriedade) |
not | operador (booleano) |
object | compatibilidade retroativa (classe) |
of | instrução (parte do case) |
on | instrução (exceções) |
or | operador (booleano) |
out | diretiva (parâmetros) |
overload | diretiva de função |
override | diretiva de função |
package | estrutura de programa (pacote) |
packed | diretiva (registro) |
pascal | convenção de chamada de função |
private | especificador de acesso (classe) |
procedure | declaração |
program | estrutura de programa |
property | declaração |
protected | especificador de acesso (classe) |
public | especificador de acesso (classe) |
published | especificador de acesso (classe) |
raise | instrução (exceções) |
read | especificador de propriedade |
readonly | especificador de interface |
record | tipo |
register | convenção de chamada de função |
reintroduce | diretiva de função |
repeat | instrução |
requires | estrutura de programa (pacote) |
resident | diretiva (funções) |
resourcestring | tipo |
safecall | convenção de chamada de função |
set | tipo |
shl | operador (matemático) |
shr | operador (matemático) |
stdcall | convenção de chamada de função |
stored | diretiva (propriedade) |
string | tipo |
then | instrução (parte do if) |
threadvar | declaração |
to | instrução (parte do for) |
try | instrução (exceções) |
type | declaração |
unit | estrutura de unidade |
until | instrução |
uses | estrutura de unidade |
var | declaração |
virtual | diretiva (método) |
while | instrução |
with | instrução |
write | especificador de propriedade |
writeonly | especificador de interface |
xor | operador (booleano) |
Não há uma regra geral para construir expressões, já que elas dependem principalmente dos operadores usados, e Pascal possui vários operadores. Há operadores lógicos, aritméticos, booleanos, relacionais e de conjuntos, mais alguns outros. As expressões podem ser usadas para determinar o valor a atribuir a uma variável, para computar o parâmetro de uma função ou procedimento, ou para testar uma condição. As expressões também podem conter chamadas de funções. Sempre que se executa uma operação sobre o valor de um identificador, ao invés de utilizar o próprio identificador, está-se escrevendo uma expressão.
Expressões são comuns à maioria das linguagens de programação. Uma expressão é qualquer combinação válida de constantes, variáveis, valores literais, operadores, e resultados de funções. As expressões também podem ser passadas para parâmetros de valor de procedimentos e funções, mas nem sempre para parâmetros de referência (que requerem um valor que possa ser atribuído).
Se você já escreveu algum programa em sua vida, você já sabe o que é uma expressão. Aqui, destacarei elementos específicos dos operadores Pascal. Você pode ver uma lista dos operadores da linguagem, agrupados por precedência, na Tabela 2.1.
Em Pascal, ao contrário da maioria das linguagens de programação, os operadores and e or têm precedência sobre os operadores relacionais. Assim, se você escrever a < b and c < d, o compilador tentará resolver a operação and primeiro, resultando em um erro de compilação.
Por esta razão, sempre se deve colocar cada expressão relacional entre parênteses: (a < b) and (c < d).
Alguns dos operadores comuns têm diferentes significados com diferentes tipos de dados. Por exemplo: o operador + pode ser usado para somar dois números, concatenar duas strings, fazer a união de dois conjuntos, e até mesmo adicionar um deslocamento a um ponteiro PChar. Entretanto, não se pode somar dois caracteres, como é possível em C.
Outro operador estranho é div. Em Pascal, pode-se dividir quaisquer dois números (reais ou inteiros) com o operador /, resultando, invariavelmente, em um número real. Caso se precise dividir dois inteiros, obtendo um resultado inteiro, deve-se usar o operador div.
Tabela 2.2: Operadores da Linguagem Pascal, Agrupados por Precedência
Operadores Unários (Precedência mais Alta) | |
---|---|
@ | Endereço de variável ou função (retorna um ponteiro) |
not | Não booleano ou bit-a-bit |
Operadores Multiplicativos e de Operações Bit-a-Bit | |
* | Multiplicação aritmética ou interseção de conjuntos |
/ | Divisão de ponto flutuante |
div | Divisão inteira |
mod | Resto da divisão inteira |
as | Coerção de tipo segura (RTTI) |
and | E booleano ou bit-a-bit |
shl | Deslocamento bit-a-bit à esquerda |
shr | Deslocamento bit-a-bit à direita |
Operadores Aditivos | |
+ | Adição aritmética, união de conjuntos, concatenação de strings, adição de deslocamento de ponteiros |
- | Subtração aritmética, diferença de conjuntos, subtração de deslocamento de ponteiros |
or | Ou booleano ou bit-a-bit |
xor | Ou Exclusivo booleano ou bit-a-bit |
Operadores Relacionais (Precedência mais Baixa) | |
= | Teste de igualdade |
<> | Teste de desigualdade |
< | Testa se é menor que |
> | Testa se é maior que |
<= | Testa se é menor ou igual a, ou se é subconjunto de um conjunto |
>= | Testa se é maior ou igual a, ou se é superconjunto de um conjunto |
in | Testa se o item pertence a um conjunto |
is | Testa se o objeto é de tipo compatível (outro operador RTTI) |
Os operadores de conjunto incluem: união (+), diferença (-), interseção (*), pertinência (in), e mais alguns operadores relacionais. Para adicionar um elemento a um conjunto, pode-se fazer a união do conjunto com outro que possua apenas o elemento necessário. Aqui está um exemplo do Delphi, relacionado a estilos de fonte:
Style := Style + [fsBold]; Style := Style + [fsBold, fsItalic] - [fsUnderline];
Alternativamente, pode-se usar os procedimentos padrão Include e Exclude, que são muito mais eficientes (mas não podem ser usados em propriedades de componentes do tipo conjunto, porque requerem um parâmetro de valor):
Include (Style, fsBold);
Agora que sabemos o lay-out básico de um programa Pascal, estamos prontos para começar a entender seu significado em detalhes. Começaremos explorando a definição de tipos de dados predefinidos e definidos pelo usuário, para então estudar o uso de palavras-chave na formação de instruções de programação.
© Copyright Marco Cantù, Wintech Italia Srl 1995-99