編製索引條款 (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是一次行程迴圈。 - 如果迴圈透過
BREAK或END 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、J 及 K 分別設為 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 FILE。END 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.
- 如果透過
BREAK或END LOOP陳述式上的條件式子句結束迴圈,則不會更新反覆運算變數。 - 如果
LOOP陳述式同時包含索引子句及條件式子句,則會先執行索引子句,而且不論哪個子句導致迴圈終止,都會更新實際反覆運算變數。
下面顯示此範例的輸出。
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