Hoolimata sellest, et jutt on ühe algteema ümber, on see artikkel kirjutatud kogenud spetsialistidele. Eesmärk on näidata, millised eksimused esinevad algajate seas programmeerimises. Praktiseerivatele arendajatele on need probleemid juba ammu lahendatud, unustatud või isegi märkamata jäävad. Artikkel võib osutuda kasulikuks, kui peaksid kellegi teisega selle teema osas aitama. Artiklis tehakse paralleele erinevate programmeerimisraamatute, autoriteks Shildt, Stroustrup, Okulov, materjalidega.
Tsüklite teema on valitud, kuna selle tõttu jääb programmeerimise õppimise käigus kõrvale päris palju inimesi.
See meetod on suunatud nõrkadele üliõpilastele. Üldiselt ei jää tugevad selle teema juurde ja neile ei pea eriti meetodeid välja mõtlema. Artikli teiseks eesmärgiks on viia see meetod klassist "toimib kõigis üliõpilastes, kuid vaid ühe õpetaja juures" klassi "toimib kõigis üliõpilastes, kõikide õpetajate juures". Absoluutseid originaalsuse ambitsioone mul ei ole. Kui sa juba kasutad sarnast meetodit selle teema õpetamiseks, palun kirjuta, millega sinu variant erineb. Kui otsustad seda rakendada, jaga palun tulemusi, kuidas kõik sujus. Kui sarnane meetod on mõnes raamatus kirjas, palun too välja pealkiri.
Seda meetodit olen arendanud 4 aastat, tehes individuaalset tööd eri tasemega üliõpilastega. Kokku umbes viiskümmend üliõpilast ja kaks tuhat tundi tunde. Alguses takerdusid üliõpilased selle teema juurde lõputult ja lahkusid. Iga üliõpilase järel kohandati meetodit ja materjale. Viimase aasta jooksul ei jää üliõpilased enam selle teema juurde kinni, nii et otsustasin oma kogemusi jagada.
Miks nii palju tähti? Tsüklid on ju elementaarsed!
Nagu ma juba varem mainisin, võib praktiseerivatele arendajatele ja tugevatele üliõpilastele tsüklite kontseptsiooni keerukust alahinnata. Näiteks võib pidada pikka loengut, näha noogutavaid peade ja nutikaid silmi. Kuid proovides lahendada mingit ülesannet, tekib ummik ja seletamatud probleemid. Pärast loengut on üliõpilastel kindlasti ainult osaline arusaam. Ootus süveneb seisukorraga, et üliõpilased ei oska ise välja tuua, milles täpselt nende eksimus seisneb.
Ühel päeval taipasin, et üliõpilased käsitlevad minu näiteid kui hierogüüfe. St kui jagamatuid tekstikilde, kuhu tuleb lisada mingi "maagiline" täht ja kõik töötab.
Mõnikord märkasin, et üliõpilased arvavad, et konkreetse ülesande lahendamiseks on vajalik mingi teine konstruction, millest ma veel rääkinud pole. Kuigi lahendamiseks oli vaja vaid natuke näidet kohandada.
Seepärast jõudsin ideeni, et peamine tähelepanu tuleks pöörata mitte avaldise süntaksile, vaid mõttele refaktoreerida korduvat koodi silmustega. Kui õpilased omandavad selle idee, siis iga süntaks tuleb väikeste harjutuste abil omandatuks.
Kellele ja milleks ma õpetan
Kuna sisseastumiseksameid ei ole, võivad tundides olla nii tugevad kui ka väga nõrgad tudengid. Rohkem minu üliõpilaste kohta saab lugeda artiklist
Püüdsin, et programmeerimist õpiksid kõik, kes seda soovivad.
Minu tunnid toimuvad individuaalselt ja üliõpilane maksab iga tunni eest. Tundub, et üliõpilased peaksid kulusid optimeerima ja nõudma minimaalseid nõudmisi. Siiski käivad inimesed kontaktõppes elava õpetajaga mitte teadmiste, vaid kindluse nimel, et nad on midagi õppinud, progressitunde ja eksperdi (õpetaja) heakskiidu pärast. Kui üliõpilased ei tunne oma õpingutes progressi, lahkuvad nad. Üldiselt on võimalik tunde struktureerida nii, et üliõpilased tunneksid progressi tuttavate konstruktsioonide arvu suurenemises. Esiteks uurime põhjalikult while-silmust, seejärel uurime for-silmust, siis do while ja meil on valmis kursus tuhat ja üks ööd, kus kahes kuus uuritakse ainult silmuseid ja lõpus on üliõpilane, kes dikteerides kirjutas standardteegi. Siiski, et lahendada praktilisi ülesandeid, on vajalik mitte ainult materjali tundmine, vaid ka iseseisvus selle rakendamisel ja uue teabe otsimisel. Seetõttu pean kontaktkursuste jaoks õigeks põhimõtte, et õpetada miinimum ja julgustada iseseisvat teema ja sellega seotud aiatöö õppimist. Silmuste teema puhul pean miinimumiks konstruktsiooni while. Selle abil saab arusaama põhimõttest. Tunnes põhimõtet saab omandada ka for ja do-while ise.
Materjali omandamine nõrkade üliõpilaste poolt ei piirdu ainult süntaksiga. Tuleb anda rohkem lihtsaid, kuid mitmekesiseid ülesandeid ja tuua näiteid põhjalikumalt. Lõppude lõpuks piirab omandamise kiirus üliõpilase võimet väljendeid muuta ja mustreid otsida. Arvestades nutikaid üliõpilasi, on enamik ülesandeid igavad. Nende õpetamise ajal ei tasu nõuda 100% ülesannete lahendamist. Minu materjali saab vaadata . Tõsi, repositoorium sarnaneb rohkem musta maagia grimuarile — keegi peale minu ei saa aru, kus miski asub, ja kui kontrolli läbi kukkuda, võib hulluks minna.
Metoodika on suunatud praktikale.
Teooriat selgitatakse probleemi lahendamise näitena. Programmeerimise aluste tundides, kus õppitakse harunemisi ja tsükleid, ei õnnestu lihtsalt veeta kasulikku loengut ühe teema kohta terve tunni. 15-20 minutit piisab, et mõisted selgeks teha. Peamised raskused tekivad praktiliste ülesannete täitmisel.
Algajad õpetajad võivad esitada operaatorid, harunemised, tsüklid ja massiivid ühe loengu jooksul. Ent nende üliõpilased seisavad silmitsi selle teabe omandamise probleemiga.
Oluline on mitte ainult materjali rääkida, vaid ka veenduda, et kuulejad on sellest aru saanud.
Teema omandamine määratakse kindlaks selle järgi, kuidas üliõpilane iseseisva tööga hakkama saab.
Kui üliõpilane suudab teemat käsitleva ülesande iseseisvalt lahendada, tähendab see, et teema on omandatud. Iga ülesande puhul on soovitatav kirjeldada teststsenaariumide tabelit. Ülesannetel on selgelt määratletud järjekord. Ülesandeid ei ole soovitatav vahele jätta. Kui praegune ülesanne on liiga keeruline, on järgmise peale üleminek mõttetu. See on veel keerulisem. Et üliõpilane saaks hakkama praeguse keerulise ülesandega, selgitatakse talle mitu tehnikaid esimese ülesande näitel. Tegelikult koondub teema sisu raskuste ületamise tehnikatele. Tsüklid on pigem kõrvaltegemine.
Esimene ülesanne on alati näidistus. Teine erineb pisut ja tehakse 'iseseisvalt' kohe pärast esimest õpetaja järelevalve all. Kõik järgnevate ülesannete eesmärk on pöörata tähelepanu erinevatele pisiasjadele, mis võivad eksitusi tekitada.
Näide selgitab dialooge, kus õpilane peab rakendama tagasivoolu ja ristvalidatsiooni, et veenduda, et ta on materjali õppimisega hakkama saanud.
Olen banaalne ja ütlen, et esimene näide teema kohta on väga oluline. Kui on olemas materjali laialdaseks iseseisvaks tööks, saab esimest näidet hiljem parandada. Kui lisaks näitele ei ole midagi muud, ei pruugi õpilane teemat omandada.
While või for?
Üks vaieldav küsimus on konstruktsiooni valik näite jaoks: while või for. Üks kord veenis mind mu tuttav praktiseeriv arendaja, kellel ei olnud õpetamiskogemust, tund aega, et for-tsükkel on kõige lihtsam mõista. Tema argumendid piirdusid väitega, et ‘kõik on selge ja kohale paigutatud’. Siiski on algajate tõeliselt keeruliste probleemide põhjuseks tsükli idee, mitte selle kirjutamine. Kui inimene ei mõista seda ideed, siis on tal raske ka süntaksiga. Kui idee on mõistetud, kaovad koodivormi probleemid iseenesest.
Minu materjalides järgneb tsüklite teema haru võrdlemise teemale. if ja while väline sarnasus võimaldab teha otseülekande: ‘kui tingimus pealkirjas on tõene, siis täidetakse keha’. Tsükli eripära seisneb aga selles, et keha täidetakse mitmeid kordi.
Teine minu argument on, et while nõuab vähem vormistust kui for. Vähem vormistust tähendab vähem rumalaid vigu, nagu puuduvaid komasid ja sulge. Algajatel ei ole veel piisavalt tähelepanelikkust ja põhjalikkust, et automaatselt vältida süntaksivigu.
Kolmas argument on see, et paljudes heades raamatutes selgitatakse while konstruktsoone esimesena.
Kui õpilasel õnnestub kergesti rakendada väljendeid, siis võib for-st õhust rääkida. Õpilane valib ise, mis talle rohkem meeldib. Kui aga rakendamine on keeruline, siis on parem mitte hajutada tähelepanu. Las õpilane lahendab esmalt kõik while konstruktsiooni abil. Kui tsüklite teema on omandatud, võib lahendusi ümber kirjutada, et harjutada while'i muutmist for-iks.
Posttingimusega tsüklid on üsna haruldased. Ma ei raiska sellele aega üldse. Kui õpilane on mõistnud mustrite tuvastamise ideed ja väljendite muutmist, suudab ta ilma minu abita toimetada.
Esitluses esimesest näitest tugeva üliõpilaskonnaga rõhutan, et esimeses näites on oluline fikseerida mitte ainult lahendus, vaid ka kogu tegevuste ahel, mis tulemuse saavutamiseks viis. Laiskadel üliõpilastel võib olla kiusatus ignoreerida kirjutamist ja kanda endale ainult lõplik algoritm. Tuleb neid veenda, et ühel hetkel seisavad nad silmitsi keerulise ülesandega. Selle lahendamiseks tuleb järgida samme, nagu antud näites. Just seepärast on oluline fikseerida kõik etapid. Järgmistes ülesannetes võib jätta alles vaid lõpliku lahenduse variandi.
Automaatimise põhieesmärk on see, et me delegoime arvutile rutiinse töö tegemise inimese asemel. Üks põhilisi tehnikaid on tsüklite kirjutamine. Seda rakendatakse, kui programmis korduvad järjepidevalt sama laadi tegevused.
Selge on parem kui ebaselge
Esimeses tsüklite ülesandes võib tunduda hea mõte ekraanile kuvada mõni sama fraas korduvalt. Näiteks:
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Hurra, see töötab!
Selline variant on halb, kuna väljundis ei ole nähtav arvesti väärtus. See on probleem algajatele. Seda ei tohi alahinnata. Alguses oli see ülesanne esimene ja järjestikuste arvude väljundamise ülesanne teine. Tuli tutvustada täiendavaid termineid 'tsükkel N korda' ja 'tsükkel A-st B-ni', mis on sisuliselt sama. Liigsete üksuste vältimiseks otsustasin näidata ainult näidet järjestuse väljundist. Ainult vähestel õnnestub esmatähtsat ettevalmistust omamata hoida arvestit peas ja modelleerida programmi käitumist mõttes. Mõned üliõpilased puutuvad 'meeles modelleerimisega' esmakordselt kokku just tsüklite teemal.
Pärast teatavat praktikat annan ülesande korduva sama teksti iseseisvaks lahendamiseks. Kui alguses anda nähtav arvesti ja seejärel nähtamatu, tekib üliõpilastel vähem probleeme. Mõnikord piisab vihjest 'ärge printige arvestit ekraanile'.
Kuidas see teiste juures seletatakse?
Enamikus veebimaterjalides antakse tsükli süntaks "loengus". Näiteks developer.mozilla.org-is (hetkel) koos while-tsükliga kirjeldatakse veel mitmeid konstruktsioone. Samuti antakse lihtsalt konstruktsioonid mallide kujul. Nende käivitamise tulemust kirjeldatakse sõnadega, kuid illustratsioon puudub. Minu arvates vähendab selline teema esitamine nende materjalide kasulikkust nullini. Õpilane võib koodi ümber kirjutada ja ise selle käivitada, kuid viidatud näidis on ikkagi vajalik. Kuidas mõista, et näidis on õigesti ümber kirjutatud, kui pole millegi tulemusega võrrelda?
Kui antakse vaid mall, ilma näidiseta, siis õpilasel on veel raskem. Kuidas mõista, et koodifragmendid on mallis õigesti paigutatud? Võib-olla proovida kirjutada mingil viisil, ja siis käivitada. Kuid kui ei ole viidatud näidist tulemuse võrdlemiseks, siis käivitamine ei aita samuti.
C++ kursusel intuitis on tsükli süntaks peidetud loengu 4 kolmandale lehele teemal "operaatorid". Tsüklite süntaksit selgitatakse, pöörates erilist tähelepanu mõistele "operaator". Mõistet antakse faktide kogumina nagu "symbol; see on operaator", "{} on koosnevaid operaator", "tsükli keha peab olema operaator". Minu arvates ei meeldi selline lähenemine, kuna see peidab olulisi seoseid ühe termini taha. Algse programmikoodi analüüsimine sellisel tasemel on vajalik kompilaatoriarendajatele keele spetsifikatsiooni rakendamiseks, kuid mitte üliõpilastele esmase arusaamise korral. Algajad programmeerimises ei oma sageli piisavalt täpsust, et suudaksid selliseid termineid mõista. Harva õpib ja mõistab keegi uusi sõnu esimesel korral. Praktiliselt keegi ei suuda korralikult rakendada mõistet, mida ta just on õppinud. Seetõttu tekib tudengitel hulk vigu nagu "kirjutasin while(a<7);{, ja programm ei tööta."
Minu arvates on kõige parem alustada konstruktsiooni süntaksist kohe koos sulgudega. Ilma sulgudeta varianti tuleks selgitada ainult siis, kui õpilasel tekib konkreetne küsimus "miks siin pole sulgude ja see töötab".
Oкулов'in «Programmeerimise alused» 2012. aastast tutvustab tsüklite kasutamist for-malli kaudu, seejärel antakse soovitusi selle kasutamiseks ning kohe pärast seda algab eksperimentaalne osa. Ma arvan, et raamat kirjutati väga andekatele õpilastele, kes harva minu tundides osalevad.
Populaarsetes raamatutes kirjutatakse alati välja koodifragmendi tulemus. Näiteks Šildti «Java 8. Täielik juhend» 2015. aastast. Esiteks antakse mall, siis programmikood ja kohe pärast seda – selle käivitamise tulemus.
Näiteks vaatame while-tsüklit, kus toimub tagurpidi
loetelu alustades numbrist 10 ja trükitakse välja täpselt 10 «takti»://Продемонстрировать применение оператора цикла while class While { public static void main(String args []) { int n = 10; while (n > 0) { System.out.println("такт " + n); n--; } } }Käivitamisel prindib see programm kümme «takti» järgmises vormis:
takti 10
takti 9
takti 8
takti 7
takti 6
takti 5
takti 4
takti 3
takti 2
takti 1
Mallide, programmikoodide ja nende tulemuste kirjeldamise lähenemist kasutatakse ka raamatus «Javascript lastele» ja w3schools.com'i js kursusel. Veebilehe vorming lubab isegi teha sellest näitest interaktiivse.
Stroustrup'i raamatus «C++ põhimõtted ja praktika» 2016. aastast läks autor veelgi kaugemale. Esiteks selgitatakse, milline tulemus peaks olema, ja seejärel näidatakse programmikoodi. Kiidetakse, et näidetena ei ole kasutatud lihtsalt juhuslikku programmi, vaid antakse ajalooline ülevaade. See aitab tähelepanu juhtida: «Vaata, see ei ole lihtsalt kasutu tekst. Sa näed midagi olulist».
Iteratsiooni näiteks vaatame esimest programmi, mis on kirjutatud salvestatud programmi masinasse (EDSAC). See kirjutati David Wheeler'i poolt Cambridge'i ülikooli arvutilaboris 6. mail 1949. aastal. See programm arvutab välja ja printib lihtse ruutude nimekirja.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801
Siin on igas reas number, mille järel järgneb tabulatsioonimärk (‘t’) ja selle numbri ruut. Selle programmi versioon C++ keeles näeb välja selline://Вычисляем и распечатываем таблицу квадратов чисел 0-99 int main() { int i = 0; // Начинаем с нуля while(i < 100){ cout << i << 't' << square(i) << 'n'; ++i; } }
Huvitav on see, et selle raamatu süntaksimall ei ole kirjeldatud. Stroustrup juhendmaterjalis () rõhutab, et hindab oma õpilaste intelligentsust. Võib-olla peetakse oskust mallide äratundmiseks mitmest näitest sellise intelligentsuse väljenduseks.
Kuidas ma ise selgitan
Stroustrup'i lähenemine: kõigepealt tulemuse kirjeldus, seejärel probleemi lahendamine ja siis iseseisev analüüs, näib olevat kõige läbimõeldum. Seetõttu otsustasin selle aluseks võtta, kuid rääkida vähem ajaloolisest näitest – ülesandest, mis käsitleb "sisukorda". See loob tuntava märgise, et hiljem öelda "mäleta ülesannet sisukorra kohta" ja et tudengid mäletaksid just seda. Oma näites püüdsin hoiatada ka kahe kõige levinuma eksituse eest. Edasi kirjutan neist lähemalt.
Selle ülesande kaudu tutvume keeruliste probleemide lahendamise tehnikatega. Esmalt tuleb lahendus teha primitiivne ja lihtne. Seejärel saab mõelda, kuidas seda lahendust täiustada.
Sissejuhatus
Peatükk 1
Peatükk 2
Lühipeatükk 3
Lühipeatükk 4
Lühipeatükk 5
Lühipeatükk 6
Lühipeatükk 7
Kokkuvõte
Oma tähelepanekute põhjal viib lähenemine „mall-näide-tulemus“ erinevates kombinatsioonides ikkagi selleni, et tudengid tajuvad tsüklit nagu hieroglif. See väljendus selles, et nad ei mõistnud, miks on seal vaja kirjutada tingimus, kuidas valida i++ ja i- ning muid näiliselt ilmseid asju. Nende eksituste vältimiseks peaks lähenemine tsüklite selgitamisele rõhutama sama tegevuse kordamise tähendust ja alles seejärel – nende vormistamist konstruktsiooni abil. Seetõttu, enne kui anda tsükli süntaks, peab lahendama ülesande "otse". Ülesande primitiivne lahendus sisukorra kohta on järgmine:
Console.WriteLine("Sissejuhatus");
Console.WriteLine("Pä Kapitel 1");
Console.WriteLine("Pä Kapitel 2");
Console.WriteLine("Pä Kapitel 3");
Console.WriteLine("Pä Kapitel 4");
Console.WriteLine("Pä Kapitel 5");
Console.WriteLine("Pä Kapitel 6");
Console.WriteLine("Pä Kapitel 7");
Console.WriteLine("Kokkuvõte");
Kuidas seda saaks parandada?
Asendada ühesugused tegevused tsükliga.
Millised tegevused korduvad järjest ilma muutusteta?
Selles fragmentis selliseid ei ole. Kuigi käsud sõna "Lugu" koos numbriga on omavahel väga sarnased.
Seega on järgmine etapp fragmentide vahelise erinevuse leidmine. Ainult selles ülesandes on kõik selge, hiljem korduvad mitte üksikute käskude, vaid 5 või rohkem rida koodi plokid. Otsima peab mitte ainult käskude loendist, vaid ka haru- või tsükli konstruktsioonidest.
Näites on käskude vahe numbris sõna "Lugu" järel.
Nii kui erinevus on leitud, tuleb mõista muutuse seaduspära. Kas erinev fragment on number? Kas see suureneb või väheneb pidevalt? Kuidas muutub numbri väärtus kahe kõrvuti oleva käsu vahel?
Näites suureneb numbri "Peatükk" järel igaühe sammuga 1. Erinevus on leitud, mustreid on avastatud. Nüüd saab eristuva fragmendi asendada muutujaga.
Sellist muutujat tuleks deklareerida enne esimest korduvat fragmenti. Seda muutujat nimetatakse tavaliselt I või j, või mõne muu pikema nimega. Selle algväärtus peaks olema võrdne ekraanile väljatrükitava esimese väärtusega. Näites on esimene väärtus 1.
Millist algväärtust tuleks võtta arvude seeria "100, 101, 102, 103, 104, 105" kuvamiseks?
Selles seerias on esimene number 100.
Pärast iga väljundikäsu peab selle muutuva väärtust suurendama 1 võrra. See ühik on muutmise samm.
Mis samm on arvude seeria "100, 102, 104, 106" puhul?
Selles seerias on samm 2.
Pärast eristuva fragmendi asendamist muutujaga näeb kood välja järgmine:
Console.WriteLine("Sissejuhatus");
int i;
i = 0;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Kokkuvõte");
Pärast meetodi "mustri väljendamine muutujaga" rakendamist sisaldab kood mitmeid rühmi identsest toimingutest, mis järgnevad üksteisele. Nüüd saab korduvad toimingud asendada tsükliga.
Probleemi lahendamise järjestus, kus tuleb kasutada tsükleid, koosneb etappidest:
- Lahendada "lamades" hulga eraldi käskudega
- Leida muster
- Väljendada mustrit muutujaga
- Kujundada tsüklina
Edasi tutvustatakse uusi termineid, et üliõpilane ei jääks olukorda "kõike mõistan, aga ei oska öelda":
— loendur — alati muutuja, mis on vajalik tsükli sammude arvu jälgimiseks. Üldjuhul täisarv, mida võrreldakse piiranguga.
— loenduri samm — loenduri muutumise mustri kirjeldus.
— piirang — number või muutuja, millega loendurit võrreldakse, et algoritm oleks lõplik. Loenduri väärtus muutub nii, et see läheneb piirangule.
— tsükli keha — käskude kogum, mida korratakse. Kui öeldakse "käsk kirjutatud tsükli sisse", siis mõeldakse just keha.
— tsükli iteratsioon — tsükli keha üksik täitmine.
— tsükli tingimus — loogiline väljend, millest sõltub, kas järgmine iteratsioon toimub. (Siin võib olla segadust harutimise konstruktsioonidega)
Oluline on olla valmis selleks, et esialgu kasutavad õpilased termineid valesti. See kehtib nii tugevate kui ka nõrkade kohta. Ühise keele loomine on üks tervet kunstivormi. Kirjutan nüüd lühidalt: tuleb seada ülesanne "toota koodifragmendi <termin>" ja kasutada neid termineid vestluses õigesti.
Pärast transformatsiooni tsükliga saadakse fragment:
Console.WriteLine("Sissejuhatus");
int i = 0;
while (i < 7) {
Console.WriteLine("Pealkiri " + i);
i = i + 1;
}
Console.WriteLine("Kokkuvõte");Peamine eksimus
Üks populaarsemaid eksimusi õpilaste seas on see, et nad panevad tsükli konstruktsiooni sisse sellised tegevused, mida tuleb teha vaid üks kord. Näiteks nii:
;
int i = 0;
while (i < 7) {
Console.WriteLine("Sissejuhatus")
Console.WriteLine("Pealkiri " + i);
i = i + 1;
Console.WriteLine("Kokkuvõte");
}
Õpilased puutuvad selle probleemiga pidevalt kokku, nii alguses kui ka keerulisemates ülesannetes.
Kuninglik vihje sel juhul:
Kui mitu korda tuleb käsk kirjutada: kord või mitu?
Käskude väljundite "Sissejuhatus" ja "Kokkuvõte" ning muutuja i deklareerimine ja initsialiseerimine ei sarnane teiste korduvate tegevustega. Need tehakse vaid üks kord, seega tuleb need kirjutada tsükli kehast välja.
Koodis peavad jääma kõik kolm lahendamise etappi, et neid hiljem raskustes viitamiseks kasutada. Esimese kahe variandi piisab, kui kommenteerida, et need ei segaks.
Õpilase tähelepanu tuleks juhtida järgmistele faktidele:
— Tsükli tingimuses võrreldakse tavaliselt loendurit ja piiri. Loendur võib tsükli kehas muutuda, piiri aga mitte. Selle reegli rikkumiseks tuleb esitada tõsised põhjused.
— Käskude "Sissejuhatus" ja "Kokkuvõte" väljundid asuvad tsükli kehast väljaspool. Me peame need täitma 1 kord. "Sissejuhatus" — enne tegevustele kordamise algust, "Kokkuvõte" — pärast.
Selle teema kinnistamisel, järgmiste omandamisel ning raskustega tegelemisel on isegi tugevatele õpilastele kasulik esitada küsimus: "Aga kui tihti tuleb seda tegevust teha? Üks kord või mitu?".
Lisaoskuste arendamine
Tsüklite uurimise käigus harjutavad üliõpilased veel probleemide diagnoosimise ja lahendamise oskust. Diagnoosi tegemiseks peab tudeng esitama soovitud tulemuse ja võrreldama seda tegeliku tulemusega. Nende vahekorra alusel sõltuvad parandamise tegevused.
Kuna üliõpilased ei suuda sel etapil veel piisavalt hästi kujutada "soovitud" tulemust, võivad nad orienteeruda testandmetele. Üldiselt ei mõista keegi sel etapil veel, mis võiks valesti minna ja kuidas sellega tegeleda. Seetõttu annan ülesande kirjutada üles tüüpilised probleemid ja mõned võimalikud lahendused. Kõige sobivama valimine on tudengi ülesanne.
Kirjutamine on vajalik, et küsida: "Kas tulemused vastasid ootustele?", "Milline olukord praegu kujunes?", "Kas rakendatud lahendus aitas?".
- Tegevuste arv on oodatust 1 võrra vähem või rohkem. Lahendamisviisid:
— suurendada algse arvu arvesti 1 võrra.
— asendada rangem võrdlusoperaator (< või >) mitte rangema (<= või >=) vastu.
— muuta piirväärtuse väärtust 1 võrra. - Tsüklis toimuvad tegevused ilma peatamiseta, lõputult. Lahendamisviisid:
— lisada arvesti muutmise käsk, kui see puudub.
— parandada arvesti muutmise käsku nii, et selle väärtus muutuks piirväärtusele lähemale.
— eemaldada piirväärtuse muutmise käsk, kui see on tsükli kehas. - Tsüklis olevate tegevuste arv on rohkem kui 1 võrra vähem või rohkem, kui oodata. Tsükli käigus ei toimunud tegevust kordagi. Esiteks on vajalik välja selgitada muutujate tegelikud väärtused vahetult enne tsükli algust. Lahendamisviisid:
— muuta algväärtust piirväärtuses
— muuta algse arvu arvesti
Tavaliselt on probleem 3 seotud vale muutuja kasutamise või arvesti mitte nullimisega.
Pärast seda seletust võivad tudengil siiski olla erinevad väärarusaamad tsüklite töö kohta.
Kõige levinumate hajutamiseks annan ülesandeid:
- Milles piirväärtus, algse arvu arvesti või arvesti samm sisestatakse kasutaja poolt.
- Milles arvesti väärtust tuleb kasutada mingis aritmeetilises väljendis. Soovitavalt arvestiga allveesuvandi väljendis või nimetajas, et vahe oleks mittelineaarne.
- Millestki, kus loenduri väärtust ei kuvata ekraanil tsükli töötamise ajal. Näiteks sama teksti fragmentide soovitud arvu kuvamine või kujundi joonistamine kilpkonna graafika abil.
- Millestki, kus tuleb esmalt täita ühed korduvad tegevused ja seejärel teised.
- Millestki, kus tuleb enne ja pärast korduvaid tegevusi täita teisi tegevusi.
Iga ülesande jaoks tuleb tuua testandmed ja oodatavad tulemused.
Kuna on vaja mõista, kui kiiresti saab edasi liikuda, tuleb anda lugeda nende ülesannete tingimused ja küsida: "kuidas need erinevad näitest?", "Mida tuleb näites muuta, et neid lahendada?". Kui tudeng vastab sisuliselt, siis lasta tal lahendada vähemalt üks koosoleku ajal ja ülejäänud kodus iseseisvalt. Kui lahendus on edukas, saab alustada tsüklite tingimuste selgitamist.
Kui iseseisev lahendamine tekitab raskusi, tuleb kõik koosolekul läbi töötada. Selleks, et ülesande lahendamine ei meenutaks öökulli joonistamist, soovitan algul lahendada ülesanne mitte universaalselt. See tähendab, et lahendus peaks läbima esimese testi ja mitte kasutama tsükli konstruktsiooni. Alles seejärel rakendage teisendusi, et saavutada universaalsus.
Tsüklid ja harud
Minu arvates on kasulik anda teema "harud tsüklite sees" eraldi. Nii, et hiljem oleks näha erinevus korduva tingimuse kontrollimise ja ühekordse kontrollimise vahel.
Kinnistamise ülesanded on numbrite väljastamine A-st B-ni, mis sisestatakse kasutaja poolt:
— alati kasvavas järjekorras.
— kasvavas või kahanevas järjekorras sõltuvalt A ja B väärtustest.
Teemasse "harud tsüklite sees" tuleb liikuda ainult pärast seda, kui tudeng on omandanud oskused: "mustrid muudetakse muutujaiks" ja "korduvad tegevused muudetakse tsükliks".
Peamine põhjus harude rakendamiseks tsüklite sees on anomaaliad mustris. Keskosas rikutakse seda sõltuvalt lähteandmetest.
Nendele tudengitele, kes suudavad otsida lahendust, kombineerides lihtsaid meetodeid, piisab öelda "harud saab kirjutada tsüklite sees" ja anda ülesanne "näitena" täielikult iseseisvaks lahendamiseks.
Näidisülesanne:
Kasutaja sisestab numbri X. Kuvage veerus numbrid 0 kuni 9 ja asetage märk ‘+’ kõrval sellele numbrile, mis on võrdne X-iga.
Kui sisestati 00+
1
2
3
4
5
6
7
8
9
Kui sisestati 60
1
2
3
4
5
6+
7
8
9
Kui sisestati 90
1
2
3
4
5
6
7
8
9+
Kui sisestati 7770
1
2
3
4
5
6
7
8
9
Kui lühikesest seletusest ei piisa, et kirjutada tsükliga, tuleb saavutada selle sama ülesande universaalne lahendus ilma tsüklita.
Tuleb üks kahest variandist:
Soovitud
string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
Console.WriteLine(0 + "+");
} else {
Console.WriteLine(0);
}
if (x==1) {
Console.WriteLine(1 + "+");
} else {
Console.WriteLine(1);
}
if (x==2) {
Console.WriteLine(2 + "+");
} else {
Console.WriteLine(2);
}
if (x==3) {
Console.WriteLine(3 + "+");
} else {
Console.WriteLine(3);
}
if (x==4) {
Console.WriteLine(4 + "+");
} else {
Console.WriteLine(4);
}
if (x==5) {
Console.WriteLine(5 + "+");
} else {
Console.WriteLine(5);
}
if (x==6) {
Console.WriteLine(6 + "+");
} else {
Console.WriteLine(6);
}
if (x==7) {
Console.WriteLine(7 + "+");
} else {
Console.WriteLine(7);
}
if (x==8) {
Console.WriteLine(8 + "+");
} else {
Console.WriteLine(8);
}
if (x==9) {
Console.WriteLine(9 + "+");
} else {
Console.WriteLine(9);
}
Võimalik
string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
Console.WriteLine("0+n1n2n3n4n5n6n7n8n9");
}
if (x==1) {
Console.WriteLine("0n1+n2n3n4n5n6n7n8n9");
}
if (x==2) {
Console.WriteLine("0n1n2+n3n4n5n6n7n8n9");
}
if (x==3) {
Console.WriteLine("0n1n2n3+n4n5n6n7n8n9");
}
if (x==4) {
Console.WriteLine("0n1n2n3n4+n5n6n7n8n9");
}
if (x==5) {
Console.WriteLine("0n1n2n3n4n5+n6n7n8n9");
}
if (x==6) {
Console.WriteLine("0n1n2n3n4n5n6+n7n8n9");
}
if (x==7) {
Console.WriteLine("0n1n2n3n4n5n6n7+n8n9");
}
if (x==8) {
Console.WriteLine("0n1n2n3n4n5n6n7n8+n9");
}
if (x==9) {
Console.WriteLine("0n1n2n3n4n5n6n7n8n9+");
}
Sarnast ülesannet annan ma ette juba teema uurimise ajal, mis käsitleb haru.
Kui üliõpilasel on välja tulnud "võimalik" variant, tuleb rääkida, et ühe ja sama ülesande lahendusi võib olla palju. Need erinevad aga nõuete muutustele vastupidavuses. Küsige: "Kus koodis tuleb muuta, kui tuleb lisada veel üks number?" "Võimaliku" variandi puhul tuleb lisada veel üks haru ja kirjutada 10 mujal kohas uus number. "Soovitud" variandi puhul piisab, et lisada ainult üks haru.
Seadke ülesanne reprodutseerida "soovitud" variant, seejärel leidke koodis seaduspära, tehke muutuja asendus ja kirjutage tsükkel.
Kui teil on idee, kuidas seda ülesannet lahendada ilma tsüklita mõnel muul viisil, kirjutage palun kommentaarides.
Tsüklid tsüklites
Selle teema puhul tuleks tähelepanu pöörata sellele, et:
— sisemise ja välimise tsükli loendurid peavad olema erinevad muutujad.
— sisemise tsükli loendur tuleb nullida mitu korda (st välimise tsükli kehas).
Tekstrain väljundite puhul ei tohi esmalt kirjutada ühte tähte mitmes reas ja siis teist. Kõik esimeses reas olevad tähed tuleb eelnevalt välja tuua, seejärel kõik teises reas olevad ja nii edasi.
Tsüklite teema selgitamist on kõige parem alustada loenduri nullimise tähtsuse selgitamisest.
Näidisülesanne:
Kasutaja sisestab kaks arvu: R ja T. Väljastada kaks rida sümboleid "#". Esimeses reas peab olema R tükki sümboleid. Teises reas T tükki. Kui mõni number on negatiivne, väljastada veateade.
R=5, T=11#####
###########
R=20, T=3####################
###
R=-1, T=6R väärtus peab olema mitte-negatiivne
R=6, T=-2T väärtus peab olema mitte-negatiivne
Ilmselt on sellel ülesandel ka vähemalt kaks lahendusvarianti.
Soovitud
string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
Console.Write("#");
i = i + 1;
}
Console.WriteLine();
i = 0;
while (i < T)
{
Console.Write("#");
i = i + 1;
}
Võimalik nr 1
string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
Console.Write("#");
i = i + 1;
}
Console.WriteLine();
int j = 0;
j = 0;
while (j < T)
{
Console.Write("#");
j = j + 1;
}
Eroone on see, et "võimalikus" lahenduses teise rea väljundiks kasutati teist muutujat. Tuleb rõhutada, et mõlema tsükli jaoks tuleks kasutada sama muutujat. Sellise piiramise põhjendamiseks võib tuua välja, et ühe loenduri lahendus kahes tsüklis on näide mõistest "loenduri nullimine". Selle termini mõistmine on vajalik järgnevate ülesannete lahendamiseks. Kompromissina võib hoida kaht lahendust ülesandele.
Tüüpiline probleem ühe loenduri kasutamisel kahe tsükli jaoks ilmneb järgmiselt:
R=5, T=11#####
######
Teise rea sümbolite arv ei vasta väärtusele T. Kui selle probleemiga on abi vaja, siis tuleb "nina sisse" torgata tsükli tüüpiliste probleemide kokkuvõttesse. See on sümptom nr 3. Diagnoositakse, kui lisada loenduri väärtuse väljund otse enne teist tsüklit. Parandatakse nullimise teel. Kuid seda parem kohe ei rääkida. Üliõpilane peab proovima vähemalt ühe hüpoteesi formuleerida.
Eksisteerib muidugi ka selline lahendus. Kuid ma pole seda üliõpilastelt kunagi näinud. Tsüklite õppimise etapis selle kohta rääkimine hajutab tähelepanu. Saame sellele hiljem tagasi tulla, kui uurime stringidega töötamise funktsioone.
Võimalik nr 2
string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
Console.WriteLine(new String('#', R));
Console.WriteLine(new String('#', T));
Järgmine kohustuslik ülesanne:
Kuva ekraanile numbrid vahemikus 0 kuni 9. Iga number peab olema oma real. Ridade arvu (W) sisestate klaviatuuri kaudu.
W=10
1
2
3
4
5
6
7
8
9
W=100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Kui üliõpilane on õpetanud muutuja asendamise tehnikat, suudab ta selle kiiresti lahendada. Võimalik probleem on jälle muutuja nullimine. Kui teisendamine ei õnnestu, tähendab see, et olete liiga rutakalt edasi liikunud ja peaksite lahendama lihtsamaid ülesandeid.
Aitäh tähelepanu eest. Pange meeldimised ja tellige kanal.
P.S. Kui leiate tekstis trükivigu või vigu, andke palun teada. Seda saate teha, tähistades tekstiosa ja vajutades Macis «⌘ + Enter» või klassikalistel klaviatuuridel «Ctrl / Enter», või sõnumite kaudu. Kui need valikud ei ole saadaval, kirjutage vigadest kommentaarides. Aitäh!
Ainult registreeritud kasutajad saavad küsitluses osaleda. , palun.
Küsitlus lugejate jaoks, kellel pole karma
20,0%Õpetan professionaalselt, +12
10,0%Õpetan professionaalselt, -11
70,0%Ei õpeta, +17
0,0%Ei õpeta, -10
0,0%Muu0
Hääletas 10 kasutajat. 5 kasutas diskreetset käitumist.
Allikas: habr.com
