FreeBASIC マニュアルのトップに戻る

FreeBASIC OpStep

目次演算子反復演算子Operator Step (Iteration)←オリジナル・サイト

演算子 Step (繰り返し) 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい


For...Next ループの反復子を、増やします。

構文:
{ Type | Class | Union } typename
declare operator Step ()
declare operator Step ( [ byref | byval ] stp as typename )
...
End { Type | Class | Union }

用法:
For iterator [ As typename ] = start_value To end_value [ Step step_value ]
[ ...statements... ]
Next

パラメタ:
(引数を含む)
typename
Type か、Class か、Union の名前
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_valuestep_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


方言差:
参照:
反復演算子 に戻る
演算子 に戻る
←リンク元に戻る プログラム開発関連に戻る
ページ歴史:2021-09-04 00:47:18
日本語翻訳:WATANABE Makoto、原文著作者:LaananFisher

ホームページのトップに戻る

表示-非営利-継承