4D v16.3Ponteiros |
||||||||||||||||||||||||||
|
4D v16.3
Ponteiros
|
Objeto | Referenciamiento | Utilização | Atribuição |
Tabela | vpTabela:=->[Tabela] | DEFAULT TABLE(vpTabela->) | n/a |
Campo | vpCampo:=->[Tabela]Campo | ALERT(vpCampo->) | vpCampo->:="João" |
Variável | vpVar:=->Variável | ALERT(vpVar->) | vpVar->:="João" |
Array | vpArr:=->Array | SORT ARRAY(vpArr->;>) | COPY ARRAY(Arr;vpArr->) |
Elemento array | vpElem:=->Array{1} | ALERT (vpElem->) | vpElem->:="João" |
É mais fácil explicar o uso de ponteiros com um exemplo. Este exemplo mostra como acessar uma variável através de um ponteiro. Começamos criando uma variável:
MinhaVar:="Olá"
MinhaVar agora é uma variável que contem a string "Olá". Agora podemos criar um ponteiro para MinhaVar:
MeuPonteiro:=->MinhaVar
O símbolo -> significa "obter um ponteiro para." Esse símbolo é formado por um hífen seguido de um sinal de "maior que". Neste caso, torna-se o ponteiro que referencia ou "aponta para" MinhaVar. Esse ponteiro é atribuído a MeuPonteiro com o operador de atribuição.
MeuPonteiro agora é uma variável que contém um ponteiro para MinhaVar. MeuPonteiro não contém "Olá", que é o valor em MinhaVar, mas você pode usar MeuPonteiro para obter este valor. A seguinte expressão retorna o valor em MinhaVar:
MeuPonteiro->
Neste caso, ele retorna a string "Olá". O símbolo ->, quando seguido de um ponteiro, faz referência ao objeto apontado. Isso é chamado dereferenciamento.
É importante compreender que você pode usar um ponteiro seguido do símbolo -> em qualquer lugar que você pudesse ter usado o objeto que o ponteiro aponta. Isso significa que você pode usar a expressão MeuPonteiro-> em qualquer lugar que você poderia usar a variável original MinhaVar.
Por exemplo, a seguinte linha exibe uma caixa de alerta com a palavra Olá nela:
ALERT(MeuPonteiro->)
Você também pode usar MeuPonteiro para alterar os dados em MinhaVar. Por exemplo, as instrução seguinte armazena "Tchau" na variável MinhaVar:
MeuPonteiro->="Tchau"
Se você examinar os dois usos da expressão MeuPonteiro-> você verá que ela age como se você tivesse usado MinhaVar. Em resumo, as duas linhas seguintes executam a mesma ação - as duas exibem uma caixa de alerta contendo o valor atual da variável MinhaVar:
ALERT(MeuPonteiro->)
ALERT(MinhaVar)
As duas linhas seguintes executam a mesma ação, atribuem a string "Tchau" a MinhaVar:
MeuPonteiro->:="Tchau"
MinhaVar:="Tchau"
Esta seção descreve como usar um ponteiro para um botão de referência. Um botão é (do ponto de vista da linguagem), nada mais do que uma variável. Embora os exemplos nesta seção usem ponteiros para os botões de referência, os conceitos aqui apresentados são aplicáveis à utilização de todos os tipos de objetos que pode ser referenciados por um ponteiro.
Digamos que você tenha uma quantidade de botões nos formulários que precisam ser ativados ou desativados. Cada botão tem uma condição associada a ele, VERDADEIRO ou FALSO. A condição diz para desativar ou ativar o botão. Você pode usar um teste como este cada vez que você precise para ativar ou desativar o botão:
If(condição) `Se a condição é VERDADEIRA…
OBJECT SET ENABLED(MeuBotao;True) ` ativa o botão
Else ` Caso contrário…
OBJECT SET ENABLED(Meubotao;False) ` desativa o botão
End if
Você precisaria usar um teste semelhante para cada botão que você definiu, apenas mudando o nome do botão. Para ser mais eficiente, você pode usar um ponteiro de referência para cada botão e então usar uma sub-rotina para o teste em si.
Você deve usar ponteiros se você usar uma sub-rotina, porque você não pode se referir a variáveis do botão de outra forma. Por exemplo, abaixo é um método de projeto chamado SET BUTTON, que faz referência a um botão com um ponteiro:
` Método de projeto DEFINIR BOTÃO
` DEFINIR BOTÃO ( Ponteiro; Booleano )
` DEFINIR BOTÃO ( -> Botão ; Ativar ou Desativar )
`
` $1 – Ponteiro a um botão
` $2 – Booleano. Se TRUE, ativar o botão. Se FALSE, desativar o botão
If($ 2) `Se a condição é TRUE…
OBJECT SET ENABLED($1->;True) ` ativar o botão
Else ` Caso contrário…
OBJECT SET ENABLED($1->;False) ` desativar o botão
End if
Você pode chamar o método de projeto SET BUTTON assim:
` ...
SET BUTTON(->bValidate;True)
` ...
SET BUTTON(->bValidate;False)
` ...
SET BUTTON(->bValidate;([Empregado]Sobrenome#"")
` ...
For($vlRadioButton;1;20)
$vpRadioButton:=Get pointer("r"+String($vlRadioButton))
SET BUTTON($vpRadioButton;False)
End for
Em qualquer lugar que a linguagem espera ver uma tabela, você pode usar um ponteiro para a tabela.
Você cria um ponteiro para uma tabela usando um código como este:
TabelaPtr:=->[qualquer tabela]
Você também pode obter um ponteiro para uma tabela usando o comando Table. Por exemplo:
TabelaPtr:=Table(20)
Você pode usar o ponteiro em comandos, como este:
DEFAULT TABLE(TabelaPtr->)
Em qualquer lugar que a linguagem espere ver um campo, você pode usar um ponteiro para fazer referência ao campo. Você cria um ponteiro para um campo usando uma linha como esta:
CampoPtr:=->[umaTabela]EsteCampo
Você também pode obter um ponteiro para um campo usando o comando Field. Por exemplo:
CampoPtr:=Field(1;2)
Você pode usar o ponteiro em comandos, como este:
OBJECT SET FONT(CampoPtr->;"Arial")
O exemplo no início desta seção ilustra o uso de um ponteiro para uma variável:
MinhaVar:="Olá"
MeuPonteiro:=->MinhaVar
Você pode usar ponteiros para variáveis interprocesso, processo e, a partir da versão 2004.1, para variáveis locais.
Quando você usa ponteiros para variáveis processo ou locais, você deve ter certeza que a variável apontada já está definida quando o ponteiro for usado. Tenha em mente que as variáveis locais são apagadas quando o método que a criou já completou a sua execução e as variáveis do processo são eliminadas no final do processo que as criou. Quando um ponteiro chama uma variável que não existe mais, isso gera um erro de sintaxe no modo interpretado (variável não definida), mas pode gerar um erro mais grave no modo compilado.
Nota sobre as variáveis locais: Ponteiros para as variáveis locais permite que você salve as variáveis do processo, em muitos casos. Ponteiros para as variáveis locais só podem ser utilizados dentro do mesmo processo.
No depurador, quando você exibir um ponteiro para uma variável local que tenha sido declarada em outro método, o nome do método original está indicado entre parênteses, após o ponteiro. Por exemplo, se você escrever em Metodo1:
$MinhaVar="Olá Mundo!"
Metodo2(->$MinhaVar)
Em Metodo2, o depurador irá exibir $1 desta maneira:
$1 ->$MinhaVar (Metodo1)
O valor de $1 será:
$MinhaVar (Metodo1) "Olá Mundo"
Você pode criar um ponteiro para um elemento do array. Por exemplo, as seguintes linhas criam uma matriz e atribuem um ponteiro para o primeiro elemento de uma variável chamada ElemPtr:
ARRAY REAL(umArray;10) ` Cria um array
ElemPtr:=->umArray{1} `Cria um ponteiro para o elemento do array
Você pode usar o ponteiro para atribuir um valor ao elemento, assim:
ElemPtr->:=8
Você pode criar um ponteiro para um array. Por exemplo, as seguintes linhas criam um array e atribuem um ponteiro para o array para uma variável chamada ArrPtr:
ARRAY REAL(umArray;10) ` Cria um array
ArrPtr:=->umArray `Cria um ponteiro para o array
É importante compreender que o ponteiro aponta para o array, que não aponta para um elemento do array. Por exemplo, você pode usar o ponteiro das linhas anteriores, como este:
SORT ARRAY(ArrPtr->;>) `Ordena o array
Se você precisa se referir ao quarto elemento na matriz, usando o ponteiro, você pode fazer isso:
ArrPtr->{4}:=84
Muitas vezes, é útil ter um array de ponteiros que fazem referência a um grupo de objetos relacionados.
Um exemplo de um grupo de objetos é uma grade de variáveis em um formulário. Cada variável na grade é numerada sequencialmente, por exemplo: Var1,Var2,…, Var10. Você muitas vezes vai precisar de referenciar essas variáveis indiretamente com um número. Se você criar um array de ponteiros, e inicializar os ponteiros para apontar para cada variável, você pode fazer referência, então, facilmente às variáveis. Por exemplo, para criar uma matriz e inicializar cada elemento, você pode usar as seguintes linhas:
ARRAY POINTER(apPointers;10) `Cria um array para armazenar 10 ponteiros
For($i;1;10) `Loop para cada variável, uma vez
apPointers{$i}:=Get pointer("Var"+String($i)) `Inicializa o array
End for
A função Get pointer retorna um ponteiro ponteiro para o objeto chamado.
Para fazer referência a qualquer das variáveis, você usa os elementos do array. Por exemplo, para preencher as variáveis com as datas dos próximos dez dias (assumindo que elas são variáveis do tipo data), você pode usar as seguintes linhas:
For($i;1;10) ` Loop para cada variável, uma vez
apPointers{$i}->:=Current date+$i `Atribuir as datas
End for
Se você tem um grupo de botões de rádio relacionados em um formulário, muitas vezes você precisa colocá-los rapidamente. É ineficiente fazer referência a cada um deles pelo nome. Digamos que você tem um grupo de botões de rádio chamados Botão1, Botão2,…, Botão5.
Em um grupo de botões de rádio, apenas um botão de rádio está ligado. O número do botão que está ligado pode ser armazenado em um campo numérico. Por exemplo, se o campo chamado [Preferencias]Estado contém 3, então Botão3 é selecionado. No seu método de formulário, você poderia usar o seguinte código para definir o botão:
Case of
:(Form event=On Load)
` ...
Case of
:([Preferencias]Estado=1)
Botão1:=1
:([Preferencias]Estado=2)
Botão2:=1
:([Preferencias]Estado=3)
Botão3:=1
:([Preferencias]Estado=4)
Botão4:=1
:([Preferencias]Estado=5)
Botão5:=1
End case
` ...
End case
Um caso distinto deve ser testado para cada botão de rádio. Este poderia ser um método muito longo se você tiver muitos botões no formulário. Felizmente, você pode usar ponteiros para resolver este problema. Você pode usar o comando Get pointer para retornar um ponteiro para um botão de rádio. O exemplo a seguir usa como referência um ponteiro para o botão que deve ser definido. Aqui está o código melhorado:
Case of
:(Form event=On Load)
` ...
$vpRadio:=Get pointer("Botão"+String([Preferencias]Estado))
$vpRadio->:=1
` ...
End case
O número do botão de rádio de referência deve ser armazenado no campo chamado [Preferencias]
[Preferencias]Estado:=Botão1+(Botão2*2)+(Botão3*3)+(Botão4*4)+(Botão5*5)
Você pode passar um ponteiro como um parâmetro para um método. Dentro do método, você pode modificar o objeto referenciado pelo ponteiro. Por exemplo, o método a seguir, TAKE TWO, tem dois parâmetros que são ponteiros. Ele muda o objeto referenciado pelo primeiro parâmetro para caracteres maiúsculos, e o objeto referenciado pelo segundo parâmetro para caracteres minúsculos. Aqui está o método:
` Método de projeto TAKE TWO
` $1 – Ponteiro para um campo string ou variável. Alterar para maiúsculas.
` $2 – Ponteiro para um campo string ou variável. Alterar para minúsculas.
$1->:=Uppercase($1->)
$2->:=Lowercase($2->)
A linha a seguir usa o método TAKE TWO para alterar um campo para caracteres maiúsculos e mudar uma variável para caracteres minúsculos:
TAKE TWO(->[Minha Tabela]Meu Campo;->MinhaVar)
Se o campo [Minha Tabela] Meu Campo continha a string "jones", ele teria de ser alterado para a string de "JONES". Se a variável MinhaVar continha a string "OLÁ", seria alterada para "olá"
No método TAKE TWO, e de fato, sempre que você usar ponteiros, é importante que o tipo de dados do objeto a ser referenciado seja correto. No exemplo anterior, os ponteiros devem apontar para um objeto que contém uma seqüência de caracteres ou texto.
Se você realmente gosta de complicar as coisas, você pode usar ponteiros para fazer referência a outros ponteiros. Veja este exemplo:
MinhaVar:="Olá"
PonteiroUm:=->MinhaVar
PonteiroDois:=->PonteiroUm
(PonteiroDois->)->:="Até logo"
ALERT((Ponteiro Dois->)->)
Exibe uma caixa de alerta com a palavra "Tchau" nela.
Aqui está uma explicação de cada linha do exemplo:
Portanto (PonteiroDois->)-> referencia o conteúdo de MinhaVar. De modo que neste caso, MinhaVar é atribuída a "Tchau".
A linha seguinte coloca "Olá" em MinhaVar:
(PonteiroDois->)->:="Olá"
A linha seguinte obtém "ola" de MinhaVar e atribui a NovaVar: NovaVar:=(PonteiroDois->)->
Importante: o desreferenciamiento múltiplo requer parêntesis.
Arrays
Arrays e ponteiros
Constantes
Controle de fluxo
Convenções
Métodos
Operadores
Tipos de dados
Variáveis
Produto: 4D
Tema: Apresentação da linguagem
Manual de linguagem 4D ( 4D v16)
Manual de linguagem 4D ( 4D v16.1)
Manual de linguagem 4D ( 4D v16.2)
Manual de linguagem 4D ( 4D v16.3)