For loop flow diagram

| 结构 |
| --- |
| do-while |
| while |
| for |
| foreach |
|  |
| * 
* 论
* 编
 |

**for迴圈**（英語：）在電腦科學是一種程式語言的迭代陳述，能夠讓程式碼反覆的執行。

它跟其他的迴圈，如while迴圈，最大的不同，是它擁有一個迴圈計數器，或是迴圈變數。這使得for迴圈能夠知道在迭代過程中的執行順序。

for 迴圈的種類
---------

### 傳統的 for 迴圈 for-loops

C語言中傳統的for-loop包含三個部分：初始化、條件、遞增，這三個部分都是可有可無的。

以Java為例：

```
for (INITIALIZATION; CONDITION; AFTERTHOUGHT) 
{
 // Code for the for-loop's body goes here.
}

```

初始化是宣告（或者賦值）任何需要的變數的動作。如果你要使用多個變數，則變數的種類要一致。條件的部分則是檢查是否離開這個迴圈，也就是讓程式碼往下執行。如果條件判斷為假，則離開迴圈。遞增在每跑一次迴圈都會重複執行一次。 

在此以Java為例：

```
for (int i=0; i<100; i++) // Prints the numbers 0 to 99 (and not 100), each separated by a space.
{
 System.out.print(i);
 System.out.print(' ');
}
System.out.println();

```

### 使用指標的for迴圈

這種形式的for迴圈是大多數其他for迴圈的變革：他允許除了數字以外的計數方式。他通常用隱含或外顯指標的方式呈現，而在此迴圈變數會依序表示。以下是一個代表性的例子(語言：Python)：

```
for item in some\_iterable\_object:
    do Something
    do Something Else

```

### 矩陣化for迴圈

有一些語言支援比較特別的for迴圈，如同它可以同時處理所有的指標in parallel，像是在FORTRAN 95中的`for all`語法。
舉例來說，在以下的for迴圈虛擬碼片段，當計算`A(i)`的新的值，除了第一個(也就是 `i = 2`)，`A(i - 1)`的參照會得到新的值。
然而，在`for all` 版本，每個計算都會使用一開始的值，不會更改 `A`.

```
**for**     i := 2 : N - 1 **do** A(i) := [A(i - 1) + A(i) + A(i + 1)] / 3; **next** i;
**for all** i := 2 : N - 1 **do** A(i) := [A(i - 1) + A(i) + A(i + 1)] / 3;
```

和一般的for迴圈可能差距比較大。

應用範例
----

以c語言為例：

### 作為無窮迴圈

```
for (;;)
 printf("just keep going on!");

```

這個程式碼會不斷的印出"just keep going on!"。

### 配合矩陣

矩陣賦值：

```
for(int i=0;i<bound\_of\_matrix;i++)
 matrix[i] = i;

```

以上給予矩陣 matrix 依序從0到bound\_of\_matrix-1 的值。

### 巢狀迴圈

就像巢穴一樣，一層包覆一層，所以以下這個程式碼一共會執行(bound\_of\_x)乘上(bound\_of\_y)次。

```
for(int i=0;i<bound\_of\_x;i++)
 for(int j=0;j<bound\_of\_y;j++)
 matrix[i][j] = j;

```

常見的錯誤
-----

### 無窮迴圈

這裡指的是無意產生的無窮迴圈，容易導致當機。

以C語言為例：

```
for (int i=0;i<10;i--)
 printf("confused");

```

### 超出界限

編譯器會顯示out of bound，通常是指嘗試取矩陣界限外的值。

### 迴圈內的變數

迴圈內的變數在出迴圈之後，便無法使用。

發展概論
----

主要緣起為許多需要重複執行的程式碼，而不一樣的程式語言也會有不一樣的語法型式。

### 1957: FORTRAN

在Fortran 的`DO` 迴圈 同等於for迴圈。
Fortran的 `DO` 迴圈語法為：

```
 DO label counter = first, last, step
 statements
 label statement

```

接下來的兩個例子做出來的結果等同於其他語言的三個參數的for迴圈。其中變數COUNTER被初始化為1，以1遞增，並且到5的時候停下。

```
 DO 9, COUNTER = 1, 5, 1
 WRITE (6,8) COUNTER
8 FORMAT( I2 )
9 CONTINUE

```

Fortran 77 或之後的版本，也可能寫成： 

```
do counter = 1, 5
 write(\*, '(i2)') counter
end do

```

如果遞增為1，則遞增的部分可以省略。例如：

```
\* DO loop example.
   PROGRAM MAIN
   SUM SQ = 0
   DO 199 I = 1, 9999999
   IF (SUM SQ.GT.1000) GO TO 200
199   SUM SQ = SUM SQ + I\*\*2
200   PRINT 206, SUMSQ
206   FORMAT( I2 )
   END

```

### 1958: Algol

Algol 在Algo158首次正式格式化。

### 1960: COBOL

COBOL在許多努力之下，在1959年終正式格式化。他使用PERFORM 動詞，而PERFORM動詞有很多功能，像是後來加上的＂結構化＂的語法，像是 END-PERFORM。忽略宣告和初始化變數的必要，類似for迴圈的語法為：

```
 PERFORM VARYING I FROM 1 BY 1 UNTIL I > 1000
 ADD I\*\*2 TO SUM-SQ.
 END-PERFORM

```

如果PERFORM有TEST AFTER，這個迴圈的執行的結果會有點不同：迴圈內的程式會被執行至少一次。

### 1964: BASIC

BASIC 中的迴圈有時稱為 for-next迴圈。

```
For I = 1 to 5;
 Print I;
Next I
```

### 1964: PL/I

由IBM公司在1950年代發明的第三代高級程式語言， 有些類似PASCAL語言。 

以下為PLI使用例：

```
do counter = 1 to 5 by 1; /* "by 1" is the default if not specified */
  /*statements*/;
  end;
```

*LEAVE* 指令可以用來結束迴圈，像c語言的break，而*ITERATE*則像continue。

### 1968: Algol 68

Algol68 很類似現在的for語言了：

```
FOR i FROM 1 BY 2 TO 3 WHILE i≠4 DO ~ OD
```

  

### 1970: Pascal

```
for Counter := 1 to 5 do
 (\*statement\*);

```

### 1972: C/C++

更多：C syntax § Iteration statements

```
for (initialization; condition; increment/decrement)
 statement

```

### 1972: Smalltalk

### 1980: Ada

```
for Counter in 1 .. 5 loop
   -- statements
end loop;

```

### 1980: Maple

Maple有兩種型式的for迴圈，一個是指標一定範圍的值，另一個是指標一定大小的容器。
第一種：

  

```
**for** *i* **from** *f* **by** *b* **to** *t* **while** *w* **do**
    *# loop body*
**od**;
```

第二種：

```
**for** *e* **in** *c* **while** *w* **do**
    *# loop body*
**od**;
```

  

### 1982: PostScript

他的for迴圈 `[initial] [increment] [limit] { ... } for` 初始化一個內部的變數, 並且執行到他不大於限制的值(若遞增為負則以此類推)。

```
1 1 6 {STATEMENTS} for

```

### 1983: Ada 83 and above

```
procedure Main is
  Sum\_Sq : Integer := 0;
begin
  for I in 1 .. 9999999 loop 
    if Sum\_Sq <= 1000 then
      Sum\_Sq := Sum\_Sq + I\*\*2
    end if;
  end loop;
end;

```

### 1984: MATLAB

```
for i = 1:5 
 -- statements
end

```

### 1987: Perl

```
for ($counter = 1; $counter <= 5; $counter++) { # implictly or predefined variable
 # statements;
}
for (my $counter = 1; $counter <= 5; $counter++) { # variable private to the loop
 # statements;
}
for (1..5) { # variable impicitly called $\_; 1..5 creates a list of these 5 elements
 # statements;
}
statement for 1..5; # almost same (only 1 statement) with natural language order
for my $counter (1..5) { # variable private to the loop
 # statements;
}

```

  

### 1988: Mathematica

  

```
Do[f[x], {x, 0, 1, 0.1}]

```

  

```
For[x= 0 , x <= 1, x += 0.1,
 f[x]
]

```

### 1989: Bash

```
*第一種
for i in 1 2 3 4 5
do
 # must have at least one command in loop
 echo $i # just print value of i
done

```

```
*第二種
for (( i = 1; i <= 5; i++ ))
do
 # must have at least one command in loop
 echo $i # just print value of i
done

```

### 1990: Haskell

```
forM\_ [1..5] $ \indx -> do statements

```

  

如果你想要用更正式的方式存 [1..5]的內容，一個比較官方的方式為：

```
import Control.Monad as M

forLoopM\_ :: Monad m => a -> (a -> Bool) -> (a -> a) -> (a -> m ()) -> m ()
forLoopM\_ indx prop incr f = do
 f indx
 M.when (prop next) $ forLoopM\_ next prop incr f
 where 
 next = incr indx

```

並且可以這樣使用：

```
 forLoopM\_ (0::Int) (< len) (+1) $ \indx -> do -- whatever with the index

```

### 1991: Oberon-2, Oberon-07, or Component Pascal

```
FOR Counter := 1 TO 5 DO
  (* statement sequence *)
END
```

### 1991: Python

```
for counter in range(1, 6):  # range(1, 6) gives values from 1 to 5 inclusive (but not 6)
  # statements

```

### 1993: AppleScript

```
repeat with i from 1 to 5
	-- statements
	log i
end repeat

```

### 1993: Lua

```
for i = start, stop, interval do
     -- statements
end

```

這個程式碼 

```
for i = 1, 5, 2 do
     print(i)
end

```
即會印出：

```
1 3 5

```

  

### 1995: Java

```
for (int i = 0; i < 5; i++) {
 //perform functions within the loop;
 //can use the statement 'break;' to exit early;
 //can use the statement 'continue;' to skip the current iteration
}

```

### 1995: JavaScript

JavaScript 支援像是C語言的三個參數的迴圈，並且支援break和continue。

```
for (let i = 0; i < 5; i++) {
 // ...
}

```

### 1995: PHP

```
for ($i = 0; $i <= 5; $i++)
{
  for ($j = 0; $j <= $i; $j++)
  {
    echo "\*";
  }
  echo "<br>";
}

```

### 1995: Ruby

```
for counter in 1..5
 # statements
end

5.times do |counter| # counter iterates from 0 to 4
 # statements
end

1.upto(5) do |counter|
 # statements
end

```

### 1996: OCaml

請參考

```
 (\* for\_statement := "for" ident '=' expr ( "to" ∣ "downto" ) expr "do" expr "done" \*)

for i = 1 to 5 do
    (\* statements \*)
  done ;;

for j = 5 downto 0 do
    (\* statements \*)
  done ;;

```

### 1998: ActionScript 3

```
for (var counter:uint = 1; counter <= 5; counter++){
 //statement;
}

```

參考文獻
----

1. ↑ .  [2016-03-06]. （原始内容存档于2016-03-05）.
2. ↑ . Addison-Wesley Publishing Company. : 596. ISBN 0-201-37922-8.
3. ↑ .  [2016-03-06]. （原始内容存档于2013-04-12）.

參見
--

* Foreach循环