У науци о компјутерима for-петља (или једноставније for петља) је контролна изјава у програмским језицима за навођење итерације (понављања) , која омогућава коду да се извршава у више наврата. Синтакса for петље је направљена у стилу програмског језика у којем се користи или је позајмљена из старијих програмских језика, па тако програмски језици који су потомци или изданци истог језика ће често користити исту реч да означе итератор, нпр., потомци ALGOL-а користе „for“, док потомци Fortran-а користе „do“. Постоје и друге могућности, на пример COBOL користи „PERFORM“.
За разлику од других петљи, као што је while петља, for петље често одликују израженији бројачи или израженије променљиве. Ово омогућава телу for петље (код који се у више наврата извршава) да зна редослед сваког понављања. For петље се углавном користе када се број понављања зна пре него што се петља напише. Када се while петља може написати као For петља и када се зна број понављања, боље је користити For петљу јер је краћа.
Име For петље потиче од енглеске речи for, која се користи као кључна реч у највећем броју програмских да би се увела for петља. Овај израз се користио још у ALGOL-у 58, а постао је популаран касније у ALGOL-у 60; он је директан превод немачке речи für, коришћене у Superplan-у (1949-1951) Хајнца Рутисхаусера, који је такође био укључен у програмирању ALGOL-а 58 и ALGOL-а 60. Тело петље извршава „for“ за вредности променљивих из петље, и ово је много израженије у ALGOL изјавама, у којима се листе потенцијалних вредности и/или корака могу одредити.
У FORTRAN и PL/I, се користи кључна реч DO, а петља се зове do петља, и пошто је скоро идентична for петљи описаној овде, нећемо је користити како је не би мешали са do while петљом.
Врсте for петљи
Изјаве For петљи су доступне у већини императивних програмских језика. Чак и игноришући мање разлике у синтаксама постоји много разлика у томе како ове изјаве раде и какав ниво изражајности подржавају. Генерално for петље се могу поделити на:
for(УВОЂЕЊЕ;УСЛОВ;НАКНАДНАМИСАО){// Код тела фор петље иде овде}
У увођењу се наводе (вероватно и додељују) све потребне променљиве. Тип променљивих би требало да буде исти ако користите више променљивих у делу увођења. Услов проверава услов, и прекида петљу ако услов даје логички одговор нетачно. Накнадна мисао се извршава само једном сваки пут када се петља завршава и понавља.
Овај тип for петље је копија for петље засноване на нумеричким опсезима; јер омогућава бројање скупова ставки који не морају бити низови бројева. Обично се одликује употребом имплицитног или експлицитног итератора, у којој променљива петље преузима вредност из секвенци или из друге могуће колекције. Репрезентативан пример у Пајтону је:
forstavkainobjekat:uradineštouradineštodrugo
Где је објекат или колекција која подржава имплицитно понављање (као листа имена запослених) или је то можда сам итератор. Неки језици имају ово као додатак другим синтаксама for петље; посебно PHP има овај тип петље под именом for each, као и троизразну for петљу (видети доле) под именом for.
Векторизоване for петље
Неки језици нуде for петље које обављају if процес на свим понављањима паралелно, за разлику од експлицитне форме понављања. На пример то ради кључна реч for all у FORTRAN 95, који има тумачење да су сви изрази са десне стране вредновани пре него што су задаци направљени. У 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;
Разлика може бити значајна.
Неки језици (као FORTRAN 95, PL/I) такође нуде низ изјава за додељивање, које омогућују да многе for петље буду изостављене. Тако ће псеудокод A := 0; поставити све елементе низа А на нулу, без обзира на њену величину или димензију. На пример таква петља може бити:
A(2:N-1):=[A(1:N-2)+A(2:N-1)+A(3:N)]/3;
Да ли је изражена у стилу for петље, for all петље или неке друге можда неће бити тачно описано у упутству.
Спојене for петље
Уведене у ALGOL 68 и испраћене са PL/I, омогућавају да понављање петље буде спојено са испитивањем, као у
for i := 1 : N while A(i) > 0 uradi itd.
То јест, вредност је додељена променљивој i и само ако је израз тачан тело петље ће се извршити. Ако је вредност нетачна израчунавање се завршава. Под претпоставком да је вредност променљиве дефинисана након завршетка петље, горња наредба ће пронаћи први не позитиван елемент низа А (ако такав не постоји, негова вредност ће бити N+1) или, са одговарајућим варијантама, први не празан карактер у ниској, итд.
Додатне семантике и конструкције
Коришћење бесконачне петље
Овај С-стил for петљи је још од основних корака понављања је потпуно у контроли програмера. У ствари, када су бесконачне петље намерно створене, ова врста for петљи се може користити (са празним изразима) као:
for(;;)//тело петље
Овај стил се користи уместо бесконачне while (1) петље да би се избегло упозорење у неким С/С++ компајлерима.[3] Неки програмери воле више језгровиту for (;;) форму него семантички еквивалентну али опширнију while (тачно) форму.
Рани излаз и наставак
Неки језици такође могу да пруже и друге пратеће изјаве, које када су присутне могу да мењају понављање for петље. Заједничке међу њима су break и continue изјаве које се налазе у C програмском језику и његовим изданцима. Изјава break прекида петљу одмах након задатог услова. Изјава continue ће одмах кренути на следећу итерацију без даљег напретка кроз тело петље за текућу итерацију. Остали језици могу имати сличне изјаве или да на други начин обезбеде средства за мењање for петље ; на пример у FORTRAN-у 95:
DO I=1,Nизјаве!Извршава све вредности за "I", све до катастрофе ако постоји.IF(ниједобро)CYCLE!Прескаче ову вредност за "I", наставља са следећом.изјаве!Извршава само где је добро.IF(катастрофа)EXIT!Напушта петљу.изјаве!Све док је добро, док није катастрофа.END DO!Треба да се усклади са "DO".
Обим променљиве у петљи и семантика
Различити језици наводе различита правила за оно што ће вредност променљиве у петљи имати након завршетка петље. Ово дозвољава преводиоцу да генерише код који не оставља никакву вредност променљивој из петље, или можда чак и оставља, али је то непромењена вредност петље и никада се не чува у меморији. Стварно понашање може чак да варира у складу са поставкама оптимизације компајлера, као са Honywell Fortran66 компајлером.
У неким језицима (али не у С и C++) петља променљиве је непроменљива у оквиру тела петље, сваки покушај да се промени њена вредност сматра се семантичком грешком. Такве модификације су понекад последица грешке програмера, што може бити веома тешко идентификовати. Међутим сама грешка ће вероватно бити откривена од стране људи који проверавају код. Ситуације у којима адресе променљивих у петљи пролазе као аргументи потпрограма су веома тешко проверљиве, јер понашање рутине је у целини непознато у компајлеру. Неки примери у Фортрановом стилу:
DO I=1,NI=7!Очито подешавање променљиве из петље. Вероватно приговор.Z=ADJUST(I)!Функција "ADJUST" ће изменити "I", у неизвесно.нормалнеизјаве!Меморија ће избрисати да је "I" променљива из петље.PRINT(A(I),B(I),I=1,N,2)!Користи петљу да одштампа непарне елементе низа А и В, поново користећи "I"…PRINT I!Која вредност ће бити одштампана?END DO!Колико пута ће петља бити рачуната?
Заједнички приступ је да израчуна тачку понављања на почетку петље (са посебним освртом на изливање као у for i := 0 : 65535 do ... ; у шеснаестобитном интиџеру аритметике) и са сваким новим издањем смањи ово, рачунајући while такође додавањем вредности I: дупло бројање резултата. Такође прилагођавање вредности I: дупло бројати резултате. Међутим, прилагођавања вредности I у оквиру петље неће променити број понављања извршења.
Још једна могућност је да је код генерисан и може се користити помоћну променљиве као променљива петље, вероватно сачуваном у регистру, чија вредност може или не може бити копирана у I на сваком понављању. Опет, модификације I неће утицати на контролу петље, али сада је на раскрсници могуће: у оквиру петље, референце вредности I могу бити (евентуално измењене) садашње вредности I или помоћне променљиве I па су збуњујући резултати загарантовани. На пример, у оквиру петље референцу на елемент I низа вероватно ће запослити помоћну променљиве (поготово ако је одржана у регистру), али ако је параметар на неку рутину (на пример, штампање изјава открива своју вредност), вероватно би позивало на одговарајуће променљиве I. Најбоље је да се избегну такве могућности.
Прилагођавање граница
Баш као што индекс променљиве може бити модификован у оквиру for петљи, тако се могу мењати и границе и правци. Али са неизвесним ефектима. Преводилац може спречити такве покушаје, јер они можда немају никакав ефекат, или чак можда након тога неће радити исправно, мада би многи рекли да је погрешно то урадити. Размотрите изјаву као
for i := first : last : step do
A(i) := A(i) / A(last);
Ако приступ састављању такве петље треба да буде процена првог, последњег члана, броја корака и обрачун понављања са нечим као (последњи-први)/корак само на почетку, и онда ако те ставке буду једноставне променљиве и њихове вредности су некако увећане током понављања, то неће имати никаквог ефекта на итерацију count иако је елемент изабран за поделу са А (последњи) промењен.
Листа вредности опсега
PL/I и ALGOL 68 омогућава петљама у којима се налази променљива да се понављају изван опсега вредности уместо у једном опсегу. Следи PL/I пример који израчунава петљу са 6 вредности за i:1,7,12,13,14,15:
do i = 1, 7, 12 to 15;
/*изјаве*/
end;
Еквивалентност са while петљом
For петља се може конвертовати у еквивалентну while петљу дописивањем бројача променљиве директно. Следећи псеудокод показује ову технику:
faktorijel = 1
for broj from 1 to 5
faktorijel = faktorijel * broj
Лако се преводи у while петљу:
faktorijel = 1
broj = 1
while broj <= 5
faktorijel = faktorijel * broj
broj = broj + 1
Овај превод је мало компликован за језике који дозвољавају скакање до новог понављања у петљи (као continue изјава у С-у). Ове изјаве ће обично имплицитно повећавати број петље, али не и еквивалент while петље (јер у овом другом случају број није саставни део конструкције петље). Било који превод ће морати да стави све изјаве унутар блока који експлицитно повећава број пре покретања изјаве.
Хронологија синтаксе for петље у разним програмским језицима
На основу акције која мора бити поновљена, на пример, пет пута, различити језици ће for петљу написати другачије. Синтакса за три израза for петље је скоро идентична у свим језицима који га имају, након различитих стилова блока-крај петље и тако даље.
1957: FORTRAN
Док користите кључну реч do уместо for, овај тип FORTRAN-ове do петље се понаша слично као троаргументна for петља у осталим језицима. Овај пример се понаша исто као остали, иницијализујући број променљиве на 1, увећавајући је за 1 у свакој итерацији петље и стопирати када достигне вредност 5.
do broj=1,5,1write(*,'(i2)')brojend do
У FORTRAN-у for петља је еквивалентна са DO петљом. Синтакса Fortran-ове DO петље је:
DO ознакаброј=почетак,крај,коракизјавеознакаизјава
Где се део корака може изоставити уколико је корак један. Пример: (простори су ирелевантни у Fortran изјавама, тако SUM SQ је исто као SUMSQ)
! Пример DO петљеPROGRAM MAINSUM SQ=0DO 101I=1,9999999IF(SUM SQ.GT.1000)GOTO109SUM SQ=SUM SQ+I**2101CONTINUE109CONTINUE END
1958: Algol
Алгол је први пут формализован у извештају Algol58.
1960: COBOL
COBOL је формализован крајем 1959 год. И имао је много елаборација. Користи PERFORM реч која има много опција, уз касније додавање „саставних“ изјава као што су END-PERFORM. Игнорисањем потребе за декларисањем и иницијализацијом променљиве, еквивалентно са for петљом ће бити:
Обратите пажњу да маркер краја петље наводи име индекса променљиве, која мора да одговара имену индекса променљиве на почетку for петље. Неки језици (PL/I, FORTRAN 95 и касније) омогућавају ознаку изјаве на почетку for петље тако да може бити ухваћена од стране компајлера у односу на исти текст на одговарајућој изјави end. Фортран такође омогућава EXIT и CYCLE изјаве да би означили име овог текста; у гнезду петље ово чисти петљу која је намењена. Међутим, на овим језицима етикете морају да буду јединствене, тако узастопне петље које укључују исти индекс променљиве не могу да користе исти текст, нити може етикета бити иста као име променљиве, као што је индекс променљиве у for петљи.
1964: PL/I
do broj = 1 to 5 by 1; /* "by 1" је подразумевано ако ништа није наведено */
/*изјаве*/;
end;
Изјава LEAVE може да се користи за излазак из петље. Петља може бити означена, и leave ће можда оставити посебну петљу у групи гнезда петљи. Неки PL/I дијалекти укључују изјаву ITERATE да прекине тренутну итерацију петље и да почне следећа.
1968: Algol 68
Алгол68 има оно што је сматрано универзалном петљом, пуна синтакса је:
FOR i FROM 1 BY 2 TO 3 WHILE i≠4 DO ~ OD
Даље, један опсег понављања може бити замењен листом таквих опсега. Постоји неколико необичних аспеката конструкције.
само "do ~ od" део је обавезан, у овом случају петља ће се понављати унедоглед.
тако ће се део "to 100 do ~ od" поновити тачно 100 пута.
елемент "while" ће дозволити програмеру да прекине for петљу раније, као у:
INT sum sq := 0;
FOR i
WHILE
print(("Do sada:", i, new line)); # Уведено за сврху праћења. #
sum sq ≠ 70↑2 # Ово је тест за WHILE #
DO
sum sq +:= i↑2
OD
1970:Pascal
forBroj:=1to5do(*изјава*);
Опадање (рачунајући уназад) користи „downto“ кључну реч уместо „to“, као у:
//Коришћење for петљи за додавање бројева 1 - 5intsum=0;for(inti=1;i<6;++i){sum+=i;}
1972: Smalltalk
1to:5do: [ :broj|"изјаве" ]
За разлику од других језика, у Smalltalk-у for петља није језичка конструкција, али је дефинисана у класи Број као метод са два параметра, на крају вредности и затварања, користећи себе као почетну вредност.
1980: Ada
forBrojin1..5loop-- изјавеendloop;
Изјава exit може да се користи за излазак из петље. Петље могу бити означене, а излаз може оставити посебно означену петљу у групу угнежђених петљи:
Maple има два облика for петљи, један за понављање опсега вредности, а други за понављања садржаја контејнера. Вредност опсега је следећи:
forifromfbybtotwhilewdo# тело петљеod;
Сви делови осим do и od су опциони. "Fori" део, ако је присутан, мора бити први. Преостали део ("fromf", "byb", "tot", "whilew") може да се појави у било ком редоследу.
Итеративно преко посуде врши се користећи овај облик петље:
foreincwhilewdo# тело петљеod;
"Inc" део прецизира контејнер, који може бити листа, скуп, збир, производ, функција, низ, или објекат спровођење итератор.
For петља може се раскинути са od, end, или end do.
1982: Maxima CAS
У Maxima CAS-у могу се користити и не целобројне вредности:
forx:0.5step0.1thru0.9do/*"Ради нешто са x"*/
1982: PostScript
For петља, написана као [почетна] [прираст] [лимит] {...}for започиње са унутрашњом променљивом, и извршава тело док унутрашња променљива није виша од лимита (или не мања, ако је негативан прираштај ) и, на крају сваке итерације, повећава унутрашњу променљиву. Пре сваког понављања, вредност унутрашње променљиве је пребачена у стек.[4]
116{ИЗЈАВЕ}for
Ту је такође и проста repeat петља. Repeat петља, написана са Х { ... } repeat понавља тело тачно Х пута.[5]
for($broj=1;$broj<=5;$broj++){# садашње или претходно дефинисане променљиве# изјаве;}for(my$broj=1;$broj<=5;$broj++){# променљиве из петље# изјаве;}for(1..5){# променљиве имплицитно назване $_; 1..5 стварају листе од 5 елемената# изјаве;}изјаваfor1..5;# готово иста (само 1 изјава) са природним низомformy$broj(1..5){# променљиве из петље# изјаве;}
1988: Mathematica
Конструкција for петље која одговара већини других језика у Mathematica се назива Do.
Do[f[x],{x,0,1,0.1}]
Mathematica такође има For конструкцију који имитира for петљу С језика.
For[x=0,x<=1,x+=0.1,f[x]]
1989: Bash
# прва формаforiin12345do# мора имати најмање једну команду у петљиecho$i# само штампа вредност idone
# друга формаfor((i=1;i<=5;i++))do# мора имати најмање једну команду у петљиecho$i# само штампа вредност idone
Имајте на уму да се празна петља (тј једна без команди између do и done)третира као синтаксна грешка. Ако изнад петље садржи само коментаре, извршење ће резултирати поруком "синтаксна грешка код неочекиваног знака 'Done'".
1990: Haskell
Уграђени императив forM_ мапира израз у листу, као
forM_[1..5]$\indx->doизјаве
или да сваким новим издањем резултат буде као у листи
forLoopM_(0::Int)(<len)(+1)$\indx->do-- било шта са индексом
1991: Oberon-2, Oberon-07, or Component Pascal
FORBroj:=1TO5DO(* изјава *)END
Имајте на уму да је у оригиналном језику Oberon for петља изостављена у корист генералног конструкта Oberon петље. For петљa је поново уведена у Oberon 2.
1991: Python
forbrojinrange(1,6):# опсег (1, 6) даје вредност од 1 до 5 (али не 6)# изјаве
1993: AppleScript
repeatwithifrom1to5-- изјавеlogiendrepeat
Такође можете проћи кроз листу ставки, слично ономе што можете да урадите са низовима y другим језицима:
Такође можете користити "exit repeat" да изађете из петље у било ком тренутку. За разлику од других језика, AppleScript тренутно нема никакву наредбу да настави до следеће наредбе у петљи.
1993: Lua
fori=почетак,крај,интервалdo-- изјавеend
Дакле, овај код
fori=1,5,2doprint(i)end
ће исписати:
135
For петље могу такође да иду кроз табелу коришћењем
for(inti=0;i<5;i++){//обавља функције у оквиру петље;//може користити изјаву 'break;' да брзо изађе из петље//може користити изјаву 'continue;' да прескочи тренутни корак }
Имплементација у Интерпретираним програмским језицима
У интерпретираним програмским језицима, for петље могу бити реализоване на више начина. Често су for петље директно преведене на асемблер као упоређујућа упутства и упутства условних скокова. Међутим, то није увек тако. У неким тумачима програмских језика, for петље су само преведене на while петље.[7] На пример, узмите следећи Mint/Horchata код:
for i = 0; i < 100; i++
print i
end
за сваку ставку секвенце
штампај ставку
крај
/* 'Преведена традиционална for петља' */
i = 0
while i < 100
print i
i++
end
/* 'Преведена for each петља' */
SYSTEM_VAR_0000 = 0
while SYSTEM_VAR_0000 < sekvenca.length()
stavka = sekvenca[SYSTEM_VAR_0000]
print stavka
SYSTEM_VAR_0000++
end