目次→
演算子→
反復演算子→
Operator Step (Iteration)←オリジナル・サイト
For...Next ループの反復子を、増やします。
構文:
用法:
For iterator [ As typename ] = start_value To end_value [ Step step_value ]
[ ...statements... ]
Next
パラメタ:
(引数を含む)
typename
stp,
step_value
typename オブジェクトで、増分の値として使われる
iterator
typename オブジェクトで、反復子として使われる
end_value
typename オブジェクトで、ループを終える値として使われる
start_value
typename オブジェクトで、コピー構築するか、または反復子に最初に割り当てるために使われる。
記述:
演算子 For,
演算子 Next,
演算子 Step は、ユーザ定義型の定義で、多重定義できます。
そして、ユーザ定義型のオブジェクトを、
For...Next ループの反復子と増分値として使えるようにします。
すべての非静的メンバー手続きとして、これらは、3つの演算子のコード本体の、反復子オブジェクトへの参照によってアクセスできる、非表示の
this パラメーターを渡しました。
演算子 Step は、
For...Next 内のすべての命令文が実行された直後に、反復子オブジェクトを増加させるために呼び出されます。
演算子 Step の最初の構文は、
For...Next 命令文で step 値が指定されていない場合に、使われます。
step 値が指定されている場合、第2の構文が使われ、step 値が渡されて反復子オブジェクトが増分されます。
高度な使用法
上の説明は、3つの引数
start_value,
end_value,
step_value は
反復子 と同じ型でなければならない(これは明白な使用法です)ことを暗示しているようですが、完全に真実とはかぎりません:
-
start_value, end_value, step_value 引数は、任意の型にすることができます(それらの間で異なる型で、反復子 の 1つと異なる型も可能です)。
-
唯一の制約は、反復子 は、start_value 引数から構築(ローカル 反復子 の場合)するか割り当てる(グローバル 反復子 の場合)ことです。(反復子 は暗黙的に構築または内部で割り当てられるためです。)
-
同様に、他のパラメーター end_value と step_value は、反復子 と同じ型のオブジェクトに変換できる必要があります。
例:
'' 型の例
Type T
'' 値は、構築子によって設定されます
value As Double
Declare Constructor( ByVal x As Double = 0 )
Declare Operator For( ByRef stp As T )
Declare Operator Step( ByRef stp As T )
Declare Operator Next( ByRef cond As T, ByRef stp As T ) As Integer
End Type
Constructor T ( ByVal x As Double )
Print "T iterator constructed with value " & x
value = x
End Constructor
Operator T.for( ByRef stp As T )
End Operator
Operator T.step( ByRef stp As T )
Print " incremented by " & stp.value & " in step."
value += stp.value
End Operator
Operator T.next( ByRef cond As T, ByRef stp As T ) As Integer
'' 反復子は、大きい値から小さい値に移ります。(step >= 0)
If( stp.value < 0 ) Then
Return( value >= cond.value )
Else
'' 反復子は、小さい値から大きい値に移ります。(step < 0)
Return( value <= cond.value )
End If
End Operator
'' 使用例:数を用いて作業しているように見えます。
'' しかし、反復子は構築子で多重定義されています。10、1、-1 は、型T のすべてです。
For i As T = 10 To 1 Step -1
Print i.value;
Next i
Sleep
cha0s のファイル反復クラス∞ に基づいた、ファイル反復を実証するより多くの実例。
'' ファイルを終わりまで繰り返すクラス
Type FileIter
As String pathName, fileName
Declare Constructor( ByRef pathName As String )
Declare Operator For()
Declare Operator Step()
Declare Operator Next( ByRef endCond As FileIter) As Integer
End Type
Constructor FileIter( ByRef pathName As String )
This.pathName = pathName
End Constructor
Operator FileIter.for( )
fileName = Dir(pathName & "/*.*")
End Operator
Operator FileIter.step( )
fileName = Dir("")
End Operator
Operator FileIter.next( ByRef endCond As FileIter ) As Integer
Return(fileName <> endCond.pathName)
'' the c'tor sets the path name and so we check against that
End Operator
'' example code
'' change it to any directory
For i As FileIter = "./" To ""
Print i.fileName
Next
もう一つの例は、文字列で働きます:
Type CharIterator
'' used to build a step var
Declare Constructor( ByVal r As ZString Ptr )
'' implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As CharIterator ) As Integer
'' explicit step versions
Declare Operator For ( ByRef step_var As CharIterator )
Declare Operator Step( ByRef step_var As CharIterator )
Declare Operator Next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
'' give the current "value"
Declare Operator Cast( ) As String
Private:
'' data
value As String
'' このメンバーは必要でありません。
'' 我々は、各々の繰り返しにステップ変数を使うことができます。
'' しかし、我々はこの方法を選びます。
'' 文字列の比較をしたくないからです。下記参照。
is_up As Integer
End Type
Constructor CharIterator( ByVal r As ZString Ptr )
value = *r
End Constructor
Operator CharIterator.cast( ) As String
Operator = value
End Operator
'' implicit step versions
''
'' この例では、陰のステップを、
'' 常に 'up' の意味で解釈します
Operator CharIterator.for( )
Print "implicit step"
End Operator
Operator CharIterator.step( )
value[0] += 1
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator ) As Integer
Return This.value <= end_cond.value
End Operator
'' explicit step versions
''
'' この例では、FORで、方向を計算します。
'' しかし、ステップ変数が、各演算子に渡されるので、
'' これを計算するために 高速な"on-the-fly" の選択肢があります。
'' このような文字列のために、繰り返しの比較は、不利益です。
'' しかし、より単純な型を使うと、
'' 'is_up' 変数のオーバーヘッドを避けることができます。
Operator CharIterator.for( ByRef step_var As CharIterator )
Print "explicit step"
is_up = (step_var.value = "up")
End Operator
Operator CharIterator.step( ByRef step_var As CharIterator )
If( is_up ) Then
value[0] += 1
Else
value[0] -= 1
End If
End Operator
Operator CharIterator.next( ByRef end_cond As CharIterator, ByRef step_var As CharIterator ) As Integer
If( This.is_up ) Then
Return This.value <= end_cond.value
Else
Return This.value >= end_cond.value
End If
End Operator
For i As CharIterator = "a" To "z"
Print i; " ";
Next
Print "done"
For i As CharIterator = "a" To "z" Step "up"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "down"
Print i; " ";
Next
Print "done"
For i As CharIterator = "z" To "a" Step "up"
Print i; " ";
Next
Print "done"
Sleep
分数で繰り返す例:
Type fraction
'' Used to build a step var
Declare Constructor( ByVal n As Integer, ByVal d As Integer )
'' Implicit step versions
Declare Operator For ( )
Declare Operator Step( )
Declare Operator Next( ByRef end_cond As fraction ) As Integer
'' Explicit step versions
Declare Operator For ( ByRef step_var As fraction )
Declare Operator Step( ByRef step_var As fraction )
Declare Operator Next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
'' Give the current "value"
Declare Operator Cast( ) As Double
Declare Operator Cast( ) As String
Private:
As Integer num, den
End Type
Constructor fraction( ByVal n As Integer, ByVal d As Integer )
This.num = n : This.den = d
End Constructor
Operator fraction.cast( ) As Double
Operator = num / den
End Operator
Operator fraction.cast( ) As String
Operator = num & "/" & den
End Operator
'' Some fraction functions
Function gcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Dim As Integer t
While m <> 0
t = m
m = n Mod m
n = t
Wend
Return n
End Function
Function lcd( ByVal n As Integer, ByVal m As Integer ) As Integer
Return (n * m) / gcd( n, m )
End Function
''
'' Implicit step versions
''
'' In this example, we interpret implicit step
'' to mean 1
''
Operator fraction.for( )
Print "implicit step"
End Operator
Operator fraction.step( )
Var lowest = lcd( This.den, 1 )
Var mult_factor = This.den / lowest
Dim As fraction step_temp = fraction( 1, 1 )
This.num *= mult_factor
This.den *= mult_factor
step_temp.num *= lowest
step_temp.den *= lowest
This.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction ) As Integer
Return This <= end_cond
End Operator
''
'' Explicit step versions
''
Operator fraction.for( ByRef step_var As fraction )
Print "explicit step"
End Operator
Operator fraction.step( ByRef step_var As fraction )
Var lowest = lcd( This.den, step_var.den )
Var mult_factor = This.den / lowest
Dim As fraction step_temp = step_var
This.num *= mult_factor
This.den *= mult_factor
mult_factor = step_temp.den / lowest
step_temp.num *= mult_factor
step_temp.den *= mult_factor
This.num += step_temp.num
End Operator
Operator fraction.next( ByRef end_cond As fraction, ByRef step_var As fraction ) As Integer
If(( step_var.num < 0 ) Or ( step_var.den < 0 ) ) Then
Return This >= end_cond
Else
Return This <= end_cond
End If
End Operator
For i As fraction = fraction(1,1) To fraction(4,1)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(1,4) To fraction(1,1) Step fraction(1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4) Step fraction(-1,4)
Print i; " ";
Next
Print "done"
For i As fraction = fraction(4,4) To fraction(1,4)
Print i; " ";
Next
Print "done"
Sleep
方言差:
参照: