Структурнае праграмаваньне

парадыгма праграмаваньня

Структураванае праграмаваньне — гэта парадыгма праграмаваньня, накіраваная на паляпшэньне яснасьці, якасьці і часу распрацоўкі кампутарнае праграмы шляхам шырокага выкарыстаньня структураваных канструкцый кіраваньня патокам для выбару, як if..then..else..endif, і паўтарэньня, як while і for, блёкавых структур і падпраграм.

Зьявілася ў канцы 1950-х гадоў з мовамі праграмаваньня ALGOL 58 і ALGOL 60,[1] прычым апошняя ўключала падтрымку блёкавых структур. Фактары, якія спрыялі яго папулярнасьці і шырокаму прызнаньню спачатку ў акадэмічных колах, а потым і сярод спецыялістаў-практыкаў, уключаюць адкрыцьцё ў 1966 г. таго, што цяпер вядома як тэарэма аб структураванай праграме,[2] і публікацыю ўплывовага адкрытага ліста «Шкоднае сцьвярджэньне GOTO» у 1968 г. галяндскім інфарматыкам Эдсгерам Дэйкстрам, які ўвёў тэрмін «структураванае праграмаваньне».[3]

Структураванае праграмаваньне часьцей за ўсё выкарыстоўваецца з адхіленьнямі, якія дазваляюць больш выразныя праграмы ў некаторых асобных выпадках, напрыклад, калі неабходна выканаць апрацоўку выключэньняў.

Элемэнты

рэдагаваць

Структуры кіраваньня

рэдагаваць

Згодна з тэарэмаю аб структураванай праграме усе праграмы разглядаюцца як складзеныя з трох структур кіраваньня:

  • «Паслядоўнасць» — упарадкаваныя інструкцыі або падпраграмы, якія выконваюцца паслядоўна.
  • «Выбар» — выконваецца адна або шэраг інструкцый у залежнасьці ад стану праграмы. Звычайна для гэтага выкарыстоўваюцца такія ключавыя словы, як if..then..else..endif. Умова павінна праўдзіцца хаця бы ў адным выпадку, і кожная ўмова павінна мець толькі адзін пункт выхаду.
  • «Ітэрацыя» — інструкцыя або блёк выконваецца, пакуль праграма не дасягне пэўнага стану, або апэрацыі не будуць прымененыя да кожнага элемэнта калекцыі. Ключавыя словы while, repeat, for або do..until звычайна ўжываюцца для гэтага. Часта рэкамендуецца, каб кожны цыкль меў адзіны пункт ўваходу (а ў арыгінальным структураваным праграмаваньні таксама адзіны пункт выхаду, што забясьпечваюць некаторыя мовы).
 
Графічнае адлюстраваньне трох асноўных канструкцый — паслядоўнасьці, выбару і паўтарэньня — з выкарыстаньнем дыяграм Насі-Шнэйдэрмана (сіні) і блёк-схем (зялёны).

Падпраграмы

рэдагаваць

Падпраграмы — часткі кода, якія можна выклікаць, такія як працэдуры, функцыі або мэтады. Выкарыстоўваюцца для таго, каб на паслядоўнасць інструкцый можна было спасылацца адной інструкцыяй.

Блёкі выкарыстоўваюцца для таго, каб аб’яднаць групу інструкцый ў адну інструкцыю. Мовы з блёчнай структураю маюць сынтакс для групаваньня структур нейкім фармальным спосабам, напрыклад, канструкцыя if..fi, як у ALGOL 68, або блёк кода ў межах BEGIN..END, як у PL/I і Pascal, водступы пропускамі, як у Python, або фігурныя дужкі {...} у C і многіх пазьнейшых мовах.

Структураваныя мовы праграмаваньня

рэдагаваць

Структураванае праграмаваньне магчымае на любой мове праграмаваньня, хоць лепш выкарыстоўваць нешта накшталт працэдурнае мовы праграмаваньня.[4][5] Некаторыя з моў, якія першапачаткова выкарыстоўваліся для структураванага праграмаваньня, уключаюць: ALGOL, Pascal, PL/I, Ada і RPL. Большасць новых працэдурных моў праграмаваньня маюць функцыі для заахвочваньня структураванага праграмаваньня, а часам наўмысна выключаюць некаторыя функцыі, асабліва GOTO, у спробе ўскладніць неструктураванае праграмаваньне.

Структураванае праграмаваньне (часам вядомае як модульнае праграмаванне[6]) прымушае, каб лягічная структуру праграмы была прапісаная, што робіць праграму больш эфэктыўнай і прасцейшай для разуменьня і мадыфікацыі.

Гісторыя

рэдагаваць

Тэарэтычныя асновы

рэдагаваць

Тэарэма аб структураванай праграме забясьпечвае тэарэтычную аснову структураванага праграмаваньня. У ёй сцьвярджаецца, што канструкцый трох тыпаў (паслядоўнасьці, выбару і ітэрацыі) дастаткова для вызначэньня любое вылічальнае функцыі. Гэтае назіраньне ўзнікла раней за структураванае праграмаваньне так, як вышэй названых структур дастаткова для апісаньня іншых зьяў, напрыклад, цыкля інструкцый цэнтральнага працэсара або машыны Т’юрынга. Такім чынам, працэсар заўсёды, у гэтым сэнсе, выконвае «структураваную праграму», нават калі інструкцыі, якія ён чытае з памяці, не з’яўляюцца часткаю структураванае праграмы. Аднак аўтарства тэрміну звычайна прыпісваюць Бёма і Якапіні, магчыма таму, што Дэйкстра сам цытаваў іх працу 1966 года.[7] Тэарэма аб структураванай праграме не датычыцца таго, як напісаць і прааналізаваць структураваную праграму, гэтыя пытаньні разглядалася ў канцы 1960-х і пачатку 1970-х гадоў у працах Дэйкстры, Роберта У. Флойда, Тоні Хоара, Оле-Ёхана Даля і Дэвіда Грыса.

Адзін з першых прыхільнікаў структураванага праграмаваньня Філіп Дж. Пладжэр апісаў сваю рэакцыю на тэарэму аб структураванай праграме так:

Мы, новазьвернутыя, размахвалі гэтай цікавай навіною пад носам у нерэканструяваных праграмістаў асэмблера, якія працягвалі ламаць галовы і казаць: «Не магу структураваць гэта». Ні доказы Бёма й Якапіні, ні нашы неаднаразовыя посьпехі ў напісаньні структураванага кода не паўплывалі на іх, пераканаць сябе маглі толькі яны самі.[8]

Дональд Кнут прыняў прынцып, што праграмы павінны пісацца з улікам доказнасьці, але ён не пагадзіўся з забаронаю канструкцыі GOTO, і працягваў выкарыстоўваць яе ў сваіх праграмах.[9] У сваёй працы 1974 г. «Структураванае праграмаваньне з GOTO»[10] ён прывёў прыклады, дзе, на яго думку, прамы скачок прыводзіць да больш выразнага і эфэктыўнага кода бяз шкоды для доказнасьці. Кнут прапанаваў больш свабоднае структурнае абмежаваньне: павінна быць магчымасьць намаляваць блёк-схему праграмы з усімі прамымі галінамі злева, усімі зваротнымі галінамі справа і без галін, якія перасякаюць адна адну.

Прыхільнікі структураванага праграмаваньня займелі значнага саюзніка ў 1970-х гадах пасля таго, як дасьледчык IBM Харлан Мілс прымяніў сваю інтэрпрэтацыю тэорыі структураванага праграмаваньня да распрацоўкі сыстэмы індэксаваньня для The New York Times. Праект меў вялікі інжынэрны посьпех, і мэнэджары іншых кампаній цытавалі яго ў падтрымку структураванага праграмаваньня, хоць Дэйкстра крытыкаваў тое, чым інтэрпрэтацыя Мілза адрозьнівалася ад апублікаванае працы.[11]

Яшчэ ў 1987 годзе можна было падняць пытаньне аб структураваным праграмаваньні ў часопісах па інфарматыцы. Фрэнк Рубін зрабіў гэта ў тым годзе з адкрытым лістом пад назваю «'GOTO лічыцца шкодным' лічыцца шкодным».[12] Услед рушылі шматлікія пярэчаньні, у тым ліку адказ Дэйкстры, які рэзка крытыкаваў як Рубіна, так і іншых аўтараў, зрабіўшых таму саступкі.

Да канца 20-га стагодьдзя амаль усе зацікаўленыя навукоўцы былі перакананыя, што карысна вывучаць і прымяняць канцэпцыі структураванага праграмаваньня. Мовы праграмаваньня высокага ўзроўню, у якіх першапачаткова не хапала структуры праграмаваньня, такія як Fortran, COBOL і BASIC, цяпер іх маюць.

Распаўсюджаныя адхіленьні

рэдагаваць

У той час як goto цяпер у значнай ступені заменены структураванымі канструкцыямі выбару (if/then/else) і паўтарэньня (while і for), нешматлікія мовы з’яўляюцца чыста структураванымі. Найбольш распаўсюджаным адхіленьнем характэрным для многіх моў, з’яўляецца выкарыстаньне return для раньняга выхаду з падпраграмы. Гэта прыводзіць да некалькіх пунктаў выхаду замест аднаго, неабходнага ў структураваным праграмаваньні. Ёсць і іншыя канструкцыі, нязручныя ў чыста структураваным праграмаваньні.

Раньні выхад

рэдагаваць

Найбольш распаўсюджаным адхіленьнем ад структураванага праграмаваньня з’яўляецца раньні выхад з функцыі або цыкля. На ўзроўні функцый гэта сцьвярджэньне return. На ўзроўні цыкляў гэта break (завяршэньне цыкля) або continue (завяршэньне бягучае ітэрацыі, пераход да наступнае ітэрацыі). У структураваным праграмаваньні іх можна рэплікаваць шляхам даданьня дадатковых галін або тэстаў, але для вяртаньня з укладзенага кода гэта можа значна прыбавіць складанасьці. C з’яўляецца раньнім і яркім прыкладам гэтых канструкцый. Некаторыя новыя мовы таксама маюць «найменаваныя перапынкі», якія дазваляюць больш, чым проста выйсьце з самага ўнутранага цыкля. Выключэньні таксама дазваляюць датэрміновы выхад, але маюць дадатковыя наступствы, і таму разглядаюцца ніжэй.

Множныя выхады могуць узнікаць па розных прычынах, часцей за ўсё альбо з-за таго, што ў падпраграмы больш няма працы (калі яна вяртае значэньне, яна завяршыла вылічэньне), альбо сутыкнулася з «выключнымі» абставінамі, якія перашкаджаюць ёй працягваць працу, таму патрабуецца апрацоўка выключэньняў.

Самая распаўсюджаная праблема раньняга выхаду заключаецца ў тым, што не выконваюцца ачыстка або фінальныя інструкцыі, напрыклад, выдзеленая памяць не вызваляецца або адкрытыя файлы не зачыняюцца, што выклікае ўцечку памяці або рэсурсаў. Гэта трэба рабіць на кожным месцы выхаду з падпраграмы, што патрабуе дадатковай увагі і можа лёгка прывесьці да памылак. Напрыклад, распрацоўшчык можа прапусьціць інструкцыю return, і дзеяньне, якое павінна быць выканана ў канцы падпраграмы (напрыклад, трасіроўка), можа выконвацца не ва ўсіх выпадках. Мовы без інструкцыі return, такія як стандартны Pascal і Seed7, не маюць гэтае праблемы.

Большасьць сучасных моў маюць сродкі, каб прадухіліць такія ўцечкі.[13] Часцей за ўсё гэта робіцца з дапамогаю абароны ад размотваньня, якая гарантуе, што пэўны код будзе выкананы, калі выкананьне выходзіць за межы блёка; гэта структурная альтэрнатыва блёку ачысткі і goto. Канструкцыя try... finally, якая лічыцца часткаю апрацоўкі выключэньняў, можа быць ужытая для гэтага. Існуюць розныя мэтады кіраваньня рэсурсамі. Альтэрнатыўны падыход, які сустракаецца ў асноўным у C++, вядомы пад назваю «Атрыманьне рэсурса ёсьць ініцыялізацыя». Пры гэтым выкарыстоўваецца звычайнае размотваньне стэка пры выхадзе з функцыі для выкліку дэструктараў лякальных зьменных для вызваленьня рэсурсаў.

Кент Бэк, Марцін Фаўлер разам з сааўтарамі ў сваіх кнігах па рэфактарынгу сцьвярджалі, што ўмоўныя інструкцыі глыбокага ўзроўню ўкладзенасьці могуць быць цяжэйшымі для разуменьня, чым пэўны тып больш плоськіх структур з выкарыстаньнем некалькіх выхадаў анатаваных ахоўным кодам. У іх кнізе 2009 года сьцьвярджаецца, што «адзіны пункт выхаду — гэта сапраўды нязручнае правіла. Яснасць — ключавы прынцып: калі мэтад больш зразумелы з адным пунктам выхаду, выкарыстоўвайце адзін пункт выхаду — у адваротным выпадку не». Яны прапануюць гатовае рашэньне для пераўтварэньня функцыі, якая складаецца толькі з укладзеных умоўных інструкцый, у паслядоўнасць інструкцый вяртаньня з ахоўным кодам (або выкідаў), за якімі ідзе адзіны неабаронены блёк кода для звычайнага выпадку, у той час як абароненыя код павінны мець справу з менш распаўсюджанымі выпадкамі (або з памылкамі).[14] Герб Сатэр і Андрэй Александрэску таксама сьцьвярджаюць у сваёй кнізе па C++ за 2004 г., што адзіны пункт выхаду з’яўляецца састарэлым патрабаваньнем.[15]

У сваім падручніку 2004 г. Дэвід Уат піша, што «патокі кіраваньня з адным уваходам і некалькімі выхадамі часта пажаданыя». Выкарыстоўваючы паняцьце сэквэнсара з фрэймворка Тэнанта, Уат апісвае канструкцыі кіраваньня патокам сучасных моў праграмаваньня, і спрабуе растлумачыць, чаму некаторыя тыпы сэквэнсараў пераважней іншых у кантэксьце патокаў з некалькімі выхадамі. Уат піша, што неабмежаваныя goto (сэквэнсары пераходаў) дрэнныя, таму што пункт прызначэньня пераходу не з’яўляецца для чытача праграмы зразумелым, пакуль чытач не знойдзе і не вывучыць фактычную метку або адрас, які з’яўляецца мэтаю пераходу. Наадварот, Уат сцвярджае, што канцэптуальны намер сэквэнсара вяртаньня ясны з яго ўласнага кантэксту без неабходнасьці вывучэньня яго прызначэньня. Уат піша, што клас сэквэнсараў, вядомы як сэквэнсар выхаду, вызначаецца як «сэквэнсар, які завяршае выкананьне ахопленае тэкстам каманды або працэдуры», уключае як перапыненьні цыкляў (у тым ліку шматузроўневыя перапыненьні), так і інструкцыі вяртаньня. Уат таксама адзначае, што ў той час як сэквэнсары пераходаў (goto) некалькі абмежаваныя ў такіх мовах, як C, дзе пункт прызначэньня павінны быць унутры лякальнага блёка або ахопліваючага вонкавага блёка, аднаго гэтага абмежаваньня недастаткова, каб зрабіць намер goto у C зразумелым, і таму яны ўсё яшчэ могуць прыводзіць да «спагэцьці-кода». Уат таксама вывучае, чым сэквэнсары выключэньняў адрозніваюцца ад сэквэнсараў выхаду і пераходу; што тлумачыцца ў наступным раздзеле гэтага артыкула.[16]

У адрозненне ад вышэйсказанага, Бертран Мэяр піша ў сваім падручніку 2009 года, што такія інструкцыі, як break і continue, «гэта проста старая goto у авечай шкуры», і настойліва не раіць іх выкарыстоўваць.[17]

Апрацоўка выключэньняў

рэдагаваць

Грунтуючыся на праграмнай памылцы, якая прывяла да катастрофы Ariane 501, распрацоўшчык праграмнага забеспячэньня Джым Бонанг сьцьвярджае, што любыя выключэньні, выкінутыя па-за межы функцыі, парушаюць парадыгму адзінага выхаду, і прапануе забараніць усе міжпрацэдурныя выключэньні. Бонанг прапануе, каб увесь код на C++ пісаўся наступным чынам:

bool MyCheck1() throw() {
  bool success = false;
  try {
    // Зрабіць нешта, што можа выкінуць выключэньне
    if (!MyCheck2()) {
      throw SomeInternalException();
    }
    // Іншы код, такі ж як вышэй
    success = true;
  } catch (...) {
    // Усе выключэньні перахватываюцца і апрацоўваюцца
  }
  return success;
}

Пітар Рычы таксама адзначае, што, у прынцыпе, нават адзіночны throw непасрэдна перад return у функцыі з’яўляецца парушэннем прынцыпу адзінага выхаду, але сьцьвярджае, што правілы Дэйкстры былі напісаны яшчэ да таго, як апрацоўка выключэньняў стала парадыгмаю у мовах праграмаваньня, таму ён прапануе дазволіць любую колькасць пунктаў выкідваньня выключэньняў у дадатак да адзінага пункту выхаду. Ён адзначае, што рашэньні, якія абгортваюць выключэньні дзеля стварэньня адзінага выхаду, павялічваюць глыбіню ўкладзенасьці і, такім чынам, складаней для разуменьня, і нават абвінавачвае тых, хто прапануе прымяняць такія рашэньні да моў праграмаваньня, якія падтрымліваюць выключэньні, ва ўдзеле ў культавым мысленьні.[18]

Дэвід Уат таксама аналізуе апрацоўку выключэньняў з дапамогаю фрэймворка сэквэнсараў. Уат адзначае, што ненармальная сітуацыя (як правіла, прыкладам якой з’яўляюцца арытмэтычныя перапаўненьні або збоі ўводу/вываду, напрыклад, файл не знойдзены) належыць да тыпу памылак, якія «выяўляюцца ў праграмным блёку нізкага ўзроўню, але апрацоўшчык для якіх больш натуральна знаходзіцца ў праграмным блёку больш высокага ўзроўню». Напрыклад, праграма можа мець некалькі зваротаў да файлаў, але дзеяньне, якое трэба выканаць, калі пэўны файл не знойдзены, залежыць ад мэты звароту да файла, і, такім чынам, працэдура апрацоўкі гэтае ненармальнае сітуацыі не можа быць размешчана ў кодзе нізкага ўзроўню. Далей Уат адзначае, што тэсціраваньне сцягоў стану ў месцы выкліку ў структураваным праграмаваньні з адным або, нават, з некалькімі выхадамі, прыводзіць да сітуацыі, калі «код мае тэндэнцыю загрувашчвацца тэстамі сцягоў стану» і «праграміст можа забыцца або паляніцца зьдейсьніць праверку сцяга стану. Фактычна, ненармальныя сітуацыі, прадстаўленыя сцягамі стану, ігнаруюцца па змаўчаньні!» Ён адзначае, што ў адрозненьні ад тэсціраваньня сцягоў стану, выключэньні маюць супрацьлеглыя паводзіны па змаўчаньні, прымушаючы праграму спыняцца, калі толькі праграміст нейкім чынам не апрацуе выключэньне, магчыма, дадаўшы код, каб наўмысна яго ігнараваць. Грунтуючыся на гэтых аргумэнтах, Уат прыходзіць да высновы, што сэквэнсары пераходу або выхаду не такія прыдатныя, як спецыяльны сэквэнсар выключэньняў з сэмантыкай, разгледжанай вышэй.[19]

У падручніку Лоўдэна і Ламбэрта падкрэсліваецца, што апрацоўка выключэньняў адрозніваецца ад канструкцый структураванага праграмаваньня, такіх як цыклі while, таму што перадача кіраваньня «фактычна адбываецца ў іншым месцы праграмы, а не дзе яна вызначаецца. У месцы, дзе фактычна адбываецца перадача, можа не быць сынтаксічных прыкмет таго, што кіраваньне сапраўды будзе перададзена».[20] Прафэсар інфарматыкі Арвінд Кумар Бансал таксама адзначае, што ў мовах, якія рэалізуюць апрацоўку выключэньняў, нават такія кіруючыя структуры, як for, якія маюць уласьцівасьць адзінага выхаду, больш не маюць яе пры наяўнасці выключэньняў, таму што выключэньне можа заўчасна выклікаць раньні выхад у любой частцы структуры кіраваньня; напрыклад, калі init() стварае выключэньне ў for (init(); check(); increm()), то звычайны пункт выхаду пасьля check() не дасягаецца.[21] Спасылаючыся на шматлікія папярэднія даследаваньні іншых навукоўцаў (1999—2004) і свае ўласныя, Уэстлі Вэймар і Джордж Нэкула пісалі, што істотная праблема з выключэньнямі заключаецца ў тым, што яны «ствараюць схаваныя шляхі кіраваньня патокам, пра якія праграмістам цяжка разважаць».[22]

Неабходнасць абмежаваньня да кода з адным выхадам з’яўляецца ў некаторых сучасных асяродьдзях праграмаваньня, арыентаваных на паралельныя вылічэньні, такіх як OpenMP. Розныя паралельныя канструкцыі з OpenMP, такія як parallel do, не дазваляюць раньнія выхады. Гэта абмежаваньне ўключае ўсе спосабы выхаду, ад break да выключэньняў C++, але ўсе яны дазволеныя ўнутры паралельнай канструкцыі, калі мэта пераходу таксама знаходзіцца ўнутры яе.[23]

Множны ўваход

рэдагаваць

Радзей падпраграмы дазваляюць множны ўвод. Часьцей за ўсё гэта толькі паўторны ўваход у супраграму (або генэратар/паўсупраграму), дзе выкананьне перапыняецца, але затым можа быць адноўлена з таго месца, дзе яно спынілася. Ёсць шэраг агульных варыянтаў выкарыстаньня такога праграмаваньня, напрыклад, для патокаў уводу/вываду, канцоўных аўтаматаў і паралелізму. З пункту гледжаньня выкананьня кода, перапыненьне супраграмы бліжэй да структураванага праграмавання, чым вяртаньне з падпраграмы, паколькі супраграма фактычна не была завершаная і будзе працягвацца пры паўторным выкліку, што адрозьніваецца ад раньняга выхаду. Аднак супраграмы азначаюць, што некалькі падпраграм маюць стан выкананьня, а не адзіны стэк выклікаў, такім чынам, уводзіцца іншая форма складанасьці.

Вельмі рэдка дазваляецца ўваход у адвольную пазіцыю ў супраграме, бо ў гэтым выпадку стан праграмы (напрыклад, значэньні зьменных) неініцыялізаваныя або неадназначныя, і гэта вельмі падобна на GOTO.

Канцоўныя аўтаматы

рэдагаваць

Некаторыя праграмы, у прыватнасьці парсэры й камунікацыйныя пратаколы, маюць шэраг станаў, якія ідуць адзін за адным такім чынам, што іх няпроста зьвесьці да базавых структур, і некаторыя праграмісты рэалізуюць зьмены станаў «скачком» у новы стан.

Тым не менш, можна структураваць гэтыя сыстэмы, зрабіўшы кожную зьмену стану асобнай падпраграмаю і выкарыстоўваючы зьменную для ўказаньня актыўнага стану (гл. трамплін). У якасці альтэрнатывы яны могуць быць рэалізаваныя праз супраграмы, якія абыходзяцца без трамплінаў.

  1. ^ Лэслі Уілсон, Роберт Кларк Параўнаньне моў праграмаваньня = Comparative programming languages. — 3-е. — Гарлоў, Англія: Addison-Wesley, 2000. — С. 20. — ISBN 9780201710120
  2. ^ Карада Бём, Джузэпэ Якопіні Дыяграмы патоку, машыны Т'юрынга й мовы толькі з двума фармальнымі правіламі  (анг.) = Flow Diagrams, Turing Machines and Languages with Only Two Formation Rules // Communications of the ACM. — Май 1966. — Т. 9. — С. 366–371. — DOI:10.1145/355592.365646
  3. ^ «З-за неабмежаванае выкарыстаньне інструкцыі GOTO становяцца жудасна цяжкімі пошукі хоць якога-небудзь набору каардынатаў, у якіх можна апісаць ход працэсу. … Інструкцыя GOTO у цяперашнім выглядзе занадта прымітыўная, гэта верны спосаб забрудзіць сваю праграму.» — Эдсгер Дэйкстра (1968)
    Эдсгер Дэйкстра Ліст да рэдактара. GOTO лічыцца шкодным  (анг.) = Letters to the editor: Go to statement considered harmful // Communications of the ACM. — Сакавік 1968. — Т. 11. — С. 147–148. — ISSN 0001-0782. — DOI:10.1145/362929.362947
  4. ^ Што такое структураванае праграмаваньне = What is Structured Programming? (анг.) Software Quality
  5. ^ Структураванае праграмаваньне | ITE 115 Уводзіны ў кампутарныя дадаткі й канцэпцыі = Reading: Structured Programming | ITE 115 Introduction to Computer Applications and Concepts (анг.) courses.lumenlearning.com
  6. ^ Што такое структураванае праграмаваньне? = What is Structured Programming? (анг.) Software Quality
  7. ^ Эдсгер Дэйкстра Ліст да рэдактара. GOTO лічыцца шкодным  (анг.) = Letters to the editor: Go to statement considered harmful // Communications of the ACM. — Сакавік 1968. — Т. 11. — С. 147–148. — ISSN 0001-0782. — DOI:10.1145/362929.362947
  8. ^  Пладжэр, Філіп Дж. Мэтавае праграмаваньне, эсэ па праектаваньню праграмнага забесьпячэньня = Programming on Purpose, Essays on Software Design. — 1-е. — Prentice-Hall, 12-02-1993. — С. 25. — ISBN 978-0-13-721374-0
  9. ^ DLS • Дональд Кнут • Адказы на ўсе пытаньні = DLS • Donald Knuth • All Questions Answered (анг.) YouTube. Унівэрсытэт Уатэрлоо (15-11-2018).
  10. ^ Дональд Кнут Структураванае праграмаваньне з інструкцыяй GOTO  (анг.) = Structured programming with go to statements // Computing Surveys. — Снежань 1974. — Т. 6. — С. 261–301. — DOI:10.1145/356635.356640
  11. ^ «Відаць, IBM не спадабалася папулярнасць майго тэксту. Яны выкралі тэрмін „структураванае праграмаваньне“ і пад яго эгідаю Харлан Д. Мілс спрасьціў першапачатковую канцэпцыю да забароны інструкцыі GOTO.» — Эдсгер Дэйкстра (2001)
    Эдсгер Дэйкстра (10-06-2001) Што прывяло да "Нататак пра структураванае праграмаваньне" = What led to "Notes on Structured Programming" (анг.)
  12. ^ Фрэнк Рубін "GOTO лічыцца шкодным" лічыцца шкодным  (анг.) = "GOTO Considered Harmful" Considered Harmful // Communications of the ACM. — Сакавік 1987. — Т. 30. — С. 195–196. — DOI:10.1145/214748.315722
  13. ^ Мэт Элдэр, Стыў Джэксан, Бэн Лібліт (Кастрычнік 2008) Сэндвічы з коду = Code Sandwiches (анг.). University of Wisconsin–Madison.
  14. ^ Джэй Філдс, Шэйн Гарві, Мартын Фаўлер, Кэнт Бэк Рэфакторынг. Рубінавае выданьне = Refactoring: Ruby Edition. — Pearson Education, 2009. — С. 274–279. — ISBN 978-0-321-60350-0
  15. ^ «Прыклад 4: Адзіны ўваход, адзіны выхад.
    Гістарычна склалася так, што некаторыя стандарты праграмаваньня патрабавалі, каб кожная функцыя мела роўна адзін выхад, што азначае адну інструкцыю вяртаньня. Такое патрабаваньне састарэла ў мовах, якія падтрымліваюць выключэньні і дэструктары, дзе функцыі звычайна маюць мноства няяўных выхадаў.» — Герб Сатэр, Андрэй Александрэску.
    Герб Сатэр, Андрэй Александрэску Стандарт праграмаваньня на C++: 101 правіла, рэкамэндацыя й лепшыя практыкі = C++ Coding Standards: 101 Rules, Guidelines, and Best Practices. — Pearson Education, 2004. — ISBN 978-0-13-265442-5
  16. ^ Дэвід Энтані Уатт, Уільям Фіндлэй Канцэпцыі праектаваньня моў праграмаваньня = Programming language design concepts. — John Wiley & Sons, 2004. — С. 215–221. — ISBN 978-0-470-85320-7
  17. ^ Бэрнард Мэяр Знаёмства з клясамі. Вучымся добра праграмаваць з аб'ектамі й кантрактамі = Touch of Class: Learning to Program Well with Objects and Contracts. — Springer Science & Business Media, 2009. — С. 189. — ISBN 978-3-540-92144-8
  18. ^ Адзіны ўваход, адзіны выхад, ці гэта патрэбна ў аб'ектна-арыентаваным праграмаваньні = Single-Entry, Single-Exit, Should It Still be Applicable in Object-oriented Languages? (анг.) Peter Ritchie's MVP Blog Архіўная копія ад 2012-11-14 г.
  19. ^ Дэвід Энтані Уат, Уільям Фіндлэй Канцэпцыі праектаваньня моў праграмаваньня = Programming language design concepts. — John Wiley & Sons, 2004. — С. 221–222. — ISBN 978-0-470-85320-7
  20. ^ Кэнэт С. Лаўдэн, Кэнэт А. Ламбэрт Мовы праграмаваньня. Прынцыпы й практыкі = Programming Languages: Principles and Practices. — 3-е. — Cengage Learning, 2011. — P. 423. — ISBN 978-1-111-52941-3
  21. ^ Арвінд Кумар Бансал Уводзіны ў мовы праграмаваньня = Introduction to Programming Languages. — CRC Press, 2013. — С. 135. — ISBN 978-1-4665-6514-2
  22. ^ Уэстлі Вэймар, Джордж Нэкула Выключныя сітуацыі і надзейнасць праграмы  (анг.) = Exceptional Situations and Program Reliability. — 2008. — Т. 30. — С. 8-27. — DOI:10.1145/1330017.1330019
  23. ^ Рагіт Чандра Паралельнае праграмаваньне з OpenMP = Parallel Programming in OpenMP. — Morgan Kaufmann, 2001. — С. 45. — ISBN 978-1-55860-671-5