fbpx
维基百科

迴圈

迴圈计算机科学運算領域的用語,也是一種常見的控制流程。迴圈是一段在程式中只出現一次,但可能會連續執行多次的程式碼。迴圈中的程式碼會執行特定的次數,或者是執行到特定條件成立時結束迴圈,或者是針對某一集合中的所有項目都執行一次。

在一些函數程式語言(例如HaskellScheme)中會使用递归不动点组合子來達到迴圈的效果,其中尾部递归是一種特別的递归,很容易轉換為迭代[1]

指定執行次數的迴圈(for loop) 编辑

大部份程式語言都提供迴圈的指令,可以依指定的次數重覆執行一段程式。

若指定的次數N小於1,程式語言會忽略整個迴圈不去執行,若指定的次數N為1,則迴圈只會執行一次。

在迴圈進行時,迴圈计数器也會隨著變化,大部份的程式語言可以允許迴圈计数器上數或是下數,每次的變化量可以是1或是其他不為0的數值。

 FOR I = 1 TO N for I := 1 to N do begin xxx xxx NEXT I end; DO I = 1,N for ( I=1; I<=N; ++I ) { xxx xxx END DO } 

在許多程式語言中,迴圈计数器要使用整數才能得到準確的結果。由於硬體的限制,在迴圈计数器使用浮點數時,結果可能會不符預期,如以下的迴圈

 for X := 0.1 step 0.1 to 1.0 do

依其四捨五入的誤差、硬體及編譯器的差異,不一定會執行10次,可能只會執行9次。而且X的數值可能會有些誤差,不是預期的0.1, 0.2, 0.3, ..., 1.0。

指定條件的迴圈(while loop/doWhile loop) 编辑

大多數的程式語言都有指令,可以在特定條件成立時繼續迴圈的進行,或是特定條件不成立時繼續迴圈的進行,進行到特定條件成立為止。前者一般會標示while,後者一般會標示until。

其判斷條件可能在迴圈一開始就進行,或是在迴圈最後才進行。前者的迴圈不一定會執行,而後者1的迴圈至少會執行一次。

 DO WHILE (test) repeat xxx xxx LOOP until test; while (test) { do xxx xxx } while (test); 

指定集合的迴圈 编辑

許多程式語言支援一種特別的迴圈,可以針對一個陣列中的元素或是一個集合中的所有成員進行迴圈中的指令,包括AdaD語言SmalltalkPerlC#Visual BasicRubyPythonJavaJavaScriptFortran 95等程式語言都有這類的迴圈結構:

 someCollection do: [:eachElement |xxx]. foreach (item; myCollection) { xxx } foreach someArray { xxx } Collection<String> coll; for (String s : coll) {} foreach (string s in myStringCollection) { xxx } $someCollection | ForEach-Object { $_ } forall ( index = first:last:step... ) 

泛用迴圈結構 编辑

有些程式語言有泛用迴圈結構,可以用來表示指定次數或指定條件的迴圈,像C語言的for指令或是Common Lisp語言中的do指令都是這類的例子,不過為了程式的可讀性考量,在這些程式語言中還是儘量使用一些含義較明確的指令(如while指令)。

無窮迴圈 编辑

無窮迴圈一般會用在有一段程式需要永遠執行,或是該程式在沒有發生特殊事件(如故障)時需要永遠執行的場合,例如一個事件驅動的程式需要持續執行迴圈,處理發生的事件,直到使用者結束或中斷程式為止。

若在指定條件的迴圈中,其判斷條件用到的變數數值永遠不會改變,這種程式錯誤也會使得此迴圈變成無窮迴圈。

提早結束整個迴圈 编辑

當使用指定次數的迴圈查表時,會希望在查到需要的資料時就可以直接結束迴圈的進行,有些程式語言可以用breakexit的指令達到這様的功能,這些指令會結束這個迴圈,接著會執行迴圈後面的指令。若此迴圈在副程式中,也可以用return中斷迴圈的進行, 同時離開副程式。

以下是Ada程式語言的一個範例,利用exit ... when...的方式中提早結束迴圈。

with Ada.Text IO; with Ada.Integer Text IO; procedure Print_Squares is X : Integer; begin Read_Data : loop Ada.Integer Text IO.Get(X); exit Read_Data when X = 0; Ada.Text IO.Put (X * X); Ada.Text IO.New_Line; end loop Read_Data; end Print_Squares; 

Python支援一個特別的條件判斷式,可以根據最近使用迴圈是否曾用break提早結束而做不同的處理,舉例如下:

for n in set_of_numbers: if isprime(n): print "Set contains a prime number" break else: print "Set did not contain any prime numbers" 

上例中的else子句是for迴圈的一部份,不是內層if區塊的一部份。Python語言的for迴圈及while 迴圈都支援else子句,當迴圈沒有用break提早結束時就會執行。

迴圈的特殊指令 编辑

有時在使用迴圈的程式中會希望在特定情形下跳過目前迴圈區塊的指令,回到迴圈開始執行下一個迴圈,一般這類的指令會命名為continueskipnext,其效果是提早結束這次迴圈的進行,繼續進行下一個迴圈,若此迴圈已經是最後一次執行,這類指令會結束迴圈的進行,繼續進行後續的指令。

像Perl及Ruby等程式語言有redo指令,可以重新執行目前的迴圈,若在指定次數的迴圈中,其迴圈計數器的數值不會變化。Ruby程式語言有retry指令,可以讓迴圈計數器回到初值,重新執行整個迴圈。

迴圈變式及迴圈不變式 编辑

迴圈變式英语Loop variant迴圈不變式是判斷迴圈正確性的工具[2]

迴圈變式是一個初值不為負的整數表示式,在每次執行迴圈時迴圈變式的數值需減少,但在正常的迴圈執行過程中迴圈變式的數值不會變成負值。迴圈變式用來確保迴圈會結束。

迴圈不變式是一個和迴圈有關的判斷式,在第一次進入迴圈之前,迴圈不變式的值需為真,在後續每一次執行迴圈時,其值也要為真。當迴圈正確的結束時,其終止條件和迴圈不變式都會成立。迴圈不變式可用來監控在迴圈進行時,某一指定性質的狀態。

像是Eiffel之類的程式語言本身就有支援迴圈變式及迴圈不變式,其他語言可能需要有附加元件才能支持此功能,例如Java就需要配合Java建模語言英语Java Modeling Language規範的loop statements (页面存档备份,存于互联网档案馆)才能支持此機能。

不同語言的迴圈比較表 编辑

程式語言 條件判斷式 迴圈 early exit continuation redo retry 正確性判斷機制
迴圈啟始 迴圈中間 迴圈結尾 指定次數 指定集合 泛用 無窮[1] 迴圈變式 迴圈不變式
Ada 只針對陣列 多層迴圈
C [2] 多層迴圈 [3] 多層迴圈 [3]
C++ [2] 多層迴圈 [3] 多層迴圈 [3]
C# [2] 多層迴圈 [3] 多層迴圈 [3]
Common Lisp 多層迴圈
Eiffel [10] 一層迴圈 [10] [11]
F# [6]
FORTRAN 77 一層迴圈
FORTRAN 90 多層迴圈
FORTRAN 95及後續版本 陣列 多層迴圈
Haskell [6]
Java [2] 多層迴圈 多層迴圈 非原生(non-native) [12] 非原生(non-native) [12]
JavaScript [2] 多層迴圈 多層迴圈
OCaml 陣列及列表(list) [6]
PHP [2] [5] [4] 多層迴圈 多層迴圈
Perl [2] [5] 多層迴圈 多層迴圈
Python [5] 多層迴圈 [6] 多層迴圈 [6]
REBOL [7] [8] 一層迴圈 [6]
Ruby 多層迴圈 [6] 多層迴圈 [6]
Standard ML 陣列,列表(list) [6]
Visual Basic .NET 每種迴圈一層 每種迴圈一層
Windows PowerShell [2] ?
  1. a 此項只考慮專用的無窮迴圈程式結構,因此while (true)for ( ; ; )都不算在內。
  2. a b c d e f g h C語言的for (init; test; increment)迴圈是一個通用的迴圈指令,累加量也不一定要為1。
  3. a b c 在C、C++及C#中,跳出多層迴圈可以用label和goto指令達到。
  4. a 在PHP 5中已支援 (页面存档备份,存于互联网档案馆)配合物件的迴圈。
  5. a b c 指定次數的迴圈可以用重覆incrementing list或generator的方式來達到其效果,例如Python中的range()
  6. a b c d e 可以用异常处理來跳出多層迴圈。
  7. a 沒有專門指令,但while指令可以用作此用途。
  8. a 沒有專門指令,但使用者可以定義通用迴圈指令。
  9. a 正在計劃的C++0x標準中已加入以範圍為基礎的 for 迴圈标准模板库(STL)中有std::for_each模板函數,可以對STL容器(container)的每個元素重複呼叫一個一元函數[3]。製作STL容器的巨集也可以達到類似的效果[4]
  10. a 利用整數區間的迭代可以達到指定次數迴圈的效果, early exit可以用多增加一個exit的條件來達成。
  11. a Eiffel支援保留字retry,不過是用在契约式设计異常處理,不是迴圈的流程控制指令。
  12. a 需要配合Java建模语言英语Java Modeling Language(JML)。

參考資料 编辑

  1. ^ arun_yh. . www.cnblogs.com. 博客园. [2017-03-09]. (原始内容存档于2017-03-12) (中文(中国大陆)). 
  2. ^ Meyer, Bertrand. Eiffel: The Language. Prentice Hall. 1991: 129~131. 
  3. ^ for_each (页面存档备份,存于互联网档案馆). Sgi.com. Retrieved on 2010-11-09.
  4. ^ Chapter 1. Boost.Foreach (页面存档备份,存于互联网档案馆). Boost-sandbox.sourceforge.net (2009-12-19). Retrieved on 2010-11-09.

迴圈, 是计算机科学運算領域的用語, 也是一種常見的控制流程, 是一段在程式中只出現一次, 但可能會連續執行多次的程式碼, 中的程式碼會執行特定的次數, 或者是執行到特定條件成立時結束, 或者是針對某一集合中的所有項目都執行一次, 在一些函數程式語言, 例如haskell和scheme, 中會使用递归或不动点组合子來達到的效果, 其中尾部递归是一種特別的递归, 很容易轉換為迭代, 目录, 指定執行次數的, loop, 指定條件的, while, loop, dowhile, loop, 指定集合的, 泛用結構, 無. 迴圈是计算机科学運算領域的用語 也是一種常見的控制流程 迴圈是一段在程式中只出現一次 但可能會連續執行多次的程式碼 迴圈中的程式碼會執行特定的次數 或者是執行到特定條件成立時結束迴圈 或者是針對某一集合中的所有項目都執行一次 在一些函數程式語言 例如Haskell和Scheme 中會使用递归或不动点组合子來達到迴圈的效果 其中尾部递归是一種特別的递归 很容易轉換為迭代 1 目录 1 指定執行次數的迴圈 for loop 2 指定條件的迴圈 while loop doWhile loop 3 指定集合的迴圈 4 泛用迴圈結構 5 無窮迴圈 6 提早結束整個迴圈 7 迴圈的特殊指令 8 迴圈變式及迴圈不變式 9 不同語言的迴圈比較表 10 參考資料指定執行次數的迴圈 for loop 编辑主条目 For迴圈 参见 迴圈计数器 大部份程式語言都提供迴圈的指令 可以依指定的次數重覆執行一段程式 若指定的次數N小於1 程式語言會忽略整個迴圈不去執行 若指定的次數N為1 則迴圈只會執行一次 在迴圈進行時 迴圈计数器也會隨著變化 大部份的程式語言可以允許迴圈计数器上數或是下數 每次的變化量可以是1或是其他不為0的數值 FOR I 1 TO N for I 1 to N do begin xxx xxx NEXT I end DO I 1 N for I 1 I lt N I xxx xxx END DO 在許多程式語言中 迴圈计数器要使用整數才能得到準確的結果 由於硬體的限制 在迴圈计数器使用浮點數時 結果可能會不符預期 如以下的迴圈 for X 0 1 step 0 1 to 1 0 do 依其四捨五入的誤差 硬體及編譯器的差異 不一定會執行10次 可能只會執行9次 而且X的數值可能會有些誤差 不是預期的0 1 0 2 0 3 1 0 指定條件的迴圈 while loop doWhile loop 编辑主条目 While迴圈 参见 Do while迴圈 大多數的程式語言都有指令 可以在特定條件成立時繼續迴圈的進行 或是特定條件不成立時繼續迴圈的進行 進行到特定條件成立為止 前者一般會標示while 後者一般會標示until 其判斷條件可能在迴圈一開始就進行 或是在迴圈最後才進行 前者的迴圈不一定會執行 而後者1的迴圈至少會執行一次 DO WHILE test repeat xxx xxx LOOP until test while test do xxx xxx while test 指定集合的迴圈 编辑主条目 Foreach迴圈 許多程式語言支援一種特別的迴圈 可以針對一個陣列中的元素或是一個集合中的所有成員進行迴圈中的指令 包括Ada D語言 Smalltalk Perl C Visual Basic Ruby Python Java JavaScript Fortran 95等程式語言都有這類的迴圈結構 someCollection do eachElement xxx foreach item myCollection xxx foreach someArray xxx Collection lt String gt coll for String s coll foreach string s in myStringCollection xxx someCollection ForEach Object forall index first last step 泛用迴圈結構 编辑有些程式語言有泛用迴圈結構 可以用來表示指定次數或指定條件的迴圈 像C語言的for指令或是Common Lisp語言中的do指令都是這類的例子 不過為了程式的可讀性考量 在這些程式語言中還是儘量使用一些含義較明確的指令 如while指令 無窮迴圈 编辑無窮迴圈一般會用在有一段程式需要永遠執行 或是該程式在沒有發生特殊事件 如故障 時需要永遠執行的場合 例如一個事件驅動的程式需要持續執行迴圈 處理發生的事件 直到使用者結束或中斷程式為止 若在指定條件的迴圈中 其判斷條件用到的變數數值永遠不會改變 這種程式錯誤也會使得此迴圈變成無窮迴圈 提早結束整個迴圈 编辑當使用指定次數的迴圈查表時 會希望在查到需要的資料時就可以直接結束迴圈的進行 有些程式語言可以用break或exit的指令達到這様的功能 這些指令會結束這個迴圈 接著會執行迴圈後面的指令 若此迴圈在副程式中 也可以用return中斷迴圈的進行 同時離開副程式 以下是Ada程式語言的一個範例 利用exit when 的方式中提早結束迴圈 with Ada Text IO with Ada Integer Text IO procedure Print Squares is X Integer begin Read Data loop Ada Integer Text IO Get X exit Read Data when X 0 Ada Text IO Put X X Ada Text IO New Line end loop Read Data end Print Squares Python支援一個特別的條件判斷式 可以根據最近使用迴圈是否曾用break提早結束而做不同的處理 舉例如下 for n in set of numbers if isprime n print Set contains a prime number break else print Set did not contain any prime numbers 上例中的else子句是for迴圈的一部份 不是內層if區塊的一部份 Python語言的for迴圈及while 迴圈都支援else子句 當迴圈沒有用break提早結束時就會執行 迴圈的特殊指令 编辑有時在使用迴圈的程式中會希望在特定情形下跳過目前迴圈區塊的指令 回到迴圈開始執行下一個迴圈 一般這類的指令會命名為continue skip或next 其效果是提早結束這次迴圈的進行 繼續進行下一個迴圈 若此迴圈已經是最後一次執行 這類指令會結束迴圈的進行 繼續進行後續的指令 像Perl及Ruby等程式語言有redo指令 可以重新執行目前的迴圈 若在指定次數的迴圈中 其迴圈計數器的數值不會變化 Ruby程式語言有retry指令 可以讓迴圈計數器回到初值 重新執行整個迴圈 迴圈變式及迴圈不變式 编辑迴圈變式 英语 Loop variant 及迴圈不變式是判斷迴圈正確性的工具 2 迴圈變式是一個初值不為負的整數表示式 在每次執行迴圈時迴圈變式的數值需減少 但在正常的迴圈執行過程中迴圈變式的數值不會變成負值 迴圈變式用來確保迴圈會結束 迴圈不變式是一個和迴圈有關的判斷式 在第一次進入迴圈之前 迴圈不變式的值需為真 在後續每一次執行迴圈時 其值也要為真 當迴圈正確的結束時 其終止條件和迴圈不變式都會成立 迴圈不變式可用來監控在迴圈進行時 某一指定性質的狀態 像是Eiffel之類的程式語言本身就有支援迴圈變式及迴圈不變式 其他語言可能需要有附加元件才能支持此功能 例如Java就需要配合Java建模語言 英语 Java Modeling Language 規範的loop statements 页面存档备份 存于互联网档案馆 才能支持此機能 不同語言的迴圈比較表 编辑程式語言 條件判斷式 迴圈 early exit continuation redo retry 正確性判斷機制迴圈啟始 迴圈中間 迴圈結尾 指定次數 指定集合 泛用 無窮 1 迴圈變式 迴圈不變式Ada 是 是 是 是 只針對陣列 否 是 多層迴圈 否C 是 否 是 否 2 否 是 否 多層迴圈 3 多層迴圈 3 否C 是 否 是 否 2 是 是 否 多層迴圈 3 多層迴圈 3 否C 是 否 是 否 2 是 是 否 多層迴圈 3 多層迴圈 3 Common Lisp 是 是 是 是 是 是 是 多層迴圈 否Eiffel 是 否 否 是 10 是 是 否 一層迴圈 10 否 否 否 11 是 是F 是 否 否 是 是 否 否 否 6 否 否FORTRAN 77 是 否 否 是 否 否 否 一層迴圈 是FORTRAN 90 是 否 否 是 否 否 是 多層迴圈 是FORTRAN 95及後續版本 是 否 否 是 陣列 否 是 多層迴圈 是Haskell 否 否 否 否 是 否 是 否 6 否 否Java 是 否 是 否 2 是 是 否 多層迴圈 多層迴圈 否 非原生 non native 12 非原生 non native 12 JavaScript 是 否 是 否 2 是 是 否 多層迴圈 多層迴圈 否OCaml 是 否 否 是 陣列及列表 list 否 否 否 6 否 否PHP 是 否 是 否 2 5 是 4 是 否 多層迴圈 多層迴圈 否Perl 是 否 是 否 2 5 是 是 否 多層迴圈 多層迴圈 是Python 是 否 否 否 5 是 否 否 多層迴圈 6 多層迴圈 6 否REBOL 否 7 是 是 是 是 否 8 是 一層迴圈 6 否 否Ruby 是 否 是 是 是 否 是 多層迴圈 6 多層迴圈 6 是 是Standard ML 是 否 否 否 陣列 列表 list 否 否 否 6 否 否Visual Basic NET 是 否 是 是 是 否 是 每種迴圈一層 每種迴圈一層Windows PowerShell 是 否 是 否 2 是 是 否 是a 此項只考慮專用的無窮迴圈程式結構 因此while true 和for 都不算在內 a b c d e f g h C語言的for i init i i test i i increment i 迴圈是一個通用的迴圈指令 累加量也不一定要為1 a b c 在C C 及C 中 跳出多層迴圈可以用label和goto指令達到 a 在PHP 5中已支援 页面存档备份 存于互联网档案馆 配合物件的迴圈 a b c 指定次數的迴圈可以用重覆incrementing list或generator的方式來達到其效果 例如Python中的range a b c d e 可以用异常处理來跳出多層迴圈 a 沒有專門指令 但while指令可以用作此用途 a 沒有專門指令 但使用者可以定義通用迴圈指令 a 正在計劃的C 0x標準中已加入以範圍為基礎的 for 迴圈 标准模板库 STL 中有std for each模板函數 可以對STL容器 container 的每個元素重複呼叫一個一元函數 3 製作STL容器的巨集也可以達到類似的效果 4 a 利用整數區間的迭代可以達到指定次數迴圈的效果 early exit可以用多增加一個exit的條件來達成 a Eiffel支援保留字retry 不過是用在契约式设计的異常處理 不是迴圈的流程控制指令 a 需要配合Java建模语言 英语 Java Modeling Language JML 參考資料 编辑 arun yh 循环 loop 递归 recursion 遍历 traversal 迭代 iterate 的区别 arun yh 博客园 www cnblogs com 博客园 2017 03 09 原始内容存档于2017 03 12 中文 中国大陆 Meyer Bertrand Eiffel The Language Prentice Hall 1991 129 131 for each 页面存档备份 存于互联网档案馆 Sgi com Retrieved on 2010 11 09 Chapter 1 Boost Foreach 页面存档备份 存于互联网档案馆 Boost sandbox sourceforge net 2009 12 19 Retrieved on 2010 11 09 取自 https zh wikipedia org w index php title 迴圈 amp oldid 75763089, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。