while жана for циклдери
while жана for циклдери
Сценарийлерди жазып жатканда, бир эле иш-аракетти көп жолу жасоо милдети пайда болот.
Мисалы, тизмедеги өнүмдөрдү бир-бирден көрсөтүү. Же 1ден 10го чейинки бардык сандарды кайталаңыз жана ар бири үчүн бирдей кодду аткарыңыз.
Коддун бир бөлүгүн бир нече жолу кайталоо үчүн циклдер берилет.
for…of жана for… циклдеринде
Алдыңкы окурмандар үчүн чакан кулактандыруу.
Бул макалада негизги циклдер гана камтылган: while, do..while, жана for(..;..;..).
Эгер сиз бул макалага циклдердин башка түрлөрүн издеп келген болсоңуз, бул жерде көрсөткүчтөр:
Объекттин касиеттери боюнча итерациялоо үчүн… in караңыз.
Массивдердин жана кайталануучулардын үстүнөн итерациялоо үчүн...of жана Iterables караңыз.
Болбосо, окууну улантыңыз.
while цикли
while цикли төмөнкү синтаксиске ээ:
@A@
ал эми (шарт) {
// код
// ошондой эле "укурук денеси" деп аталат
} @A@
Циклдин денесиндеги код шарттын шарты чын болгондо аткарылат.
Мисалы, төмөнкү цикл i < 3 болгондо i чыгарат:
@A@i = 0 болсун;
while (i < 3) { // 0 анан 1 анан 2 чыгарат
эскертүү(i);
i++;
}@A@
Циклдин денесинин бир аткарылышы илимий жактан итерация деп аталат. Жогорудагы мисалдагы цикл үч кайталоону түзөт.
Эгерде i++ сызыгы жогорудагы мисалда жок болсо, анда цикл (теорияда) түбөлүккө кайталанмак. Иш жүзүндө, албетте, браузер буга жол бербейт, ал колдонуучуга “жабышып калган” скриптти токтотууга мүмкүнчүлүк берет, ал эми сервер тараптагы JavaScript процессти “өлтүрүшү” керек болот.
Ар кандай туюнтма же өзгөрмө жөн гана салыштыруу эмес, цикл шарты болушу мүмкүн: while шарты бааланат жана логикалык мааниге айландырылат.Мисалы, while (i) while (i != 0) сөзүнүн кыскараак версиясы:
@A@let i = 3;
while (i) { // i 0гө барабар болгондо, шарт жалган болуп калат жана цикл токтойт
эскертүү(i);
i--;
}@A@
Тармал кашаалар бир сызык укурук корпусу үчүн талап кылынбайт
Эгерде циклдин негизги бөлүгү бир гана билдирүүдөн турса, анда биз тармал кашааларды калтырып койсок болот {...}:
@A@let i = 3;
while (i) alert(i--);
"do...while" цикли
Шарт тести циклдин астына атайын do..while синтаксисин колдонуу менен жайгаштырылышы мүмкүн:
кыл {
// цикл денеси
} while (шарт);@A@
Цикл алгач денени аткарат, андан кийин шарттын шартын текшерет жана анын мааниси чын болсо, ал кайра-кайра аткарылат.
Мисалы:
@A@i = 0 //болсун;
кыл {
эскертүү(i);
i++;
} while (i < 3);@A@
Синтаксистин бул формасы, эгер шарт жалган болсо да, циклдин негизги бөлүгү жок дегенде бир жолу аткарылышын кааласаңыз, акталат. Практикада шарты бар форма көбүрөөк колдонулат: while(...) {...}.
"үчүн" цикли
Татаалыраак, бирок ошол эле учурда эң кеңири таралган цикл for цикли.
Бул төмөнкүдөй көрүнөт:
үчүн (баштоо; шарт; кадам) {
// ... цикл денеси ...
}
Келгиле, ар бир бөлүк бир мисал менен эмнени билдирерин түшүнүп көрөлү. Төмөнкү цикл i үчүн 0дөн 3кө чейин (бирок анын ичинде эмес) эскертүү (i) аткарат:
for (let i = 0; i < 3; i++) { // 0, андан кийин 1, анан 2 басып чыгарат
эскертүү(i);
}
Конструкцияны кененирээк карап көрүңүз:
Part
start let i = 0 Циклге киргенде бир жолу аткарылат
шарт i < 3 Ар бир цикл итерациясынын алдында текшерилет. Эгерде ал "false" деп баа берсе, цикл токтойт.
body alert(i) Шарт чын деп бааланганда кайра-кайра аткарылат.
i++ кадам Шарт текшерилгенге чейин ар бир итерацияда циклдин корпусунан кийин аткарылат.Жалпысынан алганда, цикл алгоритми төмөнкүдөй көрүнөт:
Баштоо
→ (эгерде шарт == чын болсо → Run body, Run step)
→ (эгерде шарт == чын болсо → Run body, Run step)
→ (эгерде шарт == чын болсо → Run body, Run step)
→ ...
Башкача айтканда, башталышы бир жолу аткарылат, андан кийин ар бир итерация шартты текшерүү болуп саналат, андан кийин дене жана кадам аткарылат.
Эгерде циклдер темасы сиз үчүн жаңы болсо, жогорудагы мисалга кайрылып, аны кагаз бетине этап-этабы менен кайра чыгаруу пайдалуу болушу мүмкүн.
Бул жерде биздин учурда эмне болот:
// үчүн (i = 0; i < 3; i++) эскертүү(i)
// Баштоо
i = 0 болсун;
// Эгерде шарт == true → Денени аткаруу, кадамды аткаруу
if (i < 3) { alert(i); i++}
// Эгерде шарт == true → Денени аткаруу, кадамды аткаруу
if (i < 3) { alert(i); i++}
// Эгерде шарт == true → Денени аткаруу, кадамды аткаруу
if (i < 3) { alert(i); i++}
// ...аяктоо, анткени азыр i == 3
Inline Variable Declaration
Мисалда i эсептегич өзгөрмө циклдин ичинде жарыяланды. Бул "саптык" өзгөрмө декларациясы. Мындай өзгөрмөлөр циклдин ичинде гана бар.
үчүн (i = 0; i < 3; i++) {
эскертүү(i); // 0, 1, 2
}
эскертүү(i); // ката, мындай өзгөрмө жок
Жаңы өзгөрмө жарыялоонун ордуна, биз учурдагыны колдоно алабыз:
let i = 0 болсун;
for (i = 0; i < 3; i++) { // болгон өзгөрмөнү колдонуңуз
alert(i); // 0, 1, 2
}
alert(i); // 3, өзгөрмө жеткиликтүү, анткени циклден тышкары жарыяланды
"үчүн" бөлүктөрүн өткөрүп жиберүү
for'дун кандайдыр бир бөлүгүн өткөрүп жиберсе болот.
Мисалы, циклди баштоодон мурун эч нерсе кылуунун кереги жок болсо, башталгычты өткөрүп жиберсек болот.
Бул сыяктуу:
i = 0 болсун; // биз буга чейин мен жарыялаган жана маани бергенбиз
for (; i < 3; i++) { // "башталышынын" кереги жок
alert(i); // 0, 1, 2
}
Сиз ошондой эле кадамды алып салсаңыз болот:
i = 0 болсун;
үчүн (; i < 3;) {
alert(i++);
}
Бул циклди while (i <3) менен окшош кылат.
Же сиз чексиз циклди алып, баарын толугу менен алып салсаңыз болот:
үчүн(;;) {
// түбөлүккө иштейт
}
Бул учурда, чекиттүү үтүрлөрдүн өздөрү; болушу керек, болбосо синтаксистик ката болот.
Цикл үзүлүшү: "үзүү"
Цикл адатта шарт жалган деп бааланганда токтотулат.
Бирок биз циклден каалаган убакта атайын break директивасы менен чыга алабыз.
Мисалы, төмөнкү код кирген сандардын суммасын зыяратчы киргизгенге чейин эсептеп, андан кийин чыгарат:
сумма = 0 болсун;
ал эми (чын) {
let value = +prompt("Номерди киргизиңиз", '');
if (!value) break; // (*)
сумма += маани;
}
alert( 'Summ: ' + sum );
(*) саптагы break директивасы циклдин аткарылышын толугу менен токтотот жана башкарууну анын корпусунан кийинки сапка өткөрүп берет, башкача айтканда, эскертүү.
Жалпысынан алганда, "чексиз цикл + үзгүлтүк" айкалышы үзгүлтүккө учурашы керек болгон шарт циклдин башында же аягында эмес, ортодо же анын денесинин бир нече жеринде болгон жагдайлар үчүн эң сонун нерсе.Кийинки итерацияга өтүү: улантуу
Continue директивасы үзүндүнүн "жеңил версиясы" болуп саналат. Ал аткарылганда цикл үзүлбөйт, бирок кийинки итерацияга өтөт (эгерде шарт дагы эле туура болсо).
Бул циклдин учурдагы итерациясында башка эч нерсе жок экени анык болсо колдонулат.
Мисалы, төмөнкү цикл так гана маанилерди чыгарууну улантат:
үчүн (i = 0; i < 10; i++) {
// эгер чын болсо, циклдин калган бөлүгүн өткөрүп жибериңиз
эгерде (i % 2 == 0) улантуу;
эскертүү(i); // 1 анан 3, 5, 7, 9
}
iнин жуп маанилери үчүн улантуу директивасы циклдин корпусунун аткарылышын токтотот жана башкарууну итерация үчүн кийинкисине өткөрүп берет (кийинки сан менен). Ошентип, эскертүү так маанилер үчүн гана чакырылат.
улантуу директивасы уядан сактайт
Так баалуулуктарды гана иштеткен цикл төмөнкүдөй болушу мүмкүн:
үчүн (i = 0; i < 10; i++) {
эгерде (i % 2) {
эскертүү(i);
}
}
Техникалык жактан алганда, ал толугу менен окшош. Чынында эле, улантуунун ордуна, сиз жөн гана иш-аракеттерди if блогуна ороп койсоңуз болот.
Бирок, биз тармал кашаа уясынын кошумча деңгээлин алдык. If ичиндеги код узунураак болсо, анда бул улантуу опциясынан айырмаланып окулууну начарлатат.
Сиз “?” операторунун оң жагында үзгүлтүккө/улантууга колдоно албайсыз
Бул синтаксис конструкциялары туюнтма эмес экенин жана үчтүк оператор менен колдонулушу мүмкүн эмес экенин эске алыңыз ?. Атап айтканда, үзүү/улантуу сыяктуу директиваларды колдонуу катаны жаратат.Мисалы, бул кодду алсак:
эгерде (i > 5) {
эскертүү(i);
} башка {
улантуу;
}
…жана суроо белгисин колдонуп кайра жазыңыз:
(i > 5) ? alert(i): улантуу; // улантуу бул жерде катага алып келет
...бул синтаксистик ката болот.
Бул суроо белгиси операторун колдонбоо үчүн дагы бир себеппи? эгерде ордуна.
Тыныгуу/улантуу үчүн энбелгилер
Бир эле учурда циклдин бир нече деңгээлинен чыгуу керек болот.
Мисалы, төмөндөгү коддо биз i жана j аркылуу цикл жасайбыз, координаттарды (i, j) (0,0) баштап (2,2) сурайбыз:
үчүн (i = 0; i < 3; i++) {
үчүн (j = 0 болсун; j < 3; j++) {
let input = prompt(`Координаттардагы маани (${i},${j})`, '');
// Бул жерден Done (төмөндө) баскычына өтүүнү кааласакчы?
}
}
alert('Бүттү!');
Колдонуучу киргизүүнү жокко чыгарса, бизге аткарууну токтотуунун жолу керек.
Киргизүүдөн кийинки кадимки тыныгуу ички циклди гана бузат, бирок бул жетишсиз. Сиз энбелгилерди колдонуу менен каалаган жүрүм-турумга жетише аласыз.
Энбелги идентификатордун формасына ээ, андан кийин циклден мурун кош чекит коюлат:
labelName: үчүн (...) {
...
}
Төмөнкү циклде <labelName> сындыруу чакырыгы ошол энбелгиси бар эң жакын тышкы циклди издеп, анын аягына чейин секирип кетет.
тышкы: үчүн (i = 0 болсун; i < 3; i++) {
үчүн (j = 0 болсун; j < 3; j++) {
let input = prompt(`Координаттардагы маани (${i},${j})`, '');
// эгерде бош сап же Жокко чыгаруу болсо, эки циклден да чыкыңыз
if (!input) break outer; // (*)
// баалуулуктар менен бир нерсе кылуу ...
}
}
alert('Бүттү!');
Жогорудагы мисалда, бул break outer деп чакыруу сырткы циклди outer деп аталган энбелгиге чейин үзөт дегенди билдирет.
Ошентип, башкаруу (*) менен белгиленген сызыктан эскертүүгө ('Бүттү!') секирет.
Сиз белгини өзүнчө сапка жайгаштырсаңыз болот:
сырткы:
үчүн (i = 0; i < 3; i++) { ... }
улантуу директивасын энбелги менен да колдонсо болот. Бул учурда, башкаруу энбелгиси бар циклдин кийинки итерациясына өтөт.
Тегдер эч жакка "секирүүгө" жол бербейт
Энбелгилер башкарууну коддун каалаган жерине өткөрүп берүүнү мүмкүн эмес кылат.
Мисалы, төмөндөгүлөрдү жасоонун эч кандай жолу жок:
белгини бузуу; // төмөнкү белгиге секирбеңиз
энбелгиси: үчүн(...)
Тыныгуу директивасы код блогунун ичинде болушу керек. Техникалык жактан алганда, коддун кандайдыр бир белгиленген блогу, мисалы:
энбелгиси: {
// ...
белгини бузуу; // иштейт
// ...
}
…Бирок 99,9% учурларда break циклдердин ичинде колдонулат, муну биз жогорудагы мисалдардан көрдүк.
Баса, улантуу циклдин ичинде гана мүмкүн.
Бардыгы
Биз циклдердин 3 түрүн карап чыктык:
while - Ар бир итерация алдындагы шартты текшерет.
do..while - Ар бир итерациядан кийин шартты текшерет.
үчүн (;;) - Ар бир итерация алдында шартты текшерет, кошумча орнотууларды коюуга болот.
Чексиз циклди уюштуруу үчүн while (true) конструкциясын колдонуңуз. Ошол эле учурда, башка цикл сыяктуу эле, ал үзгүлтүккө учуратуу директивасы менен үзгүлтүккө учурашы мүмкүн.
Эгерде циклдин бул итерациясында дагы эч нерсе кылуунун кереги жок болсо, бирок цикл толугу менен токтотулбашы керек болсо, улантуу директивасы колдонулат.
Бул эки директивалар циклдин алдына коюлган энбелгилерди колдойт.Энбелгилер үзүлүү/улантуу учурдагы циклдин чегинен чыгуунун, сырткы циклдин аткарылышына таасир этүүнүн жалгыз жолу.
Белгилеп кетсек, энбелгилер коддун каалаган жерине өтүүгө жол бербейт, JavaScriptте мындай мүмкүнчүлүк жок.
Tasks
Акыркы циклдин мааниси
маанилүүлүгү: 3
Бул код чыгара турган акыркы маани кандай? Неге?
@A@let i = 3;
ал эми (i) {
alert(i--);
}@A@
чечим
while цикли кандай маанилерди чыгарат?
маанилүүлүгү: 4
Ар бир цикл үчүн ал кандай маанилерди чыгара турганын жазыңыз. Андан кийин жооп менен салыштырыңыз.
Эки цикл тең бирдей маанилер менен сигнал чыгарабы же жокпу?
++i префикс варианты:
i = 0 болсун;
while (++i < 5) alert( i );
i++ постфикс версиясы
i = 0 болсун;
while (i++ < 5) alert( i );
чечим
for цикли кандай маанилерди чыгарат?
маанилүүлүгү: 4
Ар бир цикл үчүн ал кандай маанилерди чыгара турганын жазыңыз. Андан кийин жооп менен салыштырыңыз.
Эки цикл тең бирдей маанилер менен сигнал береби же жокпу?
Postfix формасы:
for ( let i = 0; i < 5; i++) alert( i );
Префикс формасы:
for (i = 0; i < 5; ++i) alert( i );
чечим
жуп сандарды басып чыгаруу
маанилүүлүгү: 5
2ден 10го чейинки жуп сандарды чыгаруу үчүн for циклин колдонуңуз.
Демо иштетүү
чечим
Убакыт менен алмаштырыңыз
маанилүүлүгү: 5
Циклдин жүрүм-турумун өзгөртпөстөн, for циклин бир аз убакытка алмаштыруу үчүн кодду кайра жазыңыз.
үчүн (i = 0; i < 3; i++) {
alert( `${i} саны!` );
}
чечим
Киргизүү жараксыз болгонго чейин цикл
маанилүүлүгү: 5
Колдонуучуну 100дөн чоң санды киргизүүгө үндөгөн циклди жазыңыз. Эгерде конок башка санды киргизсе, аны кайра киргизүүнү сураныңыз ж.б.
Конок 100дөн чоң санды киргизмейинче же Жокко чыгаруу (ESC) баскычын басмайынча цикл номерди сурашы керек.Келген киши сандарды гана киргизиши күтүлүүдө. Бул тапшырмада сандык эмес саптарды иштетүүнү камсыз кылуу зарыл эмес.
Демо иштетүү
чечим
жөнөкөй сандарды басып чыгаруу
маанилүүлүгү: 3
1ден чоң натурал сан, эгерде ал өзүнөн жана 1ден башка эч нерсеге бөлүнбөсө, жай сан деп аталат.
Башка сөз менен айтканда, n > 1 жай болот, эгерде 1 жана n санынан башка каалаган санга бөлгөндө, калдык бар.
Мисалы, 5 жай сан жана аны 2, 3 же 4кө калдыксыз бөлүүгө болбойт.
2ден nге чейинки бардык жай сандарды басып чыгарган кодду жазыңыз.
n = 10 үчүн натыйжа 2,3,5,7 болушу керек.
P.S. Код дагы башка интервалдар үчүн оңой өзгөртүлүшү керек.