結(jié)構(gòu)化編程
底層的結(jié)構(gòu)化程序設(shè)計(jì)
結(jié)構(gòu)化的程序是以一些簡(jiǎn)單、有層次的程序流程架構(gòu)所組成,可分為循序(sequence)、選擇(selection)及重復(fù)(repetition)。
循序是指程序正常的運(yùn)行方式,運(yùn)行完一個(gè)指令后,運(yùn)行后面的指令。
選擇是依程序的狀態(tài),選擇數(shù)段程序中的一個(gè)來(lái)運(yùn)行,一般會(huì)使用if..then..else..endif或switch、case等關(guān)系字來(lái)識(shí)別。
重復(fù)是指一直運(yùn)行某一段程序,直到滿足特定條件,或是一集合體中的所有元素均已處理過(guò),一般會(huì)使用while、repeat、for或do..until等關(guān)鍵字識(shí)別。一般會(huì)建議每個(gè)循環(huán)只能有一個(gè)進(jìn)入點(diǎn)(戴克斯特拉的結(jié)構(gòu)化程序設(shè)計(jì)要求每個(gè)循環(huán)只能有一個(gè)進(jìn)入點(diǎn)及一個(gè)結(jié)束點(diǎn),有些編程語(yǔ)言仍有此規(guī)定)。
若一個(gè)編程語(yǔ)言的語(yǔ)法允許用成對(duì)的關(guān)鍵字包圍一段程序,形成一個(gè)結(jié)構(gòu),這種編程語(yǔ)言稱為有“區(qū)塊結(jié)構(gòu)”(block-structured),這類的結(jié)構(gòu)包括用ALGOL 68的if..fi包圍的程序,或是在PL/I中用BEGIN..END包圍的一段程序,或是在C語(yǔ)言中用大括號(hào){...}包圍的一段程序。
結(jié)構(gòu)化編程語(yǔ)言
用任何語(yǔ)言都可以進(jìn)行結(jié)構(gòu)化程序設(shè)計(jì),不過(guò)一般較常使用過(guò)程式的編程語(yǔ)言。早期的結(jié)構(gòu)化編程語(yǔ)言包括ALGOL、Pascal、PL/I及Ada,不過(guò)后來(lái)大部分的過(guò)程式編程語(yǔ)言都鼓勵(lì)使用結(jié)構(gòu)化程序設(shè)計(jì),有時(shí)也會(huì)特意的省去一些特性(例如不支持goto指令)使得非結(jié)構(gòu)化的程序設(shè)計(jì)更加困難。
歷史
理論基礎(chǔ)
結(jié)構(gòu)化程序理論可做為結(jié)構(gòu)化編程的理論基礎(chǔ),結(jié)構(gòu)化程序理論中提到利用循序、選擇及重復(fù)這三種組合程序的方式,可以表示所有可計(jì)算函數(shù)。上述的三種結(jié)構(gòu)已足以表示CPU中的指令周期,也可以表示圖靈機(jī)的運(yùn)作,以此觀點(diǎn)來(lái)看,處理器所運(yùn)行的指令可視為是某種“結(jié)構(gòu)化程序”,雖然整個(gè)程序可能不是一個(gè)結(jié)構(gòu)化程序。一般都認(rèn)為結(jié)構(gòu)化程序理論是歸功于伯姆和賈可皮尼于1966年發(fā)表的論文,其中一個(gè)原因可能是戴克斯特拉引用過(guò)此論文。結(jié)構(gòu)化程序理論未提及如何撰寫(xiě)結(jié)構(gòu)化程序,也沒(méi)有提到結(jié)構(gòu)化程序的分析,后來(lái)1960至1970年代時(shí),戴克斯特拉、羅伯特·弗洛伊德、東尼·霍爾等計(jì)算機(jī)科學(xué)家在此領(lǐng)域有許多的貢獻(xiàn)。
爭(zhēng)議
結(jié)構(gòu)化編程中一項(xiàng)重要的原則是減少甚至禁止goto指令的使用,不過(guò)不是所有計(jì)算機(jī)科學(xué)家都贊成禁止使用goto指令。高德納贊成程序設(shè)計(jì)時(shí)需考慮可讀性,但他不贊成禁用goto指令。在其1974年發(fā)表的論文《使用goto指令的結(jié)構(gòu)化編程》(Structured Programming with Goto Statements)中,他提出了一些程序,使用goto指令可以使得程序更清楚而有效率,也不會(huì)犧牲程序的可讀性。高德納提出了一個(gè)較松的結(jié)構(gòu)限制要求:將程序以流程圖表示,前進(jìn)的分支在流程圖的左側(cè),倒退的分支在流程圖的右側(cè),所有分支均不得交叉。
結(jié)構(gòu)化編程在1970年有很大的進(jìn)展,IBM的研究員哈倫·米爾斯(英語(yǔ):Harlan Mills)將結(jié)構(gòu)化編程應(yīng)用在研究文件索引系統(tǒng)的開(kāi)發(fā),此計(jì)劃相當(dāng)成功,因此許多公司開(kāi)始使用結(jié)構(gòu)化編程,不過(guò)戴克斯特拉評(píng)論米爾斯使用的方式和一些已發(fā)表論文中的方式不同。
到1987年時(shí)在計(jì)算機(jī)科學(xué)領(lǐng)域仍有針對(duì)結(jié)構(gòu)化編程的爭(zhēng)論,弗蘭克·魯賓發(fā)表了一篇論文《“goto有害論”是有害的》(GOTO considered harmful" considered harmful),引發(fā)許多的反對(duì),戴克斯特拉本人也批評(píng)魯賓及其追隨者的論點(diǎn)。
影響
在二十世紀(jì)末時(shí)絕大多數(shù)的計(jì)算機(jī)科學(xué)學(xué)者均已同意使用結(jié)構(gòu)化程序設(shè)計(jì)的好處,原來(lái)缺乏程序結(jié)構(gòu)的高級(jí)編程語(yǔ)言(如FORTRAN、COBOL及BASIC)也都已加入此特性。
例外情形
異常處理
子程序很少會(huì)有一個(gè)以上的進(jìn)入點(diǎn),相對(duì)的,有時(shí)子程序會(huì)有一個(gè)以上的結(jié)束點(diǎn),表示剩下的程序不需運(yùn)行,或因?yàn)橐恍┰颍斐蔁o(wú)法運(yùn)行后續(xù)的程序。
以下是是一個(gè)由文件中讀取數(shù)據(jù)并處理的程序示例:
open file; while (reading not finished) { read some data; if (error) { stop the subprogram and inform rest of the program about the error; } } process read data; finish the subprogram;
其中“stop and inform”的步驟可以利用多種方式達(dá)成,包括產(chǎn)生一個(gè)異常(exception)、利用return指令回到上一層的程序、使用配合標(biāo)記的break指令,或是使用goto。當(dāng)子程序有二個(gè)結(jié)束點(diǎn)時(shí),就違背了戴克斯特拉的結(jié)構(gòu)化編程原則。但此情形下若強(qiáng)制要撰寫(xiě)只有一個(gè)結(jié)束點(diǎn)的子程序又相當(dāng)麻煩,而且若有幾個(gè)不同的錯(cuò)誤處理,錯(cuò)誤產(chǎn)生后有不同的清除方式,單一結(jié)束點(diǎn)的程序會(huì)相當(dāng)難以閱讀及理解,甚至比未結(jié)構(gòu)化使用goto的程序相當(dāng)。
許多編程語(yǔ)言就提供了在結(jié)構(gòu)化編程中產(chǎn)生多個(gè)結(jié)束點(diǎn)的方式。C語(yǔ)言允許使用continue、break及return指令來(lái)產(chǎn)生結(jié)構(gòu)的多個(gè)結(jié)束點(diǎn),C++還可以用throw產(chǎn)生異常,在結(jié)構(gòu)外再用catch進(jìn)行異常的處理,有些語(yǔ)言則有配合標(biāo)記的break指令(類似一般的break指令,但可以跳出不只一層的結(jié)構(gòu))。
狀態(tài)機(jī)
有些程序(例如語(yǔ)法分析器或是處理通信協(xié)議的程序)有許多的狀態(tài)(英語(yǔ):state (computer science)),因此程序進(jìn)行的過(guò)程會(huì)在各狀態(tài)中切換,此架構(gòu)不容易簡(jiǎn)化成基本的控制結(jié)構(gòu)??梢詫⒋思軜?gòu)各狀態(tài)下的程序分別獨(dú)立為子程序,再用一個(gè)變量表示目前的狀態(tài),(可參考trampoline(英語(yǔ):trampoline (computers))),另一種作法是用goto的方式切換到新?tīng)顟B(tài)對(duì)應(yīng)的程序。
相關(guān)條目
控制流程
短路求值
面向?qū)ο蟪绦蛟O(shè)計(jì)
Nassi-Shneiderman圖
編程范型
異常處理
結(jié)構(gòu)圖(英語(yǔ):Structure chart)
switch指令(英語(yǔ):Switch statement),可視為許多goto的組合
非結(jié)構(gòu)化程序設(shè)計(jì)
免責(zé)聲明:以上內(nèi)容版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請(qǐng)告知,我們將盡快刪除相關(guān)內(nèi)容。感謝每一位辛勤著寫(xiě)的作者,感謝每一位的分享。
- 有價(jià)值
- 一般般
- 沒(méi)價(jià)值
{{item.userName}} 舉報(bào)
{{item.time}} {{item.replyListShow ? '收起' : '展開(kāi)'}}評(píng)論 {{curReplyId == item.id ? '取消回復(fù)' : '回復(fù)'}}
{{_reply.userName}} 舉報(bào)
{{_reply.time}}