編製索引條款 (LOOP-END LOOP 指令)

檢索子句會指定程式在迴圈結構內執行指令的次數,以限制迴圈的反覆運算次數。 索引子句在 LOOP 指令上指定,並包含索引變數,後面接著起始值和終端機值。

  • 程式會將 檢索變數 設為 起始值 ,並在每次針對觀察值執行迴圈時將它增加指定的增量。 當檢索變數達到指定的 終端機值時,該情況會終止迴圈。
  • 依預設,程式會針對每一個反覆運算,將索引變數增加 1。 關鍵字 BY 會置換此增量。
  • 索引變數可以具有任何有效的變數名稱。 除非您指定標為暫時刪除變數,否則索引變數會被視為永久變數並儲存在作用中資料集中。 如果為索引變數指派與現有變數相同的名稱,則現有變數的值會在執行時由 LOOP 結構變更,且原始值會遺失。 如需相關資訊,請參閱 建立資料 (LOOP-END LOOP 指令) 主題。
  • 檢索子句會置換 SET MXLOOPS指定的迴圈數目上限。
  • 索引子句的起始值和終止值可以是數值表示式。 接受非整數及負表示式。
  • 如果起始值的表示式大於終端機值,則不會執行迴圈。 例如,如果 X 為 0 且 Y 為 -1 ,則 #J=X TO Y 是零行程迴圈。
  • 如果起始值和終止值的表示式相等,則會執行一次迴圈。 當 Y 為 0 時, #J=0 TO Y 是一次行程迴圈。
  • 如果迴圈透過 BREAKEND LOOP 陳述式上的條件式子句結束,則不會更新反覆運算變數。 如果 LOOP 陳述式同時包含索引子句及條件式子句,則會先執行索引子句,並更新反覆運算變數,而不管哪一個子句導致迴圈終止。

範例

LOOP #I=1 TO 5. /*LOOP FIVE TIMES
COMPUTE X=X+1.
END LOOP.
  • 標為暫時刪除變數 #I (編製索引變數) 會設為起始值 1 ,並在每次針對觀察值執行迴圈時增加 1。 當 #I 增加超過終端機值 5 時,不會執行進一步迴圈。 因此,每個觀察值的 X 值都會增加 5。

範例

LOOP #I=1 TO 5 IF (Y GT 10). /*Loop to X=5 only if Y GT 10
COMPUTE X=X+1.
END LOOP.
  • 檢索子句和 IF 子句都指定在 LOOP上。 對於 Y 大於 10 的所有觀察值, X 會增加 5。

範例

LOOP #I=1 TO Y. /*Loop to the value of Y
COMPUTE X=X+1.
END LOOP.
  • 觀察值的反覆運算次數取決於該觀察值的變數 Y 值。 對於變數 Y的值為 0 的觀察值,不會執行迴圈,且 X 不會變更。 對於變數 Y的值為 1 的觀察值,迴圈會執行一次,且 X 會增加 1。

範例

* Factorial routine.
 
DATA LIST FREE / X.
BEGIN DATA
1 2 3 4 5 6 7
END DATA.
 
COMPUTE FACTOR=1.
LOOP #I=1 TO X.
COMPUTE FACTOR=FACTOR * #I.
END LOOP.
LIST.
  • 迴圈結構會將 FACTOR 計算為 X的階乘值。

範例

* Example of nested loops: 
  compute every possible combination of values for each variable.
 
INPUT PROGRAM.
-LOOP #I=1 TO 4. /* LOOP TO NUMBER OF VALUES FOR I
- LOOP #J=1 TO 3. /* LOOP TO NUMBER OF VALUES FOR J
-  LOOP #K=1 TO 4. /* LOOP TO NUMBER OF VALUES FOR K
-   COMPUTE I=#I.
-   COMPUTE J=#J.
-   COMPUTE K=#K.
-   END CASE.
-  END LOOP.
- END LOOP.
-END LOOP.
END FILE.
END INPUT PROGRAM.
LIST. 
  • 第一個迴圈會反覆運算四次。 第一個疊代會將檢索變數 #I 設為等於 1 ,然後將控制權傳遞給第二個迴圈。 #I 會保留 1 ,直到第二個迴圈完成其所有反覆運算為止。
  • 第二個迴圈會執行 12 次,每一個 #I值執行三次。 第一次反覆運算會將索引變數 #J 設為等於 1 ,然後將控制權傳遞給第三個迴圈。 #J 會維持 1 ,直到第三個迴圈完成其所有反覆運算為止。
  • 第三個迴圈會產生 48 次反覆運算 (4 × 3 × 4)。 第一個疊代集 #K 等於 1。 COMPUTE 陳述式會將變數 I、JK 分別設為 1 ,且 END CASE 會建立觀察值。 第三個迴圈會第二次反覆運算,將 #K 設為等於 2。 然後會分別以值 1、1、2 來計算變數 I、J K ,並建立第二個觀察值。 第三次迴圈的第三次和第四次反覆運算會產生分別等於 1、1、3 和 1、1、4 的 I、J、K的觀察值。 在第三個迴圈中的第四個反覆運算之後,控制會傳回第二個迴圈。
  • 再次執行第二個迴圈。 #I 會保留 1 ,而 #J 會增加至 2 ,且控制會回到第三個迴圈。 第三個迴圈會完成其反覆運算,導致 等於 1、 J 至 2 ,以及 K 從 1 增加至 4 的另外四個觀察值。 第三次執行第二個迴圈,導致 I= 1、 J= 3 及 K 從 1 增加至 4 的觀察值。 當第二個迴圈完成三個反覆運算之後,控制會回到第一個迴圈,並針對 #I的下一個增量重複整個循環。
  • 第一個迴圈完成四個反覆運算之後,控制會從迴圈結構傳遞至 END FILEEND FILE 會將產生的觀察值定義為資料檔,輸入程式會終止,並執行 LIST 指令。
  • 這個範例不需要 LEAVE 指令,因為反覆運算變數是標為暫時刪除變數。 如果反覆運算變數是 I、J、K,則需要 LEAVE ,因為在每一個 END CASE 指令之後都會重新起始設定這些變數。

範例

* Modifying the loop iteration variable.
 
INPUT PROGRAM.
PRINT SPACE    2.
LOOP           A = 1 TO 3. /*Simple iteration
+  PRINT          /'A WITHIN LOOP: ' A(F1).
+  COMPUTE        A = 0.
END LOOP.
PRINT          /'A AFTER LOOP:  ' A(F1).
 
NUMERIC        #B.
LOOP           B = 1 TO 3. /*Iteration + UNTIL
+  PRINT          /'B WITHIN LOOP: ' B(F1).
+  COMPUTE        B = 0.
+  COMPUTE        #B = #B+1.
END LOOP       IF #B = 3.
PRINT          /'B AFTER LOOP:  ' B(F1).
 
NUMERIC        #C.
LOOP           C = 1 TO 3 IF #C NE 3. /*Iteration + WHILE
+  PRINT          /'C WITHIN LOOP: ' C(F1).
+  COMPUTE        C = 0.
+  COMPUTE        #C = #C+1.
END LOOP.
PRINT          /'C AFTER LOOP:  ' C(F1).
 
NUMERIC        #D.
LOOP           D = 1 TO 3. /*Iteration + BREAK
+  PRINT          /'D WITHIN LOOP: ' D(F1).
+  COMPUTE        D = 0.
+  COMPUTE        #D = #D+1.
+  DO IF          #D = 3.
+     BREAK.
+  END IF.
END LOOP.
PRINT          /'D AFTER LOOP:  ' D(F1).
 
LOOP           E = 3 TO 1. /*Zero-trip iteration
+  PRINT          /'E WITHIN LOOP: ' E(F1).
+  COMPUTE        E = 0.
END LOOP.
PRINT          /'E AFTER LOOP:  ' E(F1).
END FILE.
END INPUT PROGRAM.
EXECUTE.
  • 如果透過 BREAKEND LOOP 陳述式上的條件式子句結束迴圈,則不會更新反覆運算變數。
  • 如果 LOOP 陳述式同時包含索引子句及條件式子句,則會先執行索引子句,而且不論哪個子句導致迴圈終止,都會更新實際反覆運算變數。

下面顯示此範例的輸出。

圖 1. 修改迴圈反覆運算值

A WITHIN LOOP: 1
A WITHIN LOOP: 2
A WITHIN LOOP: 3
A AFTER LOOP:  4
B WITHIN LOOP: 1
B WITHIN LOOP: 2
B WITHIN LOOP: 3
B AFTER LOOP:  0
C WITHIN LOOP: 1
C WITHIN LOOP: 2
C WITHIN LOOP: 3
C AFTER LOOP:  4
D WITHIN LOOP: 1
D WITHIN LOOP: 2
D WITHIN LOOP: 3
D AFTER LOOP:  0
E AFTER LOOP:  3