19.FOR/ENDFOR命令

FOR/ENDFOR命令は、FOR命令とENDFOR命令で囲まれた区間であるFOR/ENDFOR区間を任意の回数繰り返す命令です。

19.1.概要

FOR/ENDFOR命令には、FOR命令とENDFOR命令の2つの命令があります。

  • FOR命令 - FOR/ENDFOR区間の開始を示します。

  • ENDFOR命令 - FOR/ENDFOR区間の終了を示します。

FOR命令とENDFOR命令の間にある命令が繰り返し実行されます。繰り返しの回数はFOR命令で指定された値で決まります。

19.2.仕様

19.2.1.FOR命令の形式

FOR命令の形式を以下に示します。

カウンタにはレジスタを使用します。初期値には、定数、レジスタ、ヒキスウを使用します。定数には-32767から32766までの整数が指定できます。目標値には、定数、レジスタ、ヒキスウを使用します。定数には-32767から32766までの整数が指定できます。

19.2.2.FOR命令の実行

FOR命令が実行された時、カウンタの値に初期値が代入されます。FOR/ENDFOR区間が実行されるためには、以下の条件が満たされる必要があります。

  • TOを指定した場合、初期値が目標値以下である。

  • DOWNTOを指定した場合、初期値が目標値以上である。

この条件が満たされない場合は、カーソルは対応するENDOFR命令の次の行に移動し、FOR/ENDFOR区間は実行されません。FOR命令は、1つのFOR/ENDOFOR区間で一度だけ実行されることになリます。

19.2.3.ENDFOR命令の形式

ENDFOR命令の形式を以下に示します。

19.2.4.ENDFOR命令の実行

ENDFOR命令実行時に、以下の条件が満たされる限り、FOR/ENDOFOR区間が繰り返されます。

  • TOを指定した場合、カウンタの値が目標値より小さい。

  • DOWNTOを指定した場合、カウンタの値が目標値よりも大きい。

この条件が満たされる場合は、TOを指定した場合はカウンタの値を1増加させます。DOWNTOを指定した場合はカウンタの値を1減少させます。また、カーソルは対応するFOR命令の次の行に移動し、FOR/ENDFOR区間が再度実行されます。この条件が満たされない場合は、カーソルは次の行に移動し、FOR/ENDFOR区間の実行は終了します。

FOR/ENDFOR命令は、連続してループ処理が実行される場合には内部で自動的に待ちが入ります。そのため、FOR/ENDFOR命令の区間内に待機命令を教示する必要はありません。

19.3.教示

19.3.1.FOR/ENDFOR命令の教示方法

FOR/ENDFOR命令の教示方法を以下に示します。

操作10.FOR/ENDFOR命令の教示

  1. この例では、1行目と5行目に空白行を挿入します。

  2. カーソルを1行目に移動し、F1[命令]を押します。

  3. 「FOR/ENDFOR」を選択します。

  4. 「FOR」を選択します。FOR命令が教示されます。

  5. カーソルが自動的にレジスタに移動します。ここでは、1を入力します。

  6. カーソルが自動的に初期値に移動します。ここでは「定数」を選択し、1を入力します。レジスタ、あるいは引数を使用する場合は、F4[選択]を押し選択してください。

  7. カーソルが自動的にTOに移動します。ここでは入力を押します。DOWNTOを使用する場合は、F4[選択]を押してDOWNTOを選択してください。

  8. カーソルが自動的に目標値へ移動します。ここではレジスタを選択します。「レジ[ ]」を選択します。レジスタ番号には2を入力します。

  9. カーソルを5行目に移動し、F1[命令]を押します。

  10. 「FOR/ENDFOR」を選択します。

  11. 「ENDFOR」を選択します。ENDFOR命令が教示されます。

19.3.2.FOR/ENDFOR命令の組み合わせ

FOR命令とENDFOR命令の組み合わせは自動的に決まります。FOR/ENDFOR命令の組み合わせは、最寄りのFOR命令とENDFOR命令から順番に決定されます。FOR/ENDFOR区間の中でさらにFOR/ENDFOR命令を教示することで、ネスト構造を形成することができます。ネスト構造は、最大で10階層まで形成することが可能です。10階層を超えて教示した場合は、実行時にアラームが発生します。

FOR命令とENDFOR命令は同一プログラム上で、同数存在する必要があります。どちらか一方が不足している状態では、実行時にアラームが発生します。アラームの詳細については、19.5."アラーム"で説明します。組み合わせが決定する方法を、以下のプログラムを用いて説明します。1行目にFOR命令を教示します。この状態では、プログラム中でFOR命令とENDFOR命令の数が一致しないため、実行時に「ジッコウ-670 1行目のFORに対するENDFORが必要です」というアラームが発生します。

6行目にENDFOR命令を教示します。すると、1行目のFOR命令と6行目のENDFOR命令でFOR/ENDFOR区間が形成されます。

次に3行目にFOR命令を教示します。この状態では、ENDFOR命令が不足するため、実行時に「ジッコウ-670 1行目のFORに対するENDFORが必要です」というエラーが発生します。

8行目にENDFOR命令を教示します。FOR/ENDFOR命令の組み合わせは、最寄りのFOR命令とENDFOR命令から順番に決定されます。そのため、この場合はまず3行目のFOR命令と6行目のENDFOR命令でFOR/ENDFOR区間が形成され、次に1行目のFOR命令と8行目のENDFOR命令でFOR/ENDFOR区間が形成されることになります。この状態では、2階層のネスト構造が形成されることになります。

1つのネスト構造の中で、カウンタに同じレジスタを重複して使用しないよう注意してください。正常に動作しない可能性があります。

19.4.実行例

19.4.1.後退実行

FOR/ENDFOR命令は後退実行することはできません。しかし、FOR/ENDFOR区間内の命令を後退実行することができます。以下の例では、1行目と5行目を後退実行すると、「ジッコウ-238 後退が終了しました」というアラームが発生します。一方で、2、3、4、6行目は後退実行が可能です。

19.4.2.実行例

FOR/ENDFOR命令実行時のカウンタの値の変化を以下のプログラムを用いて説明します。

レジ[2]=3の場合:TOを使用し、初期値が目標値以下のため、FOR命令の条件が満たされます。カウンタは1から3まで変化するため、FOR/ENDFOR区間は3回実行されます。

レジ[2]=1の場合:TOを使用し、初期値が目標値以下のため、FOR命令の条件は満たされます。しかし、カウンタ値が目標値と同値のため、ENDFOR命令は満たされません。その結果、FOR/ENDFOR命令区間は1度だけ実行されることになります。

レジ[2]=0の場合:TOを使用し、初期値が目標値より大きいため、FOR命令の条件は満たされません。カーソルは5行目のENDFOR命令の次の行である6行目に移動し、FOR/ENDFOR区間は実行されません。

FOR/ENDFOR区間の途中から実行、レジ[1]=0の場合:カウンタに使用されているレジ[1]の値に0が格納されているとします。以下のプログラムを3行目から実行した場合、5行目のENDFOR命令の条件を満たすため、0から3までの4回FOR/ENDFOR区間が繰り返されることになります。

FOR/ENDFOR区間の途中から実行:レジ[1]=5の場合:カウンタに使用されているレジ[1]の値に5が格納されているとします。以下のプログラムを3行目から実行した場合、5行目のENDFOR命令の条件が満たされないため、FOR/ENDFOR区間の実行は終了します。

FOR/ENDFOR区間の途中にジャンプ/ラベル命令がある場合:FOR/ENDFOR区間の途中にジャンプ/ラベル命令を持つ、以下のプログラムを実行した場合の挙動を説明します。3行目のジャンプ命令により、7行目のラベル[1]にジャンプします。その結果、1行目から4行目までのFOR/ENDFOR区間の実行は終了します。また、ジャンプ先もFOR/ENDFOR区間中であるため、8行目のENDFOR命令で条件の判定が行われます。8行目のENDFOR命令に対応するFOR命令は5行目のFOR命令であり、レジ[2]の値は0であるため、8行目のENDFOR命令の条件は満たされます。その結果、5行目から8行目までのFOR/ENDFOR区間が繰り返し実行されることになります。

FOR/ENDFOR区間中でジャンプ/ラベル命令を使用する場合には、区間中の挙動を十分に検討する必要があります。さもなければ、重大な問題が発生する可能性があります。

FOR/ENDFOR区間中でカウンタの値を修正する場合:FOR/ENDFOR区間中でカウンタの値を修正することができます。以下のプログラムでは、DI[1]がオンである場合、6行目でレジ[1]の値が11になります。この値は目標値よりも大きいため、ENDFOR命令の条件は満たされず、カーソルはENDFOR命令の次の行へ移動します。

FOR/ENDFOR区間中で、カウンタで使用されているレジスタの値を書き換えると、FOR/ENDFOR命令が正常に動作しない、または無限にFOR/ENDFOR区間が繰り返される恐れがあります。初期値や目標値でレジスタを指定した場合、その値をFOR/ENDFOR区間中で書き換えると、FOR/ENDFOR命令が正常に動作しない恐れがあります。

FOR/ENDFOR区間中でカウンタの値が計算により変化する場合:以下のプログラムでは、5行目でカウンタの値が計算され変化しています。最終的にカウンタの値は11になります。この値は目標値とは異なりますが、正しい結果となります。

この結果は、以下で説明されます。

  • 1行目で、レジ[1]の値は初期値6になります。

  • 5行目で、レジ[1]の値は7になります。

  • 6行目で、レジ[1]の値は7なので、ENDFOR命令の条件は満たされます。その後レジ[1]の値は8になります。

  • 5行目で、レジ[1]の値は9になります。

  • 6行目で、レジ[1]の値は9なので、ENDFOR命令の条件は満たされます。その後レジ[1]の値は10になります。

  • 5行目で、レジ[1]の値は11になります。

  • 6行目で、レジ[1]の値は11なので、ENDFOR命令の条件は満たされず、カーソルは次の行に移動します。

  • これにより、レジ[1]の値は最終的に11になります。

カウンタに用いるレジスタを計算で使用すると、アラームが発生することがあります。カウンタを計算した場合には、FOR/ENDFOR命令の直前で以下の様にDIVを用いるか、あるいはデータ画面で同じ値を入力することで、この問題を防止することができます。特に、実数との計算や、除算を用いる場合は必ず以下の様にDIVを用いてください。

レジ[1]=レジ[1] DIV 1

19.5.アラーム

FOR/ENDFOR命令では、以下の状況でアラームが発生します。

  • FOR命令がENDFOR命令に対して少ない状態で実行

  • ENDFOR命令がFOR命令に対して少ない状態で実行

  • ネスト構造の階層が10を超えている状態で実行

  • FOR命令実行時に初期値または目標値に整数以外を使用

  • ENDFOR命令実行時にカウンタの値または目標値に整数以外を使用

  • FOR命令がENDFOR命令に対して少ない状態で実行:以下のプログラムを実行します。5行目のENDFOR命令に対するFOR命令が存在しないため、プログラム実行時に「ジッコウ-669 5行目のENDFORに対するFORが必要です」というアラームが発生します。

  • ENDFOR命令がFOR命令に対して少ない状態で実行:以下のプログラムを実行します。1行目のFOR命令に対するENDFOR命令が存在しないため、プログラム実行時に「ジッコウ-670 1行目のFORに対するENDFORが必要です」というアラームが発生します。

  • ネスト構造の階層が10を超えている状態で実行:プログラム実行時に“ジッコウ-671 FORが多すぎます”というアラームが発生します。

  • FOR命令実行時に初期値または目標値に整数以外を使用

  • ENDFOR命令実行時にカウンタの値または目標値に整数以外を使用:以下のプログラムを実行します。2行目のFOR命令の目標値が整数ではありません。2行目を実行時に“ジッコウ-672 (プログラム, 2)整数以外の型が使用されています”というアラームが発生します。

    カウンタ、初期値、目標値に用いるレジスタを計算で使用すると、計算結果やデータ画面上の値が整数であるにもかかわらず、上記のアラームが発生することがあります。カウンタ、初期値、目標値に用いるレジスタを計算した場合には、FOR/ENDFOR命令の直前で以下の様にDIVを用いるか、あるいはデータ画面で同じ値を入力することで、この問題を防止することができます。特に、実数との計算や、除算を用いる場合は必ず以下の様にDIVを用いてください。

    レジ[1]=レジ[1] DIV 1