Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

WHILE

条件が True のときに、コードを実行します。

Synopsis

WHILE expression,... {
  code
}

引数

expression テスト条件。1 つ、または複数のコンマ区切りのテスト条件を指定することができます。それらはすべて、コード・ブロックの実行に対して True でなければなりません。
code 中括弧で囲まれた ObjectScript コマンドのブロックです。

概要

WHILEexpression をテストし、expression が TRUE と評価された場合に、開き中括弧と閉じ中括弧の間のコード・ブロック (1 つ以上のコマンド) を実行します。WHILE は、expression が TRUE と評価されている限り、コードのブロックを繰り返し実行します。expression が True でない場合、中括弧内のコード・ブロックは実行されず、閉じ中括弧 ( } ) に続く次のコマンドが実行されます。

プログラマは WHILE の無限ループを回避するために、注意を払う必要があります。

開き中括弧や閉じ中括弧は、1 行で独立して記述するか、コマンドと同じ行に記述できます。開き中括弧や閉じ中括弧は、列 1 に記述してもかまいませんが、お勧めはできません。推奨されるプログラミング手法として、入れ子になったコード・ブロックの開始と終了を示すために、中括弧はインデントするようにしてください。開き中括弧の前後に空白を入れる必要はありません。閉じ中括弧の前に空白を入れる必要はありません。引数のないコマンドに続く中括弧の場合も同様です。中括弧の空白に関する唯一の要件は、閉じ中括弧とその後のコマンドを、スペース、タブ、または改行で区切る必要があるということです。

中括弧内のコードのブロックは、1 つ以上の ObjectScript コマンドと関数の呼び出しで構成される可能性があります。コード・ブロックは複数行にわたる場合があります。インデント、改行、空白スペースは、コード・ブロック内で許可されています。コード・ブロック内のコマンドとコマンド内の引数は、1 つ以上の空白スペース、または改行で分けられます。

引数

expression

ブーリアンのテスト条件。単一の式かコンマで区切られた式のリストの形式をとります。expression を TRUE (ゼロ以外の数値) として評価した場合、Caché は WHILE ループを実行します。通常、expression は x<10 や "apple"="apple" などの条件テストですが、ゼロ以外の数値に評価される値はすべて TRUE になります。例えば、7、00.1、“700”、“7dwarves” などは、すべて TRUE と評価されます。ゼロに評価される値はすべて FALSE になります。例えば、0、-0、および非数値文字列は、すべて FALSE と評価されます。

expression リストでは、Caché は左から右の順で、個別の式を評価します。0 (FALSE) に評価される式に遭遇すると、評価を終了します。FALSE に評価される式の右側にある式には、検証やテストが実施されません。

すべての式がゼロ以外の数値 (TRUE) に評価される場合、Caché は WHILE ループ・コード・ブロックを実行します。expression が TRUE に評価されている限り、Caché は各ループの先頭で expression をテストしながら、WHILE ループを繰り返し実行します。式が FALSE に評価されると、Caché は、WHILE の閉じ中括弧の後の、次のコード行を実行します。

以下の例では、WHILE ループを指定した回数実行します。ループを実行する前に、expression がテストされます。

Mainloop
   SET x=1
   WHILE x<10 {
      WRITE !," Looping",x
      SET x=x+1
   }
   WRITE !,"DONE"
   QUIT

以下の 2 つの例では、2 つの expression テストを実行します。2 つのテストはコンマで区切られています。両方のテストが True に評価される場合、WHILE ループが実行されます。そのため、これらのプログラムは、リストのすべての項目、またはリスト内の指定のサンプル・サイズの項目を返します。

  SET mylist=$LISTBUILD("a","b","c","d","e")
  SET ptr=0,sampcnt=1,sampmax=4
  WHILE 1=$LISTNEXT(mylist,ptr,value),sampcnt<sampmax {
    WRITE value," is item ",sampcnt,!
    SET sampcnt=sampcnt+1
  }
  IF sampcnt<sampmax {WRITE "This is the whole list"}
  ELSE {WRITE "This is a ",sampcnt-1," item sample of the list"}
  SET mylist=$LISTBUILD("a","b","c","d","e")
  SET ptr=0,sampcnt=1,sampmax=10
  WHILE 1=$LISTNEXT(mylist,ptr,value),sampcnt<sampmax {
    WRITE value," is item ",sampcnt,!
    SET sampcnt=sampcnt+1
  }
  IF sampcnt<sampmax {WRITE "This is the whole list"}
  ELSE {WRITE "This is a ",sampcnt-1," item sample of the list"}

メモ

WHILE と DO WHILE

WHILE コマンドは、ループを実行する前に expression をテストします。DO WHILE コマンドはループを一度実行し、そして expression をテストします。

WHILE および CONTINUE

WHILE コマンドのコード・ブロック内で CONTINUE コマンドに出会うと、実行が即座に WHILE コマンドに戻ります。次に WHILE コマンドは expression テスト条件を評価し、その評価を基にしてコード・ブロック・ループを再実行するかどうかを決定します。したがって、CONTINUE コマンドの実行にはコード・ブロックの終了中括弧に到達するのとまったく同じ効果があります。

WHILE、QUIT、RETURN

code ブロック内の QUIT コマンドは WHILE ループを終了させ、終わりの中括弧に続くコマンドに制御を渡します。以下はその例です。

Testloop
   SET x=1
   WHILE x < 10
   {
      WRITE !,"Looping",x 
      QUIT:x=5
      SET x=x+1 
    }
    WRITE !,"DONE"

このプログラムは、Looping1 から Looping5 までを書き込み、その後 DONE を書き込みます。

WHILE コード・ブロックは入れ子にできます。つまり、WHILE コード・ブロックに、別のフロー制御ループ (別の WHILE、あるいは FOR または WHILE コード・ブロック) を含むことができます。内側の入れ子となったループの QUIT では、内側のループが終了して、そのループの外側のループに実行が移ります。詳細は、以下の例を参照してください。

Nestedloops
  SET x=1,y=1
  WHILE x<6 {
     WRITE "outer loop ",!
     WHILE y<100 {
        WRITE "inner loop " 
        WRITE " y=",y,!
        QUIT:y=7
        SET y=y+2 
        }
     WRITE "back to outer loop x=",x,!!
     SET x=x+1 
     }
  WRITE "Done"

RETURN を使用すると、WHILE ループや入れ子のループ構造内を含む任意の場所からルーチンの実行を終了させることができます。RETURN は常に現在のルーチンを終了し、呼び出し元のルーチンに戻るか、呼び出し元のルーチンがない場合はプログラムを終了します。RETURN は、コード・ブロック内から発行されたかどうかに関係なく、常に同じ動作を行います。

WHILE と GOTO

コード・ブロック内の GOTO コマンドは、ループ外のラベルへ実行を移動しループを終了します。同じコード・ブロック内のラベルに実行を移動することもあります。この場合、ラベルは入れ子にされたコード・ブロックに存在します。

GOTO コマンドでは、別のコード・ブロック内のラベルに実行を移すことはできません。このような構造を実行することはできますが、移動先のコード・ブロックのテスト条件が無効になるため、“不正” と見なされます。

以下は、適切な GOTO の形式です。

mainloop ; GOTO to outside of the code block
  WHILE 1=1 {
      WRITE !,"In an infinite WHILE loop"
      GOTO label1
      WRITE !,"This should not display"
  } 
  WRITE !,"This should not display"
label1
  WRITE !,"Went to label1 and quit"
mainloop ; GOTO to elsewhere within the same code block
  SET x=1
  WHILE x<3 {
      WRITE !,"In the WHILE loop"
      GOTO label1
      WRITE !,"This should not display"
label1
      WRITE !,"Still in the WHILE loop after GOTO"
      SET x=x+1
      WRITE !,"x=",x
      }
  WRITE !,"WHILE loop done" 
mainloop ; GOTO from an inner to an outer nested code block
   SET x=1,y=1
   WHILE x<6 {
     WRITE !,"Outer loop",!
     SET x=x+1
label1
     WRITE "outer loop iteration ",x-1,!
        WHILE y<4 {
           WRITE !,"   Inner loop iteration ",y,!
           SET y=y+1
           WRITE "   return to "
           GOTO label1
           WRITE "   This should not display",!
        }
   WRITE "Inner loop completed",!
   }
   WRITE "All done"
mainloop ; GOTO from an outer to an inner nested code block
   SET x=1,y=1
   WHILE x<6 {
     WRITE !,"Outer loop",!
     SET x=x+1
     WRITE "outer loop iteration ",x-1,!
     WRITE "Jumping into the "
     GOTO label1
     WRITE "This should not display",!
         WHILE y<4 {
           WRITE !,"   Inner loop iteration ",y,!
           SET y=y+1
label1
           WRITE "inner loop ",!
        }
   WRITE "Inner loop completed",!
   }
   WRITE "All done"

以下の形式の GOTO は実行可能ですが、GOTO の移動先ブロックの条件テストが無効になる (無視される) ため、“不正” と見なされます。

mainloop ; GOTO into a code block
  SET x=1
  WRITE "Jumped into the "
  GOTO label1
  WHILE x>1,x<6 {
      WRITE "Top of WHILE loop x=",x,!
label1
      WRITE "Bottom of WHILE loop x=",x,!!
      SET x=x+1
  }
mainloop ; GOTO from a code block into an IF clause block
  SET x=1
  WHILE x<6 {
      WRITE !,"WHILE loop interation=",x,!
      SET x=x+1
      GOTO label1
      WRITE "This should never display",!
    IF x#2 { WRITE "in the IF clause",!
label1
    WRITE "GOTO entry into the IF clause",!
    WRITE x," is an odd number",!
    }
    ELSE {WRITE "in the ELSE clause",!
          WRITE x," is an even number",! }
  WRITE "Bottom of WHILE loop",!
  }
    WRITE "All done"

関連項目

FeedbackOpens in a new tab