Está en la página 1de 25

Variaveis de Memoria

Blocos de Codigo
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Blocos de cdigo so um conceito existente h muito tempo em linguagens xBase. No
como algo que apareceu da noite para o dia, e sim uma evoluo progressiva utilizando
a combinao de muitos conceitos da linguagem para a sua implementao.
Um Primeiro Lembrete
O AdvPl uma linguagem baseada em funes. Funes tm um valor de retorno.
Assim como o operador de atribuio :=.
Assim, ao invs de escrever:
x := 10 // Atribui o valor 10 varivel chamada X
Alert("Valor de x: " + cValToChar(x))
Pode-se escrever:
// Atribui e ento exibe o valor da varivel X
Alert("Valor de x: " + cValtoChar(X := 10))
A expresso x:=10 avaliada primeiro, e ento seu resultado (o valor de X, que agora
10) passada para a funo cvaltochar para a converso para caracter, e em seguida
para a funo alert para a exibio. Por causa desta regra de precedncia possvel
atribuir um valor a mais de uma varavel ao mesmo tempo:
Z := Y := X := 0
Por causa dessa regra, essa expresso avaliada como se fosse escrita assim:
Z := ( Y := (X := 0) )
Apesar do AdvPl avaliar expresses da esquerda para a direita, no caso de atribuies
isso acontece ao contrrio, da direita para a esquerda. O valor atribudo varivel X,
que retorna o valor para ser atribudo varivel Y e assim sucessivamente. Pode-se
dizer que o zero foi "propagado atravs da expresso".
Outro Lembrete
Em AdvPl pode-se juntar diversas linhas de cdigo em uma nica linha fscia do
arquivo. Por exemplo, o cdigo:
If lAchou
Alert("Cliente encontrado!")
Endif
pode ser escrito assim:
If lAchou ; Alert("Cliente encontrado!") ; Endif
O ponto-e-vrgula indica ao AdvPl que a nova linha de cdigo est para comear. Pode-
se ento colocar diversas linhas lgicas de cdigo na mesma linha fsica atravs do
editor de texto utilizado.
Apesar da possibilidade de se escrever todo o programa assim, em uma nica linha
fsica, isto no recomendado pois dificulta a legibilidade do programa e,
conseqentemente, a manuteno.
Lista de Expresses
A evoluo dos blocos de cdigo comea com as listas de expresses. Nos exemplos a
seguir, o smbolo ==> indicar o retorno da expresso aps sua avaliao (seja para
atribuir em uma varivel, exibir para o usurio ou imprimir em um relatrio), que ser
impresso em um relatrio por exemplo.
Duas Linhas de Cdigo
@00,00 PSAY x := 10 ==> 10
@00,00 PSAY y := 20 ==> 20
Cada uma das linhas ter a expresso avaliada, e o valor da varivel ser ento
impresso.
Duas Linha de Cdigo em Uma , Utilizando Ponto-e-Vrgula
Este o mesmo cdigo que o anterior, apenas escrito em uma nica linha:
Alert( cValToChar( x := 10 ; y := 20 ) ) ==> 10
Apesar desse cdigo se encontrar em uma nica linha fsica, existem duas linhas lgicas
separadas pelo ponto e vrgula. Ou seja, esse cdigo equivalente a:
Alert( cValToChar( x := 10 ) )
y := 20
Portanto apenas o valor 10 da varivel x ser passado para as funes cvaltochar e alert
para ser exibido. E o valor 20 apenas ser atribudo varivel y.
Convertendo para uma Lista de Expresses
Quando parnteses so colocados ao redor do cdigo e o sinal de ponto-e-vrgula
substitudo por uma vrgula apenas, o cdigo torna-se uma lista de expresses:
Alert( cValToChar ( ( X := 10 , Y := 20 ) ) ) ==> 20
O valor de retorno resultante de uma lista de expresses o valor resultante da ltima
expresso ou elemento da lista. Funciona como se fosse um pequeno programa ou
funo, que retorna o resultado de sua ltima avaliao (efetuadas da esquerda para a
direita).
Neste exemplo, a expresso x := 10 avaliada, e ento a expresso y := 20, cujo valor
resultante passado para a funo alert e cvaltochar, e ento exibido. Depois que essa
linha de cdigo executada, o valor de X igual a 10 e o de y igual a 20, e 20 ser
exibido.
Teoricamente, no h limitao para o nmero de expresses que podem ser
combinadas em uma lista de expresses. Na prtica, o nmero mximo por volta de
500 smbolos.
Debugar listas de expresses difcil oprque as expresses no esto divididas em
linhas de cdigo fonte, o que torna todas as expresses associadas a uma mesma linha
de cdigo. Isto pode tornar muito difcil determinar onde um erro ocorreu.
Onde Pode-se Utilizar uma Lista de Expresses?
O propsito principal de uma lista de expresses agrup-las em uma nica unidade.
Em qualquer lugar do cdigo AdvPl que uma expresso simples pode ser utilizada,
pode-se utilizar uma lista de expresses. E ainda, pode-se fazer com que vrias coisas
aconteam onde normalmente apenas uma aconteceria.
X := 10 ; Y := 20
If X > Y
Alert("X")
Z := 1
Else
Alert("Y")
Z := -1
Endif
Aqui temos o mesmo conceito, escrito utilizando listas de expresses na funo iif:
X := 10 ; Y := 20
iif( X > Y , ;
( Alert("X"), Z := 1 ) , ;
( Alert("Y"), Z := -1 ) )
De Listas de Expresses para Blocos de Cdigo
Considere a seguinte lista de expresses:
Alert( cValToChar( ( x := 10, y := 20 ) ) ) ==> 20
O AdvPl permite criar funes, que so pequenos pedaos de cdigo, como se fosse um
pequeno programa, utilizados para diminuir partes de tarefas mais complexas e
reaproveitar cdigo em mais de um lugar num programa. Para maiores detalhes consulte
a documentao sobre a criao de funes em AdvPl. Porm, a idia neste momento
que a lista de expresses utilizada na linha anterior pode ser criada como uma funo:
Function Lista()
X := 10
Y := 20
Return Y
E a linha de exemplo com a lista de expresses pode ser substituda, tendo o mesmo
resultado, por:
Alert( cValToChar( Lista() ) ) ==> 20
Como mencionado anteriormente, uma lista de expresses como um pequeno
programa ou funo. Com poucas mudanas, uma lista de expresses pode se tornar um
bloco de cdigo:
( X := 10 , Y := 20 ) // Lista de Expresses
{|| X := 10 , Y := 20 } // Bloco de Cdigo
Note as chaves {} utilizadas no bloco de cdigo. Ou seja, um bloco de cdigo uma
matriz. Porm na verdade, no uma lista de dados, e sim uma lista de comandos, uma
lista de cdigo.
// Isto uma matriz de dados
A := {10, 20, 30}
// Isto um bloco de cdigo, porm funciona como
// se fosse uma matriz de comandos
B := {|| x := 10, y := 20}
Executando um Bloco de Cdigo
Diferentemente de uma matriz, no se pode acessar elementos de um bloco de cdigo
atravs de um ndice numrico. Porm blocos de cdigo so semelhantes a uma lista de
expresses, e a uma pequena funo. Ou seja, podem ser executados. Para a execuo,
ou avaliao, de um bloco de cdigo, deve-se utilizar a funo eval:
nRes := Eval(B) ==> 20
Essa funo recebe como parmero um bloco de cdigo e avalias todas as expresses
contidas neste bloco de cdigo, retornando o resultado da ltima expresso avaliada.
Passando Parmetros
J que blocos de cdigo so como pequenas funes, tambm possvel a passagem de
parmetros para um bloco de cdigo. Os parmetros devem ser informados entre as
barras verticais (||) separados por vrgulas, assim como em uma funo.
B := {| N | X := 10, Y := 20 + N}
Porm deve-se notar que j que o bloco de cdigo recebe um parmetro, um valor deve
ser passado quando o bloco de cdigo for avaliado.
C := Eval(B, 1) ==> 21
Utilizando Blocos de Cdigo
Blocos de cdigo podem ser utilizados em diversas situaes. Geralmente so utilizados
para executar tarefas quando eventos de objetos so acionados ou para modificar o
comportamento padro de algumas funes.
Por exemplo, considere a matriz abaixo:
A := {"GARY HALL", "FRED SMITH", "TIM JONES"}
Esta matriz pode ser ordenada pelo primeiro nome, utilizando-se a chamada da funo
asort(A), resultado na matriz com os elementos ordenados dessa forma:
{"FRED SMITH", "GARY HALL", "TIM JONES"}
A ordem padro para a funo asort ascendente. Este comportamento pode ser
modificado atravs da informao de um bloco de cdigo que ordena a matriz de forma
descendente:
B := { |X, Y| X > Y }
aSort(A, B)
O bloco de cdigo (de acordo com a documentao da funo asort) deve ser escrito
para aceitar dois parmetros que so os dois elementos da matriz para comparao. Note
que o bloco de cdigo no conhece que elementos est comparando - a funo asort
seleciona os elementos (talvez utilizando o algortmo QuickSort) e passa-os para o
bloco de cdigo. O bloco de cdigo compara-os e retorna verdadeiro (.T.) se se
encontram na ordem correta, ou falso (.F.) se no. Se o valor de retorno for falso, a
funo asort ir ento trocar os valores de lugar e seguir comparando o prximo par de
valores.
Ento, no bloco de cdigo anterior, a comparao X > Y verdadeira se os elementos
esto em ordem descendente, o que significa que o primeiro valor maior que o
segundo.
Para ordenar a mesma matriz pelo ltimo nome, tambm em ordem descendente, pode-
se utilizar o seguinte bloco de cdigo:
B := { |X, Y| Substr(X,At(" ",X)+1) > Substr(Y,At(" ",Y)+1) }
Note que este bloco de cdigo procura e compara as partes dos caracteres
imediatamente seguinte a um espao em branco. Depois de utilizar esse bloco de cdigo
para a funo asort, a matriz conter:
{"GARY HALL", "TIM JONES", "FRED SMITH"}
Finalmente, para ordenar um sub-elemento (coluna) de uma matriz por exemplo, pode-
se utilizar o seguinte bloco de cdigo:
B := { |X, Y| X[1] > Y[1] }
Criaco e Atribuico de Variaveis
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Variveis de memria so um dos recursos mais importantes de uma linguagem. So
reas de memria criadas para armazenar informaes utilizadas por um programa para
a execuo de tarefas. Por exemplo, quando o usurio digita uma informao qualquer,
como o nome de um produto, em uma tela de um programa esta informao
armazenada em uma varivel de memria para posteriormente ser gravada ou impressa.
A partir do momento que uma varivel criada, no necessrio mais se referenciar ao
seu contedo, e sim ao seu nome. O nome de uma varivel um identificador nico que
segue duas regras regras:
Mximo de 10 caracteres. O AdvPl no impede a criao de uma varivel de memria
cujo nome contenha mais de 10 caracteres, porm apenas os 10 primeiros sero
considerados para a localizao do contedo armazenado. Portanto se forem criadas
duas variveis cujos 10 primeiros caracteres forem iguais, como nTotalGeralAnual e
nTotalGeralMensal, as referncias a qualquer uma delas no programa resultaro o
mesmo. Ou seja, sero a mesma varivel:
nTotalGeralMensal := 100
nTotalGeralAnual := 300
Alert("Valor mensal: " + cValToChar(nTotalGeralMensal))
Quando o contedo da varivel nTotalGeralMensal exibido, o seu valor ser de 300.
Isso acontece porque no momento que esse valor foi atribuido varivel
nTotalGeralAnual, o AdvPl considerou apenas os 10 primeiros caracteres (assim como
o faz quando deve exibir o valor da varivel nTotalGeralMensal), ou seja, considerou-as
como a mesma varivel. Assim o valor original de 100 foi substituido pelo de 300.
Limitao de caracteres no nome. Os nomes das variveis devem sempre comear por
uma letra ou o caracter de sublinhado ( _ ). No restante, pode conter letras, nmeros e o
caracter de sublinhado. Qualquer outro caracter, incluindo espaos em branco, no so
permitidos.
O AdvPl permite a criao ilimitada de variveis, dependendo apenas da memria
disponvel. A seguir esto alguns nomes vlidos para variveis:
TOT01
cNumero
VAR_QUALQUER
M_CARGO
A11
E alguns invlidos:
1CODIGO (Inicia por um nmero)
M CARGO (contm um espao em branco)
LOCAL (palavra reservada do AdvPl)
O AdvPl no uma linguagem de tipos rgidos para variveis, ou seja, no necessrio
informar o tipo de dados que determinada varivel ir conter no momento de sua
declarao, e o seu valor pode mudar durante a execuo do programa. Tambm no h
necessidade de declarar variveis em uma seo especfica do seu cdigo fonte, embora
seja aconselhvel declarar todas as variveis necessrias no comeo, tornando a
manuteno mais fcil e evitando a declarao de variveis desnecessrias.
Para declarar uma varivel deve-se utilizar um identificador de escopo, seguido de uma
lista de variveis separadas por vrgula (,). Um identificador de escopo uma palavra
chave que indica a que contexto do programa a varivel declarada pertence. O contexto
de variveis pode ser local (visualizadas apenas dentro do programa atual), pblico
(visualizadas por qualquer outro programa), entre outros. Os diferentes tipos de
contexto de variveis so explicados na documentao sobre escopo de variveis.
Considere as linhas de cdigo de exemplo:
nResultado := 250 * (1 + (nPercentual / 100))
Se esta linha for executada em um programa AdvPl, ocorrer um erro de execuo com
a mensagem "variable does not exist: nPercentual", pois esta varivel est sendo
utilizada em uma expresso de clculo sem ter sido declarada. Para solucionar este erro,
deve-se declarar a varivel previamente:
Local nPercentual, nResultado
nResultado := 250 * (1 + (nPercentual / 100))
Neste exemplo, as variveis so declaradas previamente utilizando o identificador de
escopo local. Quando a linha de clculo for executada, o erro de varivel no existente
no mais ocorrer. Porm variveis no inicializadas tm sempre o valor default nulo
(Nil) e este valor no pode ser utilizado em um clculo pois tambm gerar erros de
execuo (nulo no pode ser dividido por 100). A resoluo deste problema efetuada
inicializando-se a varivel atravs de uma das formas:
Local nPercentual,nResultado
Store 10 To nPercentual
nResultado := 250 * (1 + (nPercentual / 100))
ou
Local nPercentual, nResultado
nPercentual := 10
nResultado := 250 * (1 + (nPercentual / 100))
ou
Local nPercentual := 10, nResultado
nResultado := 250 * (1 + (nPercentual / 100))
A diferena entre o ltimo exemplo e os dois anteriores que a varivel inicializada
no momento da declarao. Nos dois primeiros exemplos, a varivel primeiro
declarada e ento inicializada em uma outra linha de cdigo. O comando store existe
apenas por compatibilidade com verses anteriores e outras linguagens xBase, mas
obsoleto. Deve-se utilizar o operador de atribuio (:= ou somente =). aconselhvel
optar pelo operador de atribuio composto de dois pontos e sinal de igual, pois o
operador de atribuio utilizando somente o sinal de igual pode ser facilmente
confundido com o operador relacional (para comparao) durante a criao do
programa.
Uma vez que um valor lhe seja atribudo, o tipo de dado de uma varivel igual ao tipo
de dado do valor atribudo. Ou seja, uma varivel passa a ser numrica se um nmero
lhe atribudo, passa a ser caracter se uma string de texto lhe for atribuda, etc. Porm
mesmo que uma varivel seja de determinado tipo de dado, pode-se mudar o tipo da
varivel atribuindo outro tipo a ela:
01 Local xVariavel // Declara a varivel inicialmente com valor nulo
02
03 xVariavel := "Agora a varivel caracter..."
04 Alert("Valor do Texto: " + xVariavel)
05
06 xVariavel := 22 // Agora a varivel numrica
07 Alert(cValToChar(xVariavel))
08
09 xVariavel := .T. // Agora a varivel lgica
10 If xVariavel
11 Alert("A varivel tem valor verdadeiro...")
12 Else
13 Alert("A varivel tem valor falso...")
14 Endif
15
16 xVariavel := Date() // Agora a varivel data
17 Alert("Hoje : " + DtoC(xVariavel))
18
19 xVariavel := nil // Nulo novamente
20 Alert("Valor nulo: " + xVariavel)
21
22 Return
No programa de exemplo anterior, a varivel xVariavel utilizada para armazenar
diversos tipos de dados. A letra "x" em minsculo no comeo do nome utilizada para
indicar uma varivel que pode conter diversos tipos de dados, segundo a Notao
Hngara (consulte documentao especfica para detalhes). Este programa troca os
valores da varivel e exibe seu contedo para o usurio atravs da funo alert. Essa
funo recebe um parmetro que deve ser do tipo string de caracter, por isso
dependendo do tipo de dado da varivel xVariavel necessrio fazer uma converso
antes.
Apesar dessa flexibilidade de utilizao de variveis, deve-se tomar cuidados na
passagem de parmetros para funes ou comandos, e na concatenao (ou soma) de
valores. Note a linha 20 do programa de exemplo. Quando esta linha executada, a
varivel xVariavel contem o valor nulo. A tentativa de soma de tipos de dados
diferentes gera erro de execuo do programa. Nesta linha do exemplo, ocorrer um
erro com a mensagem "type mismatch on +". Excetuando-se o caso do valor nulo, para
os demais deve-se sempre utilizar funes de converso quando necessita-se concatenar
tipos de dados diferentes (por exemplo, nas linhas 07 e 17.
Note tambm que quando uma varivel do tipo de dado lgico, ela pode ser utilizada
diretamente para checagem (linha 10):
If xVariavel
o mesmo que
If xVariavel = .T.
A declarao de variveis para os demais tipos de dados, matrizes e blocos de cdigo,
exatamente igual ao descrito at agora. Apenas existem algumas diferenas quanto a
inicializao, que podem ser consultadas na documentao de inicializao de matrizes
e blocos de cdigo.
Diferenciaco entre variaveis e nomes de
campos
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Muitas vezes uma varivel pode ter o mesmo nome que um campo de um arquivo ou
tabela aberto no momento. Neste caso, o AdvPl privilegiar o campo. Assim uma
referncia a um nome que identifique tanto uma varivel como um campo, resultar no
contedo do campo.
Para especificar qual deve ser o elemento referenciado, deve-se utilizar o operador de
identificao de apelido (->) e um dos dois identificadores de referncia, MEMVAR ou
FIELD.
cRes := MEMVAR->NOME
Esta linha de comando identifica que o valor atribudo varivel cRes deve ser o valor
da varivel de memria chamada NOME.
cRes := FIELD->NOME
Neste caso, o valor atribudo varivel cRes ser o valor do campo NOME existente no
arquivo ou tabela aberto na rea atual.
O identificador FIELD pode ser substitudo pelo apelido de um arquivo ou tabela
aberto, para evitar a necessidade de selecionar a rea antes de acessar o contedo de
terminado campo.
cRes := CLIENTES->NOME
Para maiores detalhes sobre abertura de arquivos com atribuio de apelidos, consulte a
documentao sobre acesso a banco de dados ou a documentao da funo dbUseArea.
Inicializando Matrizes
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Algumas vezes o tamanho da matriz conhecido previamente. Outras vezes o tamanho
da matriz s ser conhecido em tempo de execuo.
Se o tamanho da matriz conhecido
Se o tamanho da matriz conhecido no momento que o programa escrito, h diversas
maneiras de implementar o cdigo.
01 Local nCnt
02 Local aX[10]
03 Local aY := Array(10)
04 Local aZ := {0,0,0,0,0,0,0,0,0,0}
05
06 For nCnt := 1 To 10
07 aX[nCnt] := nCnt * nCnt
08 Next nCnt
Este cdigo preenche a matriz com uma tabela de quadrados. Os valores sero 1, 4, 9,
16 ... 81, 100. Note que a linha 07 se refere varivel aX, mas poderia tambm
trabalhar com aY ou aZ. O objetivo deste exemplo demonstrar trs modos de criar
uma matriz de tamanho conhecido no momento da criao do cdigo.
Na linha 02 a matriz criada usando aX[10]. Isto indica ao AdvPl para alocar espao
para 10 elementos na matriz. Os colchetes [ e ] so utilizados para indicar o tamanho
necessrio.
Na linha 03 utilizada a funo array com o parmetro 10 para criar a matriz, e o
retorno desta funo atribudo varivel aY.
Na linha 03 efetuado o que se chama "desenhar a imagen da matriz". Como pode-se
notar, existem dez 0s na lista encerrada entre chaves ({}). Claramente, este mtodo no
o utilizado para criar uma matriz de 1000 elementos. O terceiro mtodo difere dos
anteriores porque inicializa a matriz com os valores definitivos. Nos dois primeiros
mtodos, cada posio da matriz contm um valor nulo (Nil) e deve ser inicializado
posteriormente.
A linha 07 demonstra como um valor pode ser atribudo para uma posio existente em
uma matriz especificando o ndice entre colchetes.
Se o tamanho da matriz no conhecido
Se o tamanho da matriz no conhecido at o momento da execuo do programa, h
algumas maneiras de criar uma matriz e adicionar elementos a ela. O exemplo a seguir
ilustra a idia de criao de uma matriz vazia (sem nenhum elemento) e adio de
elementos dinamicamente.
01 Local nCnt
02 Local aX[0]
03 Local aY := Array(0)
04 Local aZ := {}
05
06 For nCnt := 1 To nSize
07 aAdd(aX,nCnt*nCnt)
08 Next nCnt
A linha 02 utiliza os colchetes para criar uma matriz vazia. Apesar de no ter nenhum
elemento, seu tipo de dado matriz.
Na linha 03 a chamada da funo array cria uma matriz sem nenhum elemento.
Na linha 04 est declarada a representao de uma matriz vazia em AdvPl. Mais uma
vez, esto sendo utilizadas as chaves para indicar que o tipo de dados da varivel
matriz. Note que {} uma matriz vazia (tem o tamanho 0), enquanto {Nil} uma
matriz com um nico elemento nulo (tem tamanho 1).
Porque cada uma destas matrizes no contem elementos, a linha 07 utiliza a funo aadd
para adicionar elementos sucessivamente at o tamanho necessrio (especificado por
exemplo na varivel nSize).
Matrizes
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10
Matrizes, ou arrays, so colees de valores. Ou, de uma maneira mais fcil de
entender, uma lista. Uma matriz pode ser criada atravs de diferentes maneiras.
Consulte a documentao sobre Inicializao de Matrizes para maiores detalhes.
Cada item em uma matriz referenciado pela indicao de sua posio numrica na
lista, iniciando pelo nmero 1. O exemplo a seguir declara uma varivel, atribui uma
matriz de trs elementos a ela, e ento exibe um dos elementos e o tamanho da matriz:
Local aLetras // Declarao da varivel
aLetras := {"A", "B", "C"} // Atribuio da matriz varivel
Alert(aLetras[2]) // Exibe o segundo elemento da matriz
Alert(cValToChar(Len(aLetras))) // Exibe o tamanho da matriz
O AdvPl permite a manipulao de matrizes facilmente. Enquanto que em outras
linguagens como C ou Pascal necessrio alocar memria para cada elemento de uma
matriz (o que tornaria a utilizao de "pointeiros" necessria), o AdvPl se encarrega de
gerenciar a memria e torna simples adicionar elementos a uma matriz, utilizando a
funo aAdd:
aAdd(aLetras,"D") // Adiciona o quarto elemento ao final da matriz
Alert(aLetras[4]) // Exibe o quarto elemento
Alert(aLetras[5]) // Erro! No h um quinto elemento na matriz
Matrizes como Estruturas
Uma caracterstica interessante do AdvPl que uma matriz pode conter qualquer coisa:
nmeros, datas, lgicos, caracteres, objetos, etc. E ao mesmo tempo. Em outras
palavras, os elementos de uma matriz no precisam ser necessariamente do mesmo tipo
de dado, em contraste com outras linguagens como C e Pascal.
aFunct1 := {"Pedro",32,.T.}
Esta matriz contem uma string, um nmero e um valor lgico. Em outras linguagens
como C ou Pascal, este "pacote" de informaes pode ser chamado como um "struct"
(estrutura em C, por exemplo) ou um "record" (registro em Pascal, por exemplo). Como
se fosse na verdade um registro de um banco de dados, um pacote de informaes
construdo com diversos campos. Cada campo tendo um pedao diferente de dado.
Suponha que no exemplo anterior, o array aFunct1 contenha informaes sobre o nome
de uma pessoa, sua idade e sua situao matrimonial. Os seguintes #defines podem ser
criados para indicar cada posio dos valores dentro da matriz:
#define FUNCT_NOME 1
#define FUNCT_IDADE 2
#define FUNCT_CASADO 3
E considere mais algumas matrizes para representar mais pessoas:
aFunct2 := {"Maria" , 22, .T.}
aFunct3 := {"Antnio", 42, .F.}
Os nomes podem ser impressos assim:
Alert(aFunct1[FUNCT_NOME])
Alert(aFunct2[FUNCT_NOME])
Alert(aFunct3[FUNCT_NOME])
Agora, ao invs de trabalhar com variveis individuais, pode-se agrup-las em uma
outra matriz, do mesmo modo que muitos registros so agrupados em uma tabela de
banco de dados:
aFuncts := {aFunct1, aFunct2, aFunct3}
Que equivalente a isso:
aFuncts := { {"Pedro" , 32, .T.}, ;
{"Maria" , 22, .T.}, ;
{"Antnio", 42, .F.} }
aFuncts uma matriz com 3 linhas por 3 colunas. Uma vez que as variveis separadas
foram combinadas em uma matriz, os nomes podem ser exibidos assim:
Local nCount
For nCount := 1 To Len(aFuncts)
Alert(aFuncts[nCount,FUNCT_NOME])
// O acesso a elementos de uma matriz multidimensional
// pode ser realizado tambm desta forma:
// aFuncts[nCount][FUNCT_NOME]
Next nCount
A varivel nCount seleciona que funcionrio (ou que linha) de interesse. Ento a
constante FUNCT_NOME seleciona a primeira coluna daquela linha.
Cuidados com Matrizes
Matrizes so listas de elementos, portanto memria necessria para armazenar estas
informaes. Como as matrizes podem ser multidimensionais, a memria necessria
ser a multiplicao do nmero de itens em cada dimenso da matriz, considerando-se o
tamanho do contedo de cada elemento contido nesta. Portanto o tamanho de uma
matriz pode variar muito.
A facilidade da utilizao de matrizes, mesmo que para armazenar informaes em
pacotes como descrito anteriormente, no compensada pela utilizao em memria
quando o nmero de itens em um array for muito grande. Quando o nmero de
elementos for muito grande deve-se procurar outras solues, como a utilizao de um
arquivo de banco de dados temporrio.
No h limitao para o nmero de dimenses que uma matriz pode ter, mas o nmero
de elementos mximo (independentes das dimenses onde se encontram) de 100000.
Tipos de Dados
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
O AdvPl no uma linguagem de tipos rgidos (strongly typed), o que significa que
variveis de memria podem diferentes tipos de dados durante a execuo do programa.
Variveis podem tambm conter objetos, mas os tipos primrios da linguagem so:
Numrico
Lgico
Caracter
Data
Matriz (Array)
Bloco de Cdigo
Numrico
O AdvPl no diferencia valores inteiros de valores com ponto flutuante, portanto pode-
se criar variveis numricas com qualquer valor dentro do intervalo permitido. Os
seguintes elementos so do tipo de dado numrico:
2
43.53
0.5
0.00001
1000000
Uma varivel do tipo de dado numrico pode conter um nmero de dezoito dgitos
incluindo o ponto flutuante, no intervalo de 2.2250738585072014 E308 at
1.7976931348623158 E+308.
Lgico
Valores lgicos em AdvPl so identificados atravs de .T. ou .Y. para verdadeiro e .F.
ou .N. para falso (independentemente se os caracteres estiverem em maisculo ou
minsculo).
Caracter
Strings ou cadeias de caracteres so identificadas em AdvPl por blocos de texto entre
aspas duplas (") ou aspas simples ('):
"Ol mundo!"
'Esta uma string'
"Esta 'outra' string"
Uma varivel do tipo caracter pode conter strings com no mximo 1 Mb, ou seja,
1048576 caracteres.
Data
O AdvPl tem um tipo de dados especfico para datas. Internamente as variveis deste
tipo de dado so armazenadas como um nmero correspondente a data Juliana.
Variveis do tipo de dados Data no podem ser declaradas diretamente, e sim atravs da
utilizao de funes especficas como por exemplo ctod que converte uma string para
data.
Matriz (Array)
Matrizes so um tipo de dado especial. a disposio de outros elementos em colunas e
linhas. O AdvPl suporta matrizes uni ou multidimensionais. Os elementos de uma
matriz so acessados atravs de ndices numricos iniciados em 1, identificando a linha
e coluna para quantas dimenes existirem.
Uma matriz pode conter no mximo 100000 elementos, independentemente do nmero
de dimenses.
Matrizes devem ser utilizadas com cautela, pois se forem muito grandes podem exaurir
a memria do servidor.
Bloco de Cdigo
O bloco de cdigo um tipo de dado especial. utilizado para armazenar instrues
escritas em AdvPl que podero ser executadas posteriormente.
O Contexto de Variaveis dentro de um
Programa
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
As variveis declaradas em um programa ou funo, so visveis de acordo com o
escopo onde so definidas. Como tambm do escopo depende o tempo de existncia das
variveis. A definio do escopo de uma varivel efetuada no momento de sua
declarao.
Local nNumero := 10
Esta linha de cdigo declara uma varivel chamada nNumero indicando que pertence
seu escopo local.
Os identifadores de escopo so:
LOCAL
STATIC
PRIVATE
PUBLIC
O AdvPl no rgido em relao declarao de variveis no comeo do programa. A
incluso de um identificador de escopo no necessrio para a declarao de uma
varivel, contanto que um valor lhe seja atribudo.
nNumero2 := 15
Quando um valor atribudo uma varivel em um programa ou funo, o AdvPl criar
a varivel caso ela no tenha sido declarada anteriormente. A varivel ento criada
como se tivesse sido declarada como Private.
Devido a essa caracterstica, quando pretende-se fazer uma atribuio a uma varivel
declarada previamente mas escreve-se o nome da varivel de forma incorreta, o AdvPl
no gerar nenhum erro de compilao ou de execuo. Pois compreender o nome da
varivel escrito de forma incorreta como se fosse a criao de uma nova varivel. Isto
alterar a lgica do programa, e um erro muitas vezes difcil de identificar.
Variaveis Estaticas
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Variveis estticas funcionam basicamente como as variveis locais, mas mantm seu
valor atravs da execuo. Variveis estticas devem ser declaradas explicitamente no
cdigo com o identificador STATIC.
O escopo das variveis estticas depende de onde so declaradas. Se forem declaradas
dentro do corpo de uma funo ou procedimento, seu escopo ser limitado quela
rotina. Se forem declaradas fora do corpo de qualquer rotina, seu escopo todo o
arquivo de programa.
Neste exemplo, a varivel nVar declarada como esttica e inicializada com o valor 10:
Function Pai()
Static nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Quando a funo Filha executada, nVar ainda existe mas no pode ser acessada.
Diferente de variveis declaras como LOCAL ou PRIVATE, nVar continua a existir e
mantem seu valor atual quando a execuo da funo Pai termina. Entretanto, somente
pode ser acessada por execues subseqntes da funo Pai.
Variaveis Locais
Reviso: 02/12/2004
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Variveis locais so pertencentes apenas ao escopo da funo onde foram declaradas.
Devem ser explicitamente declaradas com o identificador LOCAL, como no exemplo:
Function Pai()
Local nVar := 10, aMatriz := {0,1,2,3}
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, a varivel nVar foi declarada como local e atribuda com o valor 10.
Quando a funo Filha executada, nVar ainda existe mas no pode ser acessada.
Quando a execuo da funo Pai terminar, a varivel nVar destruda. Qualquer
varivel com o mesmo nome no programa que chamou a funo Pai no afetada.
Variveis locais so criadas automaticamente cada vez que a funo onde forem
declaradas for ativada. Elas continuam a existir e mantm seu valor at o fim da
ativao da funo (ou seja, at que a funo retorne o controle para o cdigo que a
executou). Se uma funo chamada recursivamente (por exemplo, chama a si mesma),
cada chamada em recurso cria um novo conjunto de variveis locais.
A visibilidade de variveis locais idntica ao escopo de sua declarao. Ou seja, a
varivel visvel em qualquer lugar do cdigo fonte em que foi declarada. Se uma
funo chamada recursivamente, apenas as variveis locais criadas na mais recente
ativao so visveis.
A declarao de variveis locais dentro de uma funo deve preceder qualquer
comando interno ou declarao de outros tipos de variveis (Private ou Public) da
funo caso contrrio ser gerado um erro de compilao.
Exemplo:
Function A( )
Private x:= 0
Local b:=0 <<<<< ERRADO, ERRO DE COMPILAO
...
Return
Verso correta:
Function A( )
Local b:=0 // correto
Private x:=0
....
Return
Variaveis Privadas
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
A declarao opcional para variveis privadas. Mas podem ser declaradas
explicitamente com o identificador PRIVATE.
Adicionalmente, a atribuio de valor a uma varivel no criada anteriormente
automaticamente cria a varivel como privada. Uma vez criada, uma varivel privada
continua a existir e mantem seu valor at que o programa ou funo onde foi criada
termine (ou seja, at que a funo onde foi criada retorne para o cdigo que a executou).
Neste momento, automaticamente destruda.
possvel criar uma nova varivel privada com o mesmo nome de uma varivel j
existente. Entretanto, a nova (duplicada) varivel pode apenas ser criada em um nvel de
ativao inferior ao nvel onde a varivel foi declarada pela primeira vez (ou seja,
apenas em uma funo chamada pela funo onde a varivel j havia sido criada). A
nova varivel privada ir esconder qualquer outra varivel privada ou pblica (veja a
documentao sobre variveis pblicas) com o mesmo nome enquanto existir.
Uma vez criada, uma varivel privada visvel em todo o programa enquanto no for
destruda automaticamente quando a rotina que a criou terminar ou uma outra varivel
privada com o mesmo nome for criada em uma subfuno chamada (neste caso, a
varivel existente torna-se inacessvel at que a nova varivel privada seja destruda).
Em termos mais simples, uma varivel privada visvel dentro da funo de criao e
todas as funes chamadas por esta, a menos que uma funo chamada crie sua prpria
varivel privada com o mesmo nome.
Por exemplo:
Function Pai()
Private nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, a varivel nVar criada como privada e inicializada com o valor 10.
Quando a funo Filha executada, nVar ainda existe e, diferente de uma varivel local,
pode ser acessada pela funo Filha. Quando a funo Pai terminar, nVar ser destruda
e qualquer declarao de nVar anterior se tornar acessvel novamente.
Variaveis Publicas
Reviso: 13/07/2002
Abrangncia
Verso 5.07 Verso 5.08 Verso 6.09 Verso 7.10 Verses Anteriores
Pode-se criar variveis pblicas dinamicamente no cdigo com o identificador PUBLIC.
As variveis pblicas continuam a existir e mantm seu valor at o fim da execuo.
possvel criar uma varivel privada com o mesmo nome de uma varivel pblica
existente. Entretanto, no permitido criar uma varivel pblica com o mesmo nome de
uma varivel privada existente.
Uma vez criada, uma varivel pblica visvel em todo o programa onde foi declarada
at que seja escondida por uma varivel privada criada com o mesmo nome. A nova
varivel privada criada esconde a varivel pblica existente, e esta se tornar inacessvel
at que a nova varivel privada seja destruda. Por exemplo:
Function Pai()
Public nVar := 10
.
<comandos>
.
Filha()
.
<mais comandos>
.
Return(.T.)
Neste exemplo, nVar criada como pblica e inicializada com o valor 10. Quando a
funo Filha executada, nVar ainda existe e pode ser acessada. Diferente de variveis
locais ou privadas, nVar ainda existe aps o trmino da a execuo da funo Pai.
Diferentemente dos outros identificadores de escopo, quando uma varivel declarada
como pblica sem ser inicializada, o valor assumido falso (.F.) e no nulo (nil).

También podría gustarte