Hvordan man lærer at overvinde vanskeligheder og samtidig skrive cyklusser

På trods af at vi vil tale om et af de grundlæggende emner, er denne artikel skrevet til erfarne fagfolk. Målet er at vise, hvilke misforståelser begyndere har inden for programmering. For praktiserende udviklere er disse problemer længe blevet løst, glemt eller slet ikke bemærket. Artiklen kan være nyttig, hvis du pludselig har brug for at hjælpe nogen med dette emne. Artiklen drager paralleller til materiale fra forskellige bøger om programmering af Schildt, Stroustrup, Okulov.

Emnet om cykler blev valgt, fordi rigtig mange mennesker er udelukket fra det, når de mestrer programmering.

Denne teknik er designet til svage elever. Som regel hænger stærke mennesker ikke fast i dette emne, og der er ingen grund til at komme med specielle teknikker til dem. Det sekundære mål med artiklen er at flytte denne teknik fra klassen "virker for alle elever, men kun én lærer" til klassen "virker for alle elever, alle lærere". Jeg påstår ikke absolut originalitet. Hvis du allerede bruger en lignende metode til at undervise i dette emne, så skriv venligst hvordan din version adskiller sig. Hvis du beslutter dig for at bruge det, så fortæl os, hvordan det gik. Hvis en lignende teknik er beskrevet i en bog, bedes du skrive navnet.


Jeg arbejdede på denne teknik i 4 år, hvor jeg studerede individuelt med studerende på forskellige træningsniveauer. I alt er der omkring halvtreds studerende og to tusinde timers undervisning. I starten blev eleverne altid hængende i dette emne og gik. Efter hver elev blev metode og materialer justeret. I løbet af det sidste år har eleverne ikke længere siddet fast i dette emne, så jeg besluttede at dele mine resultater.

Hvorfor så mange bogstaver? Cykler er så elementære!

Som jeg skrev ovenfor, for praktiserende udviklere og for stærke studerende, kan kompleksiteten af ​​begrebet loops undervurderes. Du kan for eksempel holde et langt foredrag, se nikkende hoveder og intelligente øjne. Men når man forsøger at løse ethvert problem, begynder stupor og uforklarlige problemer. Efter forelæsningen havde eleverne formentlig kun en delvis forståelse. Situationen forværres af, at eleverne ikke selv kan give udtryk for, hvad deres vrangforestilling præcis er.
En dag indså jeg, at eleverne opfattede mine eksempler som hieroglyffer. Det vil sige som udelelige tekststykker, hvor du skal tilføje et "magisk" bogstav, og det vil virke.
Nogle gange lagde jeg mærke til, at eleverne tænker, at man har brug for at løse et specifikt problem noget andet et design, som jeg bare ikke har dækket endnu. Selvom løsningen kun krævede en lille ændring af eksemplet.

Så jeg kom op med ideen om, at fokus ikke skulle være på syntaksen af ​​udtryk, men på ideen om at omfaktorere gentagne kode ved hjælp af loops. Når eleverne har mestret denne idé, kan enhver syntaks forbedres med lidt øvelse.

Hvem og hvorfor underviser jeg?

Da der ikke er nogen adgangsprøver, kan klasserne omfatte både stærke og meget svage elever. Du kan læse mere om mine elever i artiklen Portræt af aftenkursusstuderende
Jeg stræbte efter at sikre, at alle, der ønsker at lære programmering, kan lære det.
Mine timer afholdes individuelt, og eleven betaler sine egne penge for hver. Det ser ud til, at studerende vil optimere omkostningerne og kræve minimum. Men folk går til ansigt-til-ansigt klasser med en levende lærer, ikke for selve viden, men for tilliden til det, de har lært, for en følelse af fremskridt og for godkendelse fra eksperten (læreren). Hvis eleverne ikke føler fremskridt i deres læring, vil de gå. Generelt kan klasserne struktureres, så eleverne mærker fremskridt med at øge antallet af kendte strukturer. Det vil sige, først studerer vi mens i detaljer, så studerer vi til, så laver vi mens, og nu har vi et tusind og en nat kursus klar, hvor alene cyklusser studeres i to måneder, og til sidst - en studerende, der skrev et standardbibliotek under diktat. Men for at løse praktiske problemer har du ikke kun brug for viden om materialet, men også uafhængighed i dets anvendelse og i at søge efter ny information. Derfor, for ansigt-til-ansigt-kurser, tror jeg, at det korrekte princip er at undervise i minimum og tilskynde til uafhængig undersøgelse af nuancer og relaterede emner. I emnet loops anser jeg while-konstruktionen for at være minimum. Du kan forstå princippet ud fra det. Når du kender princippet, kan du mestre både for og gør-mens selv.

For at opnå beherskelse af materialet af svage elever, er det ikke nok at beskrive syntaksen. Det er nødvendigt at give mere enkle, men varierede opgaver og beskrive eksempler mere detaljeret. I sidste ende er udviklingshastigheden begrænset af elevens evne til at transformere udtryk og søge efter mønstre. For kloge studerende vil de fleste opgaver være kedelige. Når du studerer med dem, behøver du ikke insistere på at løse 100% af problemerne. Mit materiale kan ses på min github. Sandt nok er depotet mere som en troldmands grimoire - ingen andre end mig vil forstå, hvad der er hvor, og hvis du fejler kontrollen, kan du blive skør

Metodikken er praksisorienteret

Teorien forklares ved hjælp af eksemplet med løsning af et problem. I en grundlæggende programmeringsklasse, hvor der undervises i grene og loops, er det simpelthen ikke muligt at holde en brugbar forelæsning om et emne i en hel time. 15-20 minutter er nok til at forklare konceptet. De største vanskeligheder opstår ved udførelse af praktiske opgaver.
Begyndende lærere kan rasle af operatører, grene, sløjfer og arrays i én forelæsning. Men deres elever vil stå over for problemet med at assimilere denne information.
Det er nødvendigt ikke kun at fortælle materialet, men også at sikre sig, at lytterne forstår det.

At mestre et emne bestemmes af, hvordan eleven håndterer selvstændigt arbejde.
Hvis en elev formåede at løse et problem om et emne uden hjælp fra en lærer, så er emnet blevet mestret. For at sikre selvtestning er hver opgave beskrevet i en tabel med testscenarier. Opgaverne har en klar rækkefølge. Det anbefales ikke at springe opgaver over. Hvis den aktuelle opgave er for svær, så er det nytteløst at gå videre til den næste. Det er endnu mere kompliceret. For at eleven kan mestre den aktuelle komplekse opgave, forklares flere teknikker for ham ved hjælp af eksemplet med den første opgave. Faktisk kommer hele indholdet af emnet ned til teknikker til at overvinde vanskeligheder. Cyklus er mere en bivirkning.

Den første opgave er altid et eksempel. Den anden adskiller sig lidt og udføres "uafhængigt" umiddelbart efter den første under opsyn af en lærer. Alle efterfølgende opgaver er rettet mod at være opmærksom på forskellige småting, der kan forårsage misforståelser.

Forklaringen på eksemplet er en dialog, hvor eleven skal kalde udbredelse og krydsvalidering tilbage for at sikre sig, at han mestrer en del af materialet.

Jeg vil være banal og sige, at det første eksempel om emnet er meget vigtigt. Hvis du har materialet til et omfattende selvstændigt arbejde, kan udeladelserne i det første eksempel rettes. Hvis der ikke er andet end eksemplet, vil den studerende højst sandsynligt ikke mestre emnet.

Mens eller for?

Et af de kontroversielle spørgsmål er valget af konstruktion til eksemplet: mens eller for. Engang brugte en praktiserende udvikler-ven af ​​mig uden undervisningserfaring en time på at overbevise mig om, at for-løkken var den nemmeste at forstå. Argumenterne kogte ned til "alt i det er klart og lagt på sin plads." Men grundårsagen til vanskeligheder for rigtige begyndere er ideen om selve cyklussen og ikke dens skrivning. Hvis en person ikke forstår denne idé, vil han have svært ved syntaksen. Så snart ideen er realiseret, forsvinder problemerne med kodedesign af sig selv.

I mine materialer følger temaet loops temaet forgrening. Den ydre lighed mellem hvis og mens giver os mulighed for at tegne en direkte analogi: "når betingelsen i overskriften er sand, så udføres kroppen." Den eneste ejendommelighed ved cyklussen er, at kroppen bliver henrettet mange gange.

Mit andet argument er, at mens kræver mindre formatering end for. Mindre formatering betyder færre dumme fejl med manglende kommaer og parenteser. Begyndere har endnu ikke udviklet tilstrækkelig opmærksomhed og omhyggelighed til automatisk at undgå syntaksfejl.
Det tredje argument er forklaret i mange gode bøger som det første argument.

Hvis eleven nemt kan transformere udtryk, så kan man tale om for i forbifarten. Eleven vælger så det, han bedst kan lide. Hvis transformationer forårsager vanskeligheder, er det bedre ikke at distrahere din opmærksomhed. Lad eleven først løse alt ved hjælp af mens. Når du har mestret emnet loops, kan du omskrive løsningerne for at øve dig i at konvertere mens til for.
Postcondition-løkker er et ret sjældent udyr. Jeg bruger overhovedet ikke tid på det. Hvis en elev har mestret ideerne om at identificere mønstre og transformere udtryk, kan han finde ud af det uden min hjælp.

Når jeg demonstrerer det første eksempel for stærke elever, gør jeg opmærksom på, at det i det første eksempel er vigtigt at registrere ikke kun løsningen, men også hele kæden af ​​handlinger, der førte til resultatet. Dovne elever kan forsømme skrivningen og kun kopiere den endelige algoritme. De skal overbevises om, at der en dag vil komme en svær opgave. For at løse det skal du følge trinene som i dette eksempel. Derfor er det vigtigt at registrere alle stadier. I de følgende problemer vil det være muligt kun at lade den endelige version af løsningen stå.

Hovedideen med automatisering er, at vi overlader en computer til at udføre rutinearbejde for en person. En af de grundlæggende teknikker er at skrive loops. Det bruges, når flere identiske gentagne handlinger er skrevet i et program i træk.

Eksplicit er bedre end implicit

Det kan virke som en god idé at vise den samme sætning flere gange i den første løkkeopgave. For eksempel:

Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!

Denne indstilling er dårlig, fordi tællerværdien ikke er synlig i outputtet. Dette er et problem for begyndere. Undervurder hende ikke. Først var denne opgave den første, og opgaven med at udlede en række tal i stigende rækkefølge var den anden. Det var nødvendigt at indføre yderligere udtryk "cyklus N gange" og "cyklus fra A til B", som i det væsentlige er det samme. For ikke at skabe unødvendige enheder besluttede jeg kun at vise et eksempel med output af en række tal. De færreste formår at lære at holde en tæller i hovedet og modellere et programs opførsel i hovedet uden forberedelse. Nogle elever møder først mental modellering om emnet cyklusser.
Efter lidt øvelse giver jeg den opgave at gentage den samme tekst, der skal løses selvstændigt. Giver man først en synlig tæller og derefter en usynlig, får eleverne færre problemer. Nogle gange er hintet "skriv ikke tælleren på skærmen" nok.

Hvordan forklarer andre det?

I de fleste undervisningsmaterialer på internettet gives cyklussens syntaks som en del af et "foredrag". For eksempel på developer.mozilla.org (i øjeblikket) er flere andre konstruktioner beskrevet sammen med while-løkken. I dette tilfælde er kun design selv givet i form af skabeloner. Resultatet af deres lancering er beskrevet i ord, men der er ingen illustration. Efter min mening multiplicerer en sådan præsentation af emnet nytten af ​​sådanne materialer med nul. Eleven kan omskrive koden og køre den selv, men han har stadig brug for en standard til sammenligning. Hvordan kan du forstå, at et eksempel er blevet omskrevet korrekt, hvis der ikke er noget at sammenligne resultatet med?
Når der kun gives en skabelon, uden et eksempel, bliver det endnu sværere for eleven. Hvordan forstår man, at kodefragmenterne er placeret korrekt i skabelonen? Du kan prøve at skrive på en eller anden måde, og løb derefter. Men hvis der ikke er nogen standard til at sammenligne resultatet, så hjælper lancering heller ikke.

I C++-kurset om Intuitiv er loop-syntaksen begravet på tredje side af Forelæsning 4 om emnet "operatører". Når syntaksen af ​​sløjfer forklares, lægges der særlig vægt på udtrykket "operatør". Udtrykket præsenteres som et sæt fakta som "symbol; dette er et udsagn", "{} er et sammensat udsagn", "sløjfens krop skal være et udsagn". Jeg kan ikke lide denne tilgang, fordi den ser ud til at skjule vigtige relationer bag et udtryk. At analysere et programs kildekode i termer på dette niveau er påkrævet af compilerudviklere for at implementere sprogspecifikationen, men ikke af studerende som en første tilnærmelse. Nybegyndere til programmering er sjældent omhyggelige nok til at være så opmærksomme på vilkårene. Det er en sjælden person, der husker og forstår nye ord første gang. Næsten ingen kan korrekt anvende et udtryk, de lige har lært. Derfor får eleverne en masse fejl som "Jeg skrev mens(a<7);{, men programmet virker ikke."
Efter min mening er det i begyndelsen bedre at give konstruktionens syntaks med det samme med parenteser. Muligheden uden parentes bør kun forklares, hvis eleven har et specifikt spørgsmål: "hvorfor er der ingen parentes, og det virker."

I Okulovs bog fra 2012 "Fundamentals of Programming" begynder en introduktion til loops med for-mønsteret, giver derefter anbefalinger til dets brug og går derefter straks til lektionens eksperimentelle del. Jeg forstår, at bogen er skrevet til den minoritet af meget dygtige elever, som sjældent kommer til mine timer.

I populære bøger er resultatet af kodefragmenter altid skrevet. For eksempel Shildts "Java 8. The Complete Guide" 2015-udgave. Først gives en skabelon, derefter et eksempelprogram og umiddelbart efter det - resultatet af udførelsen.

Som et eksempel kan du overveje en while-løkke, der gør det omvendte
nedtælling startende fra 10, og præcis 10 linjer med "mål" vises:

//Продемонстрировать применение оператора цикла while
class While {
    public static void main(String args []) {
        int n = 10;
        while (n > 0) {
            System.out.println("такт " + n);
            n--;
        }
    }
}

Når det er kørt, udsender dette program ti "cyklusser" som følger:
такт 10
такт 9
такт 8
такт 7
такт 6
такт 5
такт 4
такт 3
такт 2
такт 1

Tilgangen til at beskrive en skabelon, et eksempelprogram og programmets resultat bruges også i bogen "Javascript for Kids" og i js-kurset på w3schools.com. Websideformatet tillader endda dette eksempel at være interaktivt.

Stroustrups bog fra 2016 Principles and Practice Using C++ gik endnu længere. Det første trin er at forklare, hvilket resultat der skal opnås, og derefter vises programmets tekst. Desuden tager de ikke bare et tilfældigt program som eksempel, men giver en udflugt i historien. Det er med til at gøre opmærksom på det: ”Se, det her er ikke bare noget ubrugelig tekst. Du ser noget meningsfuldt."

Som et eksempel på iteration kan du overveje det første program, der udføres på en lagret programmaskine (EDSAC). Det blev skrevet af David Wheeler ved Computer Laboratory ved Cambridge University, England den 6. maj 1949. Dette program beregner og udskriver en simpel liste over kvadrater.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Her indeholder hver linje et tal efterfulgt af et tabulatortegn ('t') og kvadratet af dette tal. C++ versionen af ​​dette program ser sådan ud:

//Вычисляем и распечатываем таблицу квадратов чисел 0-99
int main()
{
    int i = 0; // Начинаем с нуля
    while(i < 100){
        cout << i << 't' << square(i) << 'n';
        ++i;
    }
}

Interessant nok er syntaksmønsteret ikke beskrevet i denne bog. Stroustrup i instruktørvejledningen (oversættelse) understreger, at den respekterer sine elevers intelligens. Måske betragtes evnen til at identificere et mønster i flere eksempler som en manifestation af en sådan intelligens.

Som jeg forklarer mig selv

Stroustrups tilgang: at beskrive resultatet, derefter at løse problemet, og derefter en selvstændig analyse af eleven - virker mest gennemtænkt. Derfor besluttede jeg at tage det som grundlag, men fortælle det ved hjælp af et mindre historisk eksempel - opgaven med at udlede en "indholdsfortegnelse". Det danner et genkendeligt anker, så man så kan sige ”husk opgaven om indholdsfortegnelsen” og så eleverne husker præcis dette. I mit eksempel forsøgte jeg at forhindre yderligere to af de mest almindelige misforståelser. Dernæst vil jeg skrive mere om dem.

I denne opgave bliver vi introduceret til teknikker til løsning af komplekse problemer. Den første beslutning skal tages primitiv og enkel. Nå, så kan du tænke over, hvordan du kan forbedre denne løsning.
Введение
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Заключение

Ifølge mine observationer fører "skabelon-eksempel-resultat" tilgangen i forskellige kombinationer stadig til, at eleverne opfatter cyklussen som en hieroglyf. Dette viste sig i, at de ikke forstod, hvorfor der var en betingelse for at skrive der, hvordan man kunne vælge mellem i++ og i— og andre tilsyneladende indlysende ting. For at undgå disse misforståelser bør tilgangen til at tale om cyklusser understrege betydningen af ​​at gentage identiske handlinger og først derefter formalisere dem ved hjælp af en struktur. Derfor, før du giver loop-syntaksen, skal du løse problemet direkte. En primitiv løsning på indholdsfortegnelsesproblemet ser sådan ud:

Console.WriteLine("Введение");
Console.WriteLine("Глава 1");
Console.WriteLine("Глава 2");
Console.WriteLine("Глава 3");
Console.WriteLine("Глава 4");
Console.WriteLine("Глава 5");
Console.WriteLine("Глава 6");
Console.WriteLine("Глава 7");
Console.WriteLine("Заключение");

Hvordan kan det forbedres?
Erstat monotone handlinger med en cyklus.
Hvilke handlinger gentages i træk uden ændringer?
Der er ingen i dette fragment. Kommandoerne til at vise ordet "Kapitel" med et tal er dog meget lig hinanden.
Derfor er næste fase at finde forskellen mellem fragmenterne. Det er kun i denne opgave, at alt er indlysende, så vil ikke enkelte kommandoer blive gentaget, men kodeblokke på 5 linjer eller mere. Du bliver nødt til at søge ikke kun i listen over kommandoer, men i forgrenings- eller sløjfekonstruktioner.
I eksemplet er forskellen mellem kommandoerne i tallet efter ordet "Kapitel".
Når forskellen er fundet, skal du forstå forandringsmønsteret. Det anderledes fragment er nummeret? Er det konstant stigende eller faldende? Hvordan ændres værdien af ​​et tal mellem to hold side om side?
I eksemplet stiger tallet efter ordet "Kapitel" i trin på 1. Forskellen er fundet, mønsteret afsløres. Nu kan du erstatte det forskellige fragment med en variabel.
Du skal erklære en sådan variabel før det første af de gentagne fragmenter. En sådan variabel kaldes normalt I eller j eller noget mere detaljeret. Dens startværdi skal være lig med den første værdi, der vises på skærmen. I eksemplet er den første værdi 1.
Hvilken begyndelsesværdi skal tages for at vise talrækken "100, 101, 102, 103, 104, 105"?
Det første tal i denne serie er 100.
Efter hver outputkommando skal du øge værdien af ​​denne variabel med 1. Denne enhed er ændringstrinnet.
Hvilket trin vil være i rækken af ​​tal "100, 102, 104, 106"?
Trin 2 i denne række.
Efter at have erstattet det forskellige fragment med en variabel, vil koden se sådan ud:

Console.WriteLine("Введение");
int i;
i = 0;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Заключение");

Efter at have anvendt "udtryk mønsteret af en variabel"-teknikken i koden, får du flere grupper af identiske handlinger, der går i træk. Nu kan gentagne handlinger erstattes med en løkke.

Sekvensen for at løse et problem, hvor du skal bruge sløjfer, består af følgende trin:

  1. Løs "head-on" med mange separate kommandoer
  2. Find et mønster
  3. Udtryk mønsteret af en variabel
  4. Design som en cyklus

Dernæst introduceres nye termer, så eleven ikke kommer i situationen "Jeg forstår alt, men jeg kan ikke sige det":
— en tæller er altid en variabel, der er nødvendig for at spore antallet af trin i en løkke. Typisk et heltal, der sammenlignes med begrænsningen.
— tællertrin — beskrivelse af mønsteret for tællerændringer.
- begrænsning - et tal eller en variabel, som tælleren sammenlignes med, så algoritmen er endelig. Tællerværdien ændres for at nærme sig grænsen.
— loop body — et sæt kommandoer, der vil blive gentaget. Når de siger "kommandoen er skrevet inde i en løkke", mener de kroppen.
— loop iteration — engangsudførelse af loop body.
— loop condition — et logisk udtryk, der bestemmer, om en anden iteration vil blive udført. (Der kan være forveksling med forgreningsstrukturer her)
Du skal være forberedt på, at eleverne i første omgang vil bruge termer til andre formål. Det gælder både de stærke og de svage. At etablere et fælles sprog er en kunst. Nu vil jeg skrive kort: du skal indstille opgaven "fremhæv kodefragmentet med <term>" og bruge disse udtryk selv korrekt i samtalen.
Efter transformation med en løkke opnås fragmentet:

Console.WriteLine("Введение");
int i = 0;
while (i < 7) {
    Console.WriteLine("Глава " + i);
    i = i + 1;
}
Console.WriteLine("Заключение");

Den vigtigste misforståelse

En populær misforståelse blandt elever er, at de placerer handlinger i en løkke, som kun skal udføres én gang. For eksempel sådan her:

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Введение")
    Console.WriteLine("Глава " + i);
    i = i + 1;
    Console.WriteLine("Заключение");
}

Eleverne støder på dette problem hele tiden, både i begyndelsen og i mere komplekse problemer.
Nøgletip i dette tilfælde:

Hvor mange gange skal du gentage kommandoen: én eller mange gange?

Kommandoerne til at udskrive ordene "Introduktion" og "Konklusion" og erklære og initialisere variablen i er ikke som andre gentagne handlinger. De udføres kun én gang, hvilket betyder, at de skal skrives uden for løkketeksten.

Alle tre faser af løsningen bør forblive i koden, så du kan henvise til dem senere i tilfælde af vanskeligheder. Det er nok at kommentere de to første muligheder, så de ikke forstyrrer.
Elevens opmærksomhed skal henledes på følgende fakta:
— I en sløjfetilstand sammenlignes normalt en tæller og en grænse. Tælleren kan ændre sig i løkkens krop, men grænsen kan ikke. For at bryde denne regel skal du formulere tvingende grunde.
— Kommandoer til at vise ordene "Introduktion" og "Konklusion" er placeret uden for løkkens krop. Vi skal udføre dem 1 gang. "Introduktion" - før gentagelse af handlingerne, "Konklusion" - efter.
I processen med at konsolidere dette emne, mestre de næste, samt håndtere vanskeligheder, er det nyttigt for selv stærke elever at stille spørgsmålet: "Hvor mange gange skal denne handling udføres? En eller mange?

Udvikling af yderligere kompetencer

I processen med at studere cyklusser udvikler eleverne også evnen til at diagnosticere og løse problemer. For at udføre diagnostik skal eleven præsentere det ønskede resultat og sammenligne det med det faktiske resultat. Korrigerende handlinger afhænger af forskellen mellem dem.
Da eleverne på dette trin stadig ikke har nogen idé om det "ønskede" resultat, kan de fokusere på testdata. Som regel er der ingen, der på nuværende tidspunkt endnu forstår, hvad der kan gå galt, og hvordan man håndterer det. Derfor skriver jeg i en notesbog en beskrivelse af typiske problemer og flere måder at løse dem på. At vælge den bedst egnede er elevens opgave.
En registrering er nødvendig for at spørge "skede det forventede?", "Hvilke af disse situationer skete nu?", "Hjælp den anvendte løsning?"

  1. Antallet af handlinger er 1 mindre eller mere end forventet. Løsninger:
    — øge tællerens begyndelsesværdi med 1.
    — Erstat den strenge sammenligningsoperator (< eller >) med en ikke-streng (<= eller >=).
    — ændre grænseværdien til 1.
  2. Handlinger i en loop udføres uden stop, på ubestemt tid. Løsninger:
    — tilføj en tællerændringskommando, hvis den mangler.
    — fix tællerændringskommandoen, så dens værdi bliver tættere på grænsen.
    — fjern kommandoen til ændring af begrænsninger, hvis den er i løkkens krop.
  3. Antallet af handlinger i en loop er mere end 1 mindre eller mere end forventet. Handlingen i løkken blev ikke udført en gang. Først skal du finde ud af de faktiske værdier af variablerne lige før løkken starter. Løsninger:
    — ændre startværdien af ​​begrænsningen
    — ændre startværdien af ​​tælleren

Opgave 3 involverer normalt at bruge den forkerte variabel eller ikke nulstille tælleren.

Efter denne forklaring kan eleven stadig have forskellige misforståelser om, hvordan loops fungerer.
For at fjerne de mest almindelige giver jeg dig følgende opgaver:

  1. I hvilken grænsen, den indledende tællerværdi eller tællertrinet indtastes af brugeren.
  2. I hvilken tællerværdien skal bruges i et eller andet aritmetisk udtryk. Det er tilrådeligt at bruge en tæller i det radikale udtryk eller i nævneren, så forskellen er ikke-lineær.
  3. I hvilken tællerværdien ikke vises på skærmen, mens løkken kører. For eksempel at vise det nødvendige antal identiske tekstfragmenter eller tegne en figur med skildpaddegrafik.
  4. I hvilket du først skal udføre nogle gentagne handlinger og derefter andre.
  5. Hvor du skal udføre andre handlinger før og efter gentagelse

For hver opgave skal du angive testdata og det forventede resultat.

For at forstå, hvor hurtigt du kan bevæge dig, skal du læse betingelserne for disse problemer og spørge: "hvordan adskiller de sig fra eksemplet?", "Hvad skal ændres i eksemplet for at løse dem?" Hvis eleven svarer meningsfuldt, så lad ham løse mindst én i klassen, og resten derhjemme på egen hånd. Hvis løsningen lykkes, så kan vi begynde at forklare forholdene inde i løkkerne.
Hvis du har problemer med at løse problemer på egen hånd, skal du arbejde dig igennem alt i klassen. For at undgå at løse problemet minder om at tegne en ugle, anbefaler jeg først at løse problemet på en ikke-universal måde. Det vil sige, at løsningen består den første test og ikke bruger løkkekonstruktionen. Nå, så anvend transformationer for at opnå universalitet af løsningen.

Løkker og grene

Efter min mening er det nyttigt at give emnet "cyklusser inden for grene" separat. Så du senere kan se forskellen mellem at kontrollere en tilstand flere gange og at kontrollere den én gang.
Opgaverne til konsolidering vil handle om at udlæse tal fra A til B, som indtastes af brugeren:
- altid i stigende rækkefølge.
- stigende eller faldende afhængigt af værdierne af A og B.

Emnet "forgrening inden for sløjfer" bør først flyttes videre, efter at eleven har mestret teknikkerne: "erstatning af et mønster med en variabel" og "erstatning af gentagne handlinger med en cyklus."
Hovedårsagen til at bruge grene inde i løkker er anomalier i mønsteret. I midten går den i stykker afhængigt af de indledende data.
For de elever, der er i stand til at lede efter en løsning ved at kombinere simple teknikker, er det nok at sige "forgrening kan skrives inde i løkker" og give problemet "for eksempel" helt til at løse selvstændigt.
Eksempel på opgave:

Brugeren indtaster tallet X. Vis tallene fra 0 til 9 i en kolonne og sæt et '+'-tegn ud for tallet, der er lig med X.

Hvis 0 blev indtastet0+
1
2
3
4
5
6
7
8
9

Hvis 6 blev indtastet0
1
2
3
4
5
6+
7
8
9

Hvis 9 blev indtastet0
1
2
3
4
5
6
7
8
9+

Hvis 777 blev indtastet0
1
2
3
4
5
6
7
8
9

Hvis en kort forklaring ikke er nok til at skrive med en loop, så skal du opnå en universel løsning på det samme problem uden en loop.
Du får en af ​​to muligheder:
Ønsket

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);
}

Muligt

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+");
}

Jeg giver en lignende opgave på forhånd, mens jeg studerer emnet forgrening.
Hvis eleven kommer med en "mulig" mulighed, så skal du fortælle dem, at der kan være mange løsninger på samme problem. Imidlertid adskiller de sig i deres modstand mod ændringer i krav. Stil spørgsmålet: "Hvor mange steder i koden skal der rettes, hvis jeg skulle tilføje et andet nummer?" I den "mulige" version skal du tilføje en gren mere og tilføje et nyt nummer 10 andre steder. I den "ønskede" er det nok kun at tilføje en gren.
Indstil opgaven til at reproducere den "ønskede" mulighed, find derefter et mønster i koden, udfør en variabel udskiftning og skriv en løkke.
Hvis du har en idé til, hvordan du løser dette problem uden en loop på anden måde, så skriv venligst i kommentarerne.

Sløjfer indenfor Sløjfer

I dette emne skal du være opmærksom på følgende:
— tællere for de indre og ydre sløjfer skal være forskellige variable.
— tælleren for den indre sløjfe skal nulstilles mange gange (det vil sige i kroppen af ​​den ydre sløjfe).
— i tekstoutputopgaver kan du ikke først skrive ét bogstav på flere linjer og derefter det andet. Du skal først udskrive alle bogstaverne i den første linje, derefter alle bogstaverne i den anden, og så videre.

Det er bedst at begynde at forklare emnet loops inden for loops ved at forklare vigtigheden af ​​at nulstille tælleren.
Eksempel på opgave:

Brugeren indtaster to tal: R og T. Udskriv to linjer med "#"-tegn. Den første linje skal indeholde R-tegn. Den anden linje indeholder T-stykker. Hvis et tal er negativt, skal du vise en fejlmeddelelse.

R=5, T=11#####
###########

R=20, T=3######################
###

R=-1, T=6R-værdien skal være ikke-negativ

R=6, T=-2T-værdien skal være ikke-negativ

Dette problem har naturligvis også mindst to løsninger.
Ønsket

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;
}

Mulig #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;
}

Forskellen er, at i den "mulige" løsning blev en anden variabel brugt til at udlæse den anden linje. Du bør insistere på at bruge den samme variabel til begge sløjfer. Denne begrænsning kan begrundes med, at en løsning med én tæller i to cyklusser vil være en illustration af udtrykket "tællernulstilling". Det er nødvendigt at forstå dette udtryk, når du løser følgende problemer. Som et kompromis kan du gemme begge løsninger på problemet.

Et typisk problem med at bruge en tællervariabel til to sløjfer ser således ud:
R=5, T=11#####
######

Antallet af tegn i anden linje svarer ikke til værdien af ​​T. Hvis du har brug for hjælp til dette problem, så skal du kigge i noterne om typiske problemer med loops. Dette er symptom #3. Det diagnosticeres, hvis du tilføjer en tællerværdioutput umiddelbart før den anden cyklus. Rettet ved nulstilling. Men det er bedre ikke at fortælle dette med det samme. Eleven skal forsøge at formulere mindst én hypotese.

Der er selvfølgelig en anden løsning. Men jeg har aldrig set det blandt studerende. På stadiet af at studere cyklusser vil historien om det distrahere opmærksomheden. Du kan vende tilbage til det senere, når du lærer om strengfunktioner.
Mulig #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));

Næste påkrævede opgave:

Vis tallene fra 0 til 9. Hvert tal skal stå på sin egen linje. Antallet af cifre i en linje (W) indtastes fra tastaturet.

W = 10
1
2
3
4
5
6
7
8
9

W = 100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999

Hvis en studerende har mestret teknikken til at erstatte en variabel, så vil han klare sig ret hurtigt. Et muligt problem vil igen være at nulstille variablen. Hvis du ikke kan håndtere transformationen, betyder det, at du havde travlt og skulle løse enklere problemer.

Tak for din opmærksomhed. Like og abonner på kanalen.

PS Hvis du finder stavefejl eller fejl i teksten, så lad mig det vide. Dette kan gøres ved at vælge en del af teksten og trykke på "⌘ + Enter" på Mac og "Ctrl / Enter" på klassiske tastaturer eller via private beskeder. Hvis disse muligheder ikke er tilgængelige, så skriv om fejl i kommentarerne. Tak skal du have!

Kun registrerede brugere kan deltage i undersøgelsen. Log ind, Vær venlig.

Afstemning for læsere uden karma

  • 20,0 %Jeg underviser professionelt, +12

  • 10,0 %Jeg underviser professionelt, -11

  • 70,0 %Jeg underviser ikke, +17

  • 0,0 %Jeg underviser ikke, -10

  • 0,0 %Andet 0

10 brugere stemte. 5 brugere undlod at stemme.

Kilde: www.habr.com

Tilføj en kommentar