version 2004.1 (Modified)
ポインタは、(プログラミングにおける)データを参照するための高度な方法です。
プログラミング言語を使用する場合、名前を用いてテーブル、フィールド、変数、配列等をアクセスします。通常は、名前によるデータの参照が最も簡単な方法ですが、名前を使用しないでデータを参照する、またはアクセスした方が便利な場合もあります。この場合、ポインタを使用すると実現できます。
ポインタの背景にある概念は、日常生活でもよく用いられています。対象物を正確に知らないで何かを示すことがあります。例えば、友人に対して“登録番号123ABDの車に乗ろう”と言わないで“君の車に乗ろう”という場合があります。つまり、“登録番号123ABDの車”を“君の車”で示したわけです。この場合、“登録番号123ABDの車”はオブジェクトの名前で、“君の車”はオブジェクトを参照するためのポインタと考えることができます。
あるものの対象物を明示しないで参照することができると非常に便利です。例えば友人が新しい車に買い替えても、同じく“君の車”と言うことができます。ポインタも同じように機能します。例えば、ある場合は数値フィールド“Age”を参照したポインタで、別の場合には数値変数“Old Age”を参照することもできます。この場合のポインタは、計算に使用する数値データを参照しています。
テーブル、フィールド、変数、配列、配列要素を参照するためにポインタを使用することができます。以下の表に、各タイプの例を示します。
| オブジェクト | 参照する | 使用する | 割り当てる |
| Table | vpTable:=->[Table] | DEFAULT TABLE(vpTable->) | n/a |
| Field | vpField:=->[Table]Field | ALERT(vpField->) | vpField->:="John" |
| Variable | vpVar:=->Variable | ALERT(vpVar->) | vpVar->:="John" |
| Array | vpArr:=->Array | SORT ARRAY(vpArr->;>) | COPY ARRAY (Arr;vpArr->) |
| Array element | vpElem:=->Array{1} | ALERT (vpElem->) | vpElem->:="John" |
ポインタの使用例
例題を用いてポインタの使用方法について説明します。以下の例は、ポインタを通して変数にアクセスする方法を示しています。まず、変数の作成から始めます。
MyVar:="Hello"
“MyVar”は、文字列“Hello”を含む変数です。“MyVar”に対するポインタを作成します。
MyPointer:=->MyVar
ポインタ記号(->)は、“に対するポインタを求める”ことを意味します。ここでは、“MyVar”を参照するポインタを呼び出します。このポインタは、代入演算子(:=)で“MyPointer”に対して割り当てられます。
“MyPointer”は、“MyVar”に対するポインタを含む変数です。“MyPointer”は、“Hello”という“MyVar”の値を含みませんが、“MyVar”に含まれる値を指すことはできます。以下の式は“MyVar”の値を返します。
MyPointer->
前述の式は、“Hello”という文字列を返します。ポインタ記号(->)をポインタの後につけると、そのポインタの指すオブジェクトの値を示します。
ポインタ記号(->)を後につけたポインタを使用してオブジェクトを参照することの意味を理解することが重要です。つまり、変数“MyVar”を使用することと、式“MyPointer->”を使用することは、全く同じ意味です。
例えば、以下のステートメントはアラートボックスに文字列“Hello”を表示します。
ALERT(MyPointer->)
“MyPointer”を使用して“MyVar”の値を変更することもできます。下記のステートメントは、変数“MyVar”に文字列"Goodbye"を代入します。
MyPointer->:="Goodbye"
この2つの“MyPointer->”を使用したステートメントのとおり、“MyVar”を使用した場合と全く同じ動作を実行します。以下の2つのステートメントも、全く同じ動作を実行します。両方とも、変数“MyVar”の現在の値をアラートボックスに表示します。
ALERT(MyPointer->) ALERT(MyVar)
以下の2つのステートメントも、全く同じ動作を実行します。両方とも“MyVar”に、文字列“Goodbye”を代入します。
MyPointer->:="Goodbye" MyVar:="Goodbye"
ボタンへのポインタを使用する
この節では、ボタンを参照するためのポインタの使用方法について説明します。ボタンは(プログラミング言語の観点から)、変数に属します。この節では、ボタンを参照するためのポインタの例を使用していますが、ここで示す概念は、他のすべての種類のオブジェクトでも同様です。
フォーム上に、多数のボタンがあり、状態(コンディション)のTrueまたはFalseによって、ボタンを使用可または使用不可にする必要があるとします。ボタンを使用可または使用不可にしなければならない度に、以下のようなテストが必要になります。
If (Condition) ` If the condition is TRUE… ENABLE BUTTON (MyButton) ` enable the button Else ` Otherwise… DISABLE BUTTON (MyButton) ` disable the button End if
フォーム中のその他のボタンに対しても、同様の判定を実行する必要があります。さらに効率良く判定処理を実行するためには、各ボタンの参照にポインタを用いて判定を実行するサブルーチンを使用します。
サブルーチンを使用する場合は、ポインタを使用しなければなりません。なぜなら、これ以外の方法では、ボタンの変数を参照することができないからです。例えば、以下のプロジェクトメソッド“Set Button”はポインタを使用してボタンを参照しています。
` SET BUTTON プロジェクトメソッド ` SET BUTTON ( Pointer ; Boolean ) ` SET BUTTON ( -> Button ; Enable or Disable ) ` ` $1: ボタンのポインタ ` $2: Boolean. もしTRUEならボタンを使用可とする。;もしFALSEならボタンを使用不可とする。 If ($2) ` もしTRUEなら… ENABLE BUTTON($1->) ` ボタンを使用可とする。 Else ` それ以外なら… DISABLE BUTTON($1->) ` ボタンを使用不可とする。 End if
プロジェクトメソッド“Set Button”は以下のように呼び出します。
` ...
SET BUTTON (->bValidate;True)
` ...
SET BUTTON (->bValidate;False)
` ...
SET BUTTON (->bValidate;([Employee]Last Name#"")
` ...
For ($vlRadioButton;1;20)
$vpRadioButton:=Get pointer("r"+String($vlRadioButton))
SET BUTTON ($vpRadioButton;False)
End for
テーブルへのポインタを使用する
プログラミング言語でテーブルの代わりにポインタを使用することができます。
以下のようなステートメントで、テーブルのポインタを作成します。
TablePtr:=->[anyTable]
あるいは、以下のようにTableコマンドを使用してテーブルのポインタを得ることができます。
TablePtr:=Table(20)
以下のようにコマンドに対して、ポインタを指定することができます。
DEFAULT TABLE(TablePtr->)
フィールドへのポインタを使用する
言語がフィールドを期待する場所ではどこでも、フィールドを参照するためにポインタの逆参照を使用できます。以下のようなステートメントで、フィールドのポインタを作成します。
FieldPtr:=->[aTable]ThisField
あるいは、以下のようにFieldコマンドを使用してフィールドのポインタを得ることができます。
FieldPtr:=Field(1; 2)
以下のようにコマンドに対して、逆参照したポインタを指定することができます。
FONT(FieldPtr->; "Osaka")
変数へのポインタを使用する
この節の最初の例は変数へのポインタの使用を説明しています。
MyVar:="Hello" MyPointer:=->MyVar
ポインタは、インタープロセス変数、プロセス変数の他、バージョン2004.1からはローカル変数にも利用できるようになりました。
プロセス変数もしくはローカル変数にポインタを使う場合、参照される変数はポインタが使用される時点で既に定義されていなければなりません。
ローカル変数は、それらを作成したメソッドの実行が終わると破棄され、プロセス変数もそれを作成したプロセスの終了時に削除される点に留意してください。存在しない変数をポインタが呼び出そうとすると、インタープリタモードでは(「変数が設定されていません」という内容の)シンタックスエラーが起きます。コンパイルモードでは、さらに重大なエラーが発生する可能性があります。
Note:ローカル変数について;ローカル変数のポインタを使用すると、プロセス変数の使用を控えることができます。ポインタは、同じプロセス内のローカル変数にのみ使用することができます。
ポインタの参照先が、別のメソッドで宣言されたローカル変数の場合、これをデバッガに表示すると、オリジナルのメソッド名が、ポインタの後の括弧内に表示されます。例としてMethod1で以下のように書いたとします。
$MyVar:="Hello world" Method2(->$MyVar)
Method2では、デバッガは$1を次のように表示します。
$1 ->$MyVar (Method1)
$1の値は、次のようになります。
$MyVar (Method1) "Hello world"
配列要素へのポインタを使用する
配列要素に対するポインタを作成することができます。以下の例は配列を作成し、配列の最初の要素を指し示すポインタを変数“ElemPtr”に割り当てます。
ARRAY REAL(anArray; 10) ` 配列を作成
ElemPtr:=->anArray{1} ` 配列要素へのポインタを作成
以下のように、ポインタの参照先である配列要素に値を代入することができます。
ElemPtr->:=8
配列へのポインタを使用する
配列に対するポインタを作成することができます。以下の例は配列を作成し、配列を指し示すポインタを変数“ArrPtr”に割り当てます。
ARRAY REAL(anArray; 10) ` Create an array ArrPtr := ->anArray ` Create a pointer to the array
ポインタが配列をポイントしていることを理解することが重要です。配列要素ではありません。例えば、ポインタの逆参照を以下のように使用できます:
SORT ARRAY(ArrPtr->; >) ` 配列のソート
配列のポインタを使用し、例えば4番目の要素にアクセスするには、以下のように記述します。
ArrPtr->{4} := 84
ポインタ配列の使用
関連するオブジェクトのグループを参照する場合にポインタ配列を使用すると便利な場合があります。
そのようなオブジェクトのグループの例として、フォーム上の変数のグリッドがあります。グリッドのそれぞれの変数には、Var1”、“Var2”、. . . 、“var10”という連番が付いているとします。間接的にこれらの変数を数字で参照することができます。ポインタの配列を作成し、各変数を指すためにポインタを初期化すれば、変数を簡単に参照することができます。例えば、配列を作成し各要素を初期化するために、以下のようなステートメントを使用します。
ARRAY POINTER(apPointers; 10) ` 10の要素を持つポインタ配列をを作成する。
For ($i; 1; 10) `各変数に対し1回ずつループする
apPointers{$i}:=Get pointer("Var"+String($i)) `配列要素を初期化する。
End for
Get pointer 関数は、指定された変数名で示されるオブジェクトへのポインタを返します。
いくつかの変数への参照が必要な場合は、配列要素を使用します。例えば、変数に10個の日付を代入する場合は(変数が日付タイプであると想定して)、以下のように記述します。
For ($i; 1; 10) ` 各変数に対し1回ずつループする
apPointers{$i}->:=Current date+$i ` 日付を代入
End for
ポインタを使用したボタンの設定
フォーム中に関連する一連のラジオボタンがある場合に、それらを素早く設定しなければならないことがあります。名前を使用して各ラジオボタンを直接参照することは、効率が良くありません。
今ここにグループ化された、Button1、Button2、… 、Button5という名前の5つのラジオボタンがあったとします。
一連のラジオボタンでは、1つのラジオボタンのみがオンになります。オンになっているラジオボタンの番号は、数値フィールドに記憶されます。例えば、[Preferences]Settingの値が3の場合は、Button3に1を設定します。フォームメソッドは以下のようなプログラムにより、ボタンをセットします。
Case of :(Form event=On Load) ` ... Case of : ([Preferences]Setting = 1) Button1:=1 : ([Preferences]Setting = 2) Button2:=1 : ([Preferences]Setting = 3) Button3:=1 : ([Preferences]Setting = 4) Button4:=1 : ([Preferencs]Setting = 5) Button5:=1 End case ` ... End case
上記例では各ラジオボタンごとに判定しなければなりません。フォーム内に多くのラジオボタンがあると、非常に長いメソッドになる場合もあります。この問題を解決するために、ポインタを使用します。
Get pointer 関数を使用して、ラジオボタン(あるいは任意のボタン)のポインタを作成することができます。値を設定する必要のあるラジオボタンを参照するためにポインタを使用します。次に改善されたメソッドの例を示します。
Case of
:(Form event=On Load)
` ...
$vpRadio:=Get pointer("Button"+String([Preferences]Setting))
$vpRadio->:=1
` ...
End case
ラジオボタンの番号が、“設定”フィールドに記憶される必要があります。これは、フォームメソッドでOn Clickedイベントに対し以下の行を加えると実現できます。
[Preferences]Setting:=Button1+(Button2*2)+(Button3*3)+(Button4*4)+(Button5*5)
メソッドにポインタを渡す
ポインタを引数としてメソッドに渡すことができます。メソッド内で、ポインタによって参照されるオブジェクトを修正することができます。
例えば、以下のメソッド“Take Two”は、引数に2つのポインタ持ちます。最初の引数は、大文字に変換するオブジェクトを参照します。2番目の引数は小文字に変換するオブジェクトを参照します。次に、そのメソッドを示します。
` TAKE TWO project method ` $1: Pointer to a string field or variable. Change this to uppercase. ` $2: Pointer to a string field or variable. Change this to lowercase. $1->:=Uppercase($1->) $2->:=Lowercase($2->)
以下のステートメントは、フィールド値を大文字に、変数を小文字に変更するためにメソッド“Take Two”を使用します。
TAKE TWO (->[My Table]My Field; ->MyVar)
このフィールド“[MyTable]MyField”が、“jones”であれば、“JONES”に変更されます。一方、変数“MyVar”が“HELLO”であれば、“hello”に変更されます。
メソッド“Take Two”で使用するポインタと、参照されるオブジェクトのデータタイプが一致していることが重要です。この例では、ポインタに対して必ず文字型またはテキスト型のオブジェクトを割り当てなければなりません。
ポインタのポインタ
より高度な使い方として、他のポインタを参照するためにポインタを使うことができます。以下の例を考察してください。
MyVar := "Hello" PointerOne := ->MyVar PointerTwo := ->PointerOne (PointerTwo->)-> := "Goodbye" ALERT((Point Two->)->)
この例はアラートボックスに“Goodbye”を表示します。
各行について見ていきましょう。
・MyVar:="Hello"
この行は、変数MyVarに“Hello”の文字列を代入しています。
・PointerOne:=->MyVar
ポインタ変数PointerOne に、変数MyVarのポインタを代入します。
・PointerTwo:=->PointerOne
新たなポインタ変数PointerTwoにPointerOne変数のポインタを代入します。
・(PointerTwo->)->:="Goodbye"
“PointerTwo->”は、変数PointerOneを示します。“(PointerTwo->)->”は、変数MyVarを示します。結果として、文字列“Goodbye”は、変数MyVarに代入されます。
・ALERT ((PointerTwo->)->)
先の説明と同様に“(PointerTwo->)->”は変数MyVarを示すので、結果としてアラートボックスには変数MyVarの内容が表示されます。
以下の例では、変数MyVarに“Hello”が代入されます。
(PointerTwo->)->:="Hello"
以下の例では、変数NewVarに変数MyVarの値である“Hello”が代入されます。
NewVar:=(PointerTwo->)->
重要: 複数の参照には括弧が必要です。
参照
データタイプ, メソッド, 演算子, 識別子, 制御フロー, 定数, 配列, 配列とポインタ, 変数.