控制流程

title: 基本概念.
title: 标记.
content: 标记是一个标示在源代码固定位置中的名称或数字,其他位置的流程控制指令可以参考标记的位置,执行标记位置所对应的程序。标记本身不影响程序的进行,除了标示位置外,对程序执行没有其他的作用。  有一些程序语言(像Fortran及BASIC等)利用行号作为标记。行号是标示在每一行程序最前面的自然数,不一定要是连续的数字,在不受流程控制指令影响的情形下,程序会从最小的行号依序执行,而流程控制指令需指定对应的行号。以下是一个BASIC的例子:  在像是C及Ada等程序语言中,标记是一个标识符,一般出现在一行的最前面,后面会加一个冒号作为识别,以下是C语言的例子:  Algol 60语言同时支持整数(类似行号)及标识符的标记(二者后面都要加上冒号),不过其他Algol语言几乎都不支援整数的标记。
title: Goto.
content: goto 指令(来自英文go和to的组合)是无条件流程控制指令中最基本的型式。一般在程序中会用以下的方式出现(指令大小写可能会依程序语言而不同)  goto 指令的效果是调整程序的控制流程,后续就执行标记位置的程序。  goto 指令是许多的计算机科学家视为有害的指令,像荷兰计算机科学家艾兹格·迪科斯彻(Edsger Wybe Dijkstra)就提出了goto有害论。
title: 子程序.
content: 子程序(subroutine)可以用许多不同的术语来表示,例如程序、函数(尤其是有传回值时)或是方法(特别是子程序属于一个类的一部分)等。  子程序是是完成一项特定工作的代码序列,其他程序可以将流程移转到子程序中,执行特定工作后再回到原来的程序,若程序中有许多部分都需要执行一特定工作,利用子程序的方式可以利用一段程序达到上述的功能,可以减少程序码的长度。  如今子程序也常用来使得程序更加的结构化,例如可以将一些特殊的算法或特殊的资料存取方式放在子程序中,和其他代码隔离。子程序也是程序模组的一种,若许多程序员共同开发一个程序,子程序也有助于其工作的分割及分工。
title: 最简结构化控制流程.
content: 1966年5月Corrado Böhm及Giuseppe Jacopini在《Communications of the ACM》期刊发表论文,说明任何一个有goto指令的程序,可以改为完全不使用goto指令的程序,goto指令可以用选择指令(IF THEN ELSE)及循环(WHILE 特定条件 DO 特定程序)取代,可能会再多一些重复的程序码及额外的布林变量。后来的研究者已证明选择指令也可以用循环取代,不过需要更多的布林变量。Böhm及Jacopini的论文说明程序可以完全不使用goto,但是在实务上大家不一定会想要这么进行。  其他的研究说明若控制结构只有一个进入点(entry)及一个结束点(exit),这样的程序会比其他型式的程序容易理解。因此这样的程序可以像一个指令一样放在程序的任何部分,不必担心会破坏其结构,换句话说,这种程序是「可组成的」(composable)。
title: 常用的控制结构.
content: 若一程序语言支援控制结构,控制结构开始时多半都会有特定的关键字,以标明是使用哪一种控制结构。但只有部分程序语言在控制结构结束时会有特定的关键字表示结束,因此可以依控制结构结束时是否有特定关键字来将程序语言分为二类。
title: 条件判断.
content: 条件判断是依指定变量或运算式的结果,决定后续执行的程序,最常用的是if-else指令,可以根据指定条件是否成立,决定后续的程序。也可以组合多个if-else指令,进行较复杂的条件判断。 许多程序语言也提供多选一的条件判断,例如C语言的switch-case指令。
title: 循环.
content: 循环是指一段在程序中只出现一次,但可能会连续执行多次的程序码。常见的循环可以分为二种,指定执行次数的循环(如C语言的for循环)以及指定继续执行条件(或停止条件)的循环(如C语言的while循环)。  在一些函数程序语言(例如Haskell和Scheme)中会使用递归或不动点组合子来达到循环的效果,其中尾部递归是一种特别的递归,很容易转换为迭代。
title: 结构化的非区部控制流程.
content: 有些程序语言会提供非区部的控制流程(non-local control flow),会允许流程跳出目前的程序码,进入一段事先指定的程序码。常用的结构化非区部控制流程可分为条件处理、异常处理及延续性(Continuation)三种。
title: 条件处理.
content: PL/I程序语言中有22种标准的条件(如 ZERODIVIDE SUBSCRIPTRANGE ENDFILE),可以在程序中设定,当特定条件成立时需进行的指令,程序设计者也可以定义自己的条件,并在程序中使用。  条件成立时,只能设定一个需进行的指令(类似未结构化的if指令),大部分的应用中,都会指定执行goto指令,跳到其他程序码执行对应的流程。  不过因为有些条件处理的实现会增加许多程序码及执行时间(特别SUBSCRIPTRANGE),所以许多程序设计者会尽量不使用条件处理。  条件处理的语法如下:
title: 异常处理.
content: 有些程序语言可提供不需要使用codice_28的结构化异常处理程序:  在codice_29的区块中,若有异常情形时,程序就会离开try的区块,由后续的一个或多个codice_30子句判断需执行何种异常处理。在D、Java、C#及Python程序语言中,codice_29区块中还可以加入一个codice_32子句,不管程序流程是否离开codice_29区块,codice_32子句中的程序都一定会执行,常用在当程序结束处理时,需要放弃一些外部资源(档案或数据库连结)的情形下:  由于上述情形相当普遍,C#提供一种特殊的语法进行相同的处理:  只要离开 codice_35区块,编译器会自动释放codice_36物件,Python的 codice_37指令及也有类似的功能。  这些语言都有定义标准的异常情形及其出现的条件,程序设计者也可以丢出自己产生的异常(其实C++及Python的throw和catch支援绝大多数形态的物件)。  若某一个codice_38指令找不到对应的codice_30,控制流程会离开目前的副程序或控制结构,设法找到对应的codice_30,若到主程序的结尾还是找不到对应的codice_30,程序会强制结束,并显示适当的错误讯息。  AppleScript脚本语言可以将"codice_42"区块分为几个部分,提供不同的讯息及异常:
title: 延续性.
content: 延续性(Continuation)可以将目前子程序的执行状态(包括目前的堆叠,区部变量及执行到的位置)储存成一个物件,后续在其他子程序中可以利用此物件回到此子程序现在的执行状态。  延续性一词也可以指第一类延续性(first-class continuation),是指程序语言可以在任意时间点储存目前的执行状态,并在之后回到之前储存的执行状态。  程序需要分配空间给子程序用到的区域变量,而且在子程序结束时需释出这些变量用到的空间。许多程序语言利用调用堆叠来存放这些变量,可以简单快速的分配及释出空间。也有一些程序语言使用动态内存分配来储存变量,可以较灵活的分配变量,但分配及释出空间较不方便。这二个架构下延续性的处理方式也会不同,各有其优点及缺点。  Scheme语言利用codice_43函数(缩写为call/cc) 可提供延续性功能。

Summary: 控制流程(也称为流程控制)是电脑运算领域的用语,意指在程序执行时,个别的指令(或是陈述、子程序)执行或求值的顺序。不论是在宣告式程序语言或是函数程序语言中,都有类似的概念。