DOUG LLOYD: All right. Så nå la oss takle en virkelig stort tema, funksjoner. Så langt i løpet, hele programmene som vi har vært å skrive har blitt skrevet innsiden av hoved. De er ganske enkle programmer. Du trenger ikke å ha alle disse greiner og ting skjer. Vi kan bare plass til alle innsiden av hoved og det blir ikke veldig overveldende. Men som kurset går videre og når du begynner å utvikle programmer uavhengig av hverandre, er de sannsynligvis kommer å begynne å få mye mer enn 10 eller 15 linjer. Du kan få hundrevis eller tusenvis eller titusenvis av linjer med kode. Og det er egentlig ikke som gal en tanke. Som sådan, er det sannsynligvis ikke en god idé å holde alt inne i hoved. Det kan bli litt vanskelig å finne hva du leter etter hvis du gjør det. Heldigvis skjønt C, og ganske mye alle andre programmeringsspråk som kan jobbe med, gjør det mulig oss til å skrive funksjoner. Og jeg skal bare ta en rask side her å nevne at funksjonene er ett område av informatikk. Og du vil se mange flere av dem på ulike punkter gjennom hele kurset og hvis du fortsetter videre. Der det er mye synonymer for det samme ord. Så vi kaller funksjonene. Men du kan også høre dem referert til som prosedyrer, eller metoder, spesielt hvis du har noen gang gjort noen objektorientert programmering before-- og ikke bekymre hvis du ikke har, ikke en stor deal-- men i revisjonsorienterte språk er ofte kalt metoder. Noen ganger de kalles subrutiner. Men de virkelig alle refererer til den samme grunnleggende ideen. La oss se hva den ideen er. Hva er en funksjon? Vel en funksjon er virkelig noe mer enn en svart boks. En svart boks som har et sett med null eller flere innganger og en enkelt utgang. Så for eksempel, dette kan være en funksjon. Dette er en funksjon som heter func. Og det tar tre innganger a, b, og c. Og inni den svarte boksen, vi vet ikke nøyaktig hva den gjør, men det behandler inngangene på en eller annen måte, og da det gir en enkel utgang, i dette tilfellet, z. Nå for å gjøre det litt mindre abstrakt, vi kunne si at vi kanskje har en funksjon som kalles legge til at tar tre innganger a, b, og c og behandler utgangs på noen måte inni den svarte boksen til frembringe en enkelt utgang. Slik at i dette tilfellet, hvis legge tar 3, 6 og 7. Et eller annet sted inne i legge til funksjon, ville vi forventer at de skal legges sammen for å frembringe den utgang, som er tre pluss seks pluss 7 eller 16. På samme måte har du en funksjon som heter mult som tar to innganger, a og b, behandler dem på en eller annen måte, for eksempel at utgangen fra funksjons er produktet av de to inngangene. De to inngangene multiplisert sammen. 4 og 5 blir vedtatt i mult, noe skjer, resultatet vi forventer er 20. Hvorfor kaller vi det en svart boks? Vel, hvis vi ikke skriver det fungerer oss selv, som vi har gjort ganske mye så langt CS50. Vi har sett print f, for eksempel, som er en funksjon som vi ikke skrive oss selv, men vi bruker hele tiden. Hvis vi ikke skriver funksjonene oss selv, vi trenger egentlig ikke å vite hvordan det er faktisk blir gjennomført under panseret. Så for eksempel den svarte boksen jeg bare viste deg for multiplikasjon, mult en kan b være defined-- og dette er bare noen pseudocode-- kan være definert som utgangs en ganger b. Det fornuftig, ikke sant. Hvis vi har en funksjon som heter mult som tar to innganger. Vi forventer at produksjonen ville være de to inngangene multiplisert sammen, en ganger b. Men kan også være mult implementert som dette, vi har en teller variabel til få satt inni mult til 0. Og da vi gjenta denne prosessen b ganger legger en til disken. For eksempel, hvis vi multipliserer 3a ved 5b, vi kunne si sette telleren til 0, gjenta fem ganger, tilsett 3 til disken. Så vi starter på 0 og deretter vi gjør dette fem ganger 3, 6, 9, 12, 15. Det er det samme resultatet. Vi fortsatt få 3 ganger 5 bare implementeringen er forskjellig. Det er det vi mener når vi sier en svart boks. Det betyr bare at vi egentlig ikke bryr seg hvordan den er implementert under panseret så lenge produksjonen er hva vi forventer. Faktisk, det er en del av kontrakten for å bruke funksjoner, spesielt funksjoner som andre skriver. Oppførselen er alltid kommer å være typisk, uforutsigbar basert på navnet på funksjonen. Og det er derfor det er virkelig viktig når du skriver funksjoner eller når andre folk skriver funksjoner som du kan bruke, at disse funksjonene har klare, relativt åpenbare navn, og er godt dokumentert. Som er absolutt tilfelle for funksjonen som print f. Så hvorfor skal vi bruke funksjoner? Vel som jeg sa tidligere, hvis vi skriver alle våre kode innsiden av viktigste tingene kan bli veldig tungvint og veldig komplisert. Funksjoner tillate oss muligheten å organisere ting og bryte opp et veldig komplisert problem i mye mer håndterbare underdeler. Funksjoner også tillate oss å forenkle kodingsprosessen. Det er mye lettere å feilsøke en 10 linje funksjon kontra en 100 linje funksjon eller en linje 1000 funksjon. Hvis vi bare nødt til å feilsøke små biter om gangen, eller skrive små stykker på den tiden, det gjør at erfaring med programmering mye bedre. Stol på meg på den. Til slutt, hvis vi skriver funksjoner vi kan gjenbruke de forskjellige delene. Funksjoner kan resirkuleres. De kan brukes i en program eller en annen. Du har allerede skrevet funksjonen, alt du trenger å gjøre er å fortelle at programmet hvor du finner den funksjonen. Vi har vært resirkulering og bruk skrive ut f i over 40 år. Men det ble bare skrevet én gang. Ganske nyttig, ikke sant. Greit. Så funksjoner er stor. Vi vet det. La oss nå begynne å skrive dem. La oss begynne å bli dem inn i våre programmer. For å gjøre det, det første vi gjør er erklære funksjonen. Når du deklarerer en funksjon hva du egentlig gjør forteller kompilatoren, hei, bare så du vet, Jeg kommer til å skrive en funksjon senere og her er hva det kommer til å se ut. Grunnen til dette er fordi kompilatorer kan gjør noen rare ting hvis de ser et sett med symboler at de ikke er kjent med. Så vi bare gi kompilatoren en heads up, jeg skaper en funksjon og det kommer til å gjøre dette. Funksjon erklæringer generelt hvis du organisere koden på en måte at andre vil kunne forstå og gjøre bruk av, du generelt ønsker å sette alle av funksjons erklæringer på toppen av koden din, rett før du begynner å skrive hoved selv. Og praktisk, det er en veldig standard skjema at hver funksjon erklæring følger. De er alle ganske mye ser ut som dette. Det er tre deler til en funksjon erklæringen, returtype, navn, og argumentliste. Nå returtypen er hva slags variable funksjonen vil produksjonen. Så for eksempel, hvis vi tenker tilbake en minutt siden til å multiplisere to- tall funksjon, hva gjør vi forvente hvis vi multipliserer et tall med et heltall produksjonen vil bli sannsynligvis et heltall, ikke sant. Multiplisert to heltall sammen, får du et heltall. Så avkastningen type som funksjon ville være int. Navn er det du ønsker å ringe din funksjon. Dette er trolig den minst viktige del av funksjonen erklæringen når det gjelder funksjonalitet. Men faktisk er trolig en av de viktigste delene av funksjonen erklæring i form av å vite hva funksjonen faktisk gjør. Hvis du navnet ditt funksjon f eller g eller h eller mysterium eller noe sånt, er du sannsynligvis kommer til å få litt utløst opp prøver å huske hva disse funksjonene gjør. Så det er viktig å gi funksjonens meningsfulle navn. Til slutt, er argument liste kommaseparert liste av alle innganger til din funksjon, som hver har en type og et navn. Så ikke bare har du til spesifisere hva slags variabel Funksjonen vil utgang, du også ønsker å spesifisere hva slags og hvilke variabler de funksjon vil være å akseptere som innganger. Så la oss gjøre et eksempel her. La oss bare ta en titt på en mer konkret en. Så her er et eksempel på en funksjon erklæring for en funksjon som ville legge to heltall sammen. Summen av to heltall skal være et heltall også, som vi bare diskutert. Og så returtypen, her i grønt, ville være int. Som bare forteller oss at legge to ints kommer til, ved slutten av dagen, utgang, eller spytte det tilbake ut til oss, et heltall. Gitt hva denne funksjonen gjør vi ønsker å gi det et meningsfullt navn. Legg to ints virker hensiktsmessig, med tanke vi tar to heltall som innganger og forhåpentligvis legge dem sammen. Det kan være litt av en tungvint navn og ærlig denne funksjonen er sannsynligvis ikke nødvendig siden vi har tilsetting operatør, hvis du husker fra vår drøfting av operatører, tidligere. Men la oss bare si for moro skyld Argumentet om at denne funksjonen er nyttig og så får vi kalle det legge to ints. Til slutt, tar denne funksjonen to innganger. Som hver for seg er et heltall. Så vi har denne komma separert liste med innganger. Nå er vi generelt ønsker å gi et navn til hver av dem slik at de kan benyttes i funksjonen. Navnene er ikke veldig viktig. I dette tilfellet har vi ikke nødvendigvis har noen betydning knyttet til dem. Så vi kan bare kalle dem a og b. Det er helt greit. Hvis derimot, finner du selv i en situasjon hvor navnene på de variable faktisk kan være viktig, kan det være lurt å ringe dem noe annet enn en, og b å gi dem noe mer symbolsk meningsfylt. Men i dette tilfellet, gjør vi egentlig ikke vite noe annet om funksjonen. Vi vil bare legge til to heltall. Så får vi bare kalle de heltall a og b. Det er ett eksempel. Hvorfor ikke ta en ekstra å tenke på dette, hvordan ville du skriver en funksjon erklæring for en funksjon som multipliserer to flyttall? Husker du hva en flyttall er? Hva ville denne funksjonen erklæring se ut? Jeg faktisk anbefale deg pause videoen her og ta hvor mye tid du trenger. Tenk på hva dette funksjon erklæring ville være? Hva ville returtypen være? Hva ville et meningsfullt navn være? Hva ville inngangene være? Så hvorfor ikke du pause videoen her og skrive opp en funksjon erklæring for en funksjon som ville formere to flyttall sammen. Forhåpentligvis du stoppet videoen. Så la oss ta en titt på et eksempel av en mulig erklæring. Flyte mult to Reals flyte x, float y. Produktet av to flyttall, som husker er hvordan vi representere reelle tall eller tall med desimaltall i c, kommer til å være et desimaltall. Når du multipliserer et desimal av en desimal, er du sannsynligvis kommer til å få en desimal. Du ønsker å gi det et relevant navn. Multiplisere to Reals virker fint. Men du kan virkelig kalle det mult to flyter, eller mult flyter. Noe sånt, så lenge det ga noen faktiske betydningen til hva denne svarte boksen skulle gjøre. Og igjen, i dette tilfellet, gjør vi ikke ser ut til å ha noen mening festet til navnene på variabler vi passerer i, så vi bare ringe dem x og y. Nå hvis du kaller dem noe annet, det er helt greit. Faktisk, hvis du gjorde denne erklæringen i stedet bruker dobles i stedet av flyter, hvis du husker som dobler er en annen måte til mer presist oppgi reelle tall eller flyt variabler. Det er helt greit også. Enten en av dem ville være fint. Faktisk er det flere ulike kombinasjoner måter å erklære denne funksjonen. Men dette er to ganske gode. Vi har erklært en funksjon, det er flott. Vi har fortalt kompilatoren hva det er, hva vi skal gjøre. Nå la oss faktisk skrive denne funksjonen. La oss gi den en definisjon, slik at inni den svarte boksen forutsigbar oppførsel som skjer. Faktisk er vi multiplisere to reelle tallene sammen, eller legge til tall sammen, eller gjøre hva det er at vi bedt vår funksjon å gjøre. Så faktisk, la oss prøve og definere multiplisere to Reals som vi bare snakket om en andre siden. Nå begynnelsen av en funksjonsdefinisjon ser nesten nøyaktig det samme som en funksjon erklæring. Jeg har begge av dem her. På toppen er funksjonen erklæring, type, navn, kommaseparert argument listen, semikolon. Semikolon indikerer at som er en funksjon erklæring. Begynnelsen av funksjonen definisjon ser nesten nøyaktig det samme, type, navn, kommaseparert argumentliste, ingen semikolon, åpne klammeparentes. Den åpne klammeparentes, akkurat som vi har gjort med hoved, betyr at vi nå begynner å definere hva som skjer inni den svarte boksen som Vi har besluttet å kalle mult to Reals. Her er en måte å gjennomføre det. Vi kan si, vi kunne erklære en ny variabel av type float kalt produktet og tilordne den variabelen til verdien x ganger y. Og deretter returnere produktet. Hva betyr retur mener her. Vel tilbake er veien Vi viser at er hvordan vi passerer utgangs ut igjen. Så tilbake noe, er den samme som, Dette er resultatet av den sorte boksen. Så det er hvordan du gjør det. Her er en annen måte å gjennomføre det. Vi kunne bare gå tilbake x ganger y. x er en flottør. y er en float. Så x ganger y er også en flåte. Vi trenger ikke engang å opprette en annen variabel. Så det er en annen måte å gjennomføre nøyaktig samme sorte boksen. Nå tar et øyeblikk, pause videoen igjen, og prøve og definere legge to ints, som er den andre funksjon som vi snakket om et øyeblikk siden. Igjen her, har jeg satt funksjonen erklæringen, og så semikolon, og en åpen klammeparentes og en lukket krøllete brace for å indikere hvor vi vil fylle i innholdet legge to ints, slik at vi definerer den spesielle atferd inne den svarte boksen. Så pause videoen. Og ta så mye tid som du må prøve og definere en implementering av legge to ints, slik at når funksjonen utmater en verdi, den gjør det, faktisk, retur summen av de to inngangene. Så akkurat som forrige eksempel, Det er flere forskjellige måter at du kan gjennomføre legge to ints. Her er en. Her inne i oransje har jeg bare hadde noen comments-- Jeg har akkurat lagt noen kommentarer for å indikere hva som skjer på hver linje med kode. Så jeg erklære en variabel kalt summen av typen int. Jeg sier sum tilsvarer et pluss b. Det er der vi faktisk gjør arbeidet tilsette A og B sammen. Og jeg kommer tilbake sum. Og det er fornuftig fordi Summen er en variabel av type int. Og hva er dataene skriver at dette funksjon forteller meg at det kommer til produksjon? Int. Så jeg er tilbake sum, som er et helt tall variabel. Og det er fornuftig gitt hva vi har erklært og definert vår funksjon å gjøre. Nå kan du også definere funksjonen på denne måten, int sum tilsvarer et pluss B-- hoppe over den først step-- og deretter returnere sum. Nå kan du også implementert det på denne måten, som jeg ikke anbefaler. Dette er dårlig stil for én ting og virkelig dårlig design, men det gjør i virkeligheten arbeid. Hvis du tar denne koden, som er int legge dårlig huggorm dot c, og bruke det. Det faktisk legger to heltall sammen. Det er en veldig dårlig gjennomføring av denne spesielle oppførsel. Men det fungerer. Det er bare her for å illustrere punktet at vi egentlig ikke seg hva som skjer på innsiden den svarte boksen, så lenge som den har den produksjonen som vi forventer. Dette er en dårlig utformet svart boks. Men på slutten av dagen, gjør det fortsatt produksjon summen av a pluss b. Greit. Så vi har erklært funksjoner. Og vi har definert funksjon. Så det er veldig bra. Nå la oss begynne å bruke funksjonene at vi har deklarert og vi har definert. Å kalle en function-- det er faktisk ganske easy-- alt du trenger å gjøre er pass det riktige argumenter, argumenter av datatype at det forventer, og deretter tildele retur verdien av denne funksjon og dette-- unnskyldning me-- tilordne returverdien av denne funksjonen til noe av riktig type. Så la oss ta en titt på dette i praksis i en fil kalt huggorm en prikk c, som Jeg har i min CS50 IDE. Så her er huggorm en prikk c. I begynnelsen ser du jeg har min inneholder, pund inkluderer, standard IO, og CS50 dot h. Og så har jeg min funksjon erklæring. Det er der jeg er forteller kompilatoren jeg er skal skrive en funksjon kalt legge to ints. Det kommer til å sende ut et heltall type variabel. Det er det denne delen er rett her. Og så har jeg to innganger til det en og b, som hver for seg er et heltall. Innsiden av hoved, jeg ber brukeren om innspill ved å si, gi meg et heltall. Og de blir bedt om å glemme int, som er en funksjon som inngår i CS50 biblioteket. Og som blir lagret i x, et heltall variabel. Så vi ber dem om et annet heltall. Vi får et annet heltall og lagre det i y. Og så, her på linje 28, er hvor vi gjør vår funksjon samtale. Vi sier, int z equals tilsett 2 ints x komma y. Ser du hvorfor dette er fornuftig? x er et helt tall og type variabel y er et helt tall type variabel. Så det er bra. Det fornuftig med hva vår funksjon erklæring på linje 17 ser ut. Kommaseparert innspill liste forventer to heltall, a og b. I så tilfelle, kan vi kalle dem hva vi vil. Det forventer bare to heltall. Og x er et helt tall og y er et helt tall. Som fungerer. Og vi vet at funksjonen skal å sende ut et heltall i tillegg. Og så er vi lagrer Utgangen av funksjon, legge to ints, i en heltallstype variabel, som vi kaller z. Og så kan vi si, summen av prosent i og prosent i er prosent i. henholdsvis x, y og z fylle de prosent i tallet. Hva er definisjonen av legge to ints se ut? Det er ganske enkelt. Det er en av de vi bare så en andre siden, int sum tilsvarer et pluss b retur sum. Virker dette? La oss lagre filen. Og deretter ned her på min terminal Jeg kommer til å gjøre huggorm 1, og jeg tømme skjermen min. Jeg kommer til å zoome inn fordi jeg vet det er litt vanskelig å se. Så vi kompilere dette programmet som huggorm en. Så vi kan gjøre dot slash huggorm en. Gi meg et heltall, 10. Gi meg et annet heltall, 20. Summen av 10 og 20 er 30. Så vi har gjort en vellykket funksjonskall. Du kan kjøre funksjonen igjen, negative 10, er 17 summen av negative 10 og 17 7. Denne funksjonen fungerer. Det har oppførselen at vi forventer det. Og så har vi gjort en vellykket funksjon, definisjon, erklæring, og en vellykket funksjon samtale. Par diverse punkter om funksjoner før vi avslutter denne delen. Husker fra vår omtale av datatyper, tidligere, som fungerer kan noen ganger ta noen innganger. Hvis det er tilfelle, vi erklære funksjonen som å ha et tomrom argument listen. Husker du hva den vanligste funksjonen vi har sett så langt som tar et tomrom argument listen er? Det viktigste. Husker også at funksjonen noen ganger ikke egentlig har en utgang. I så fall, vi erklærer funksjonen som å ha et tomrom returtype. La oss avslutte denne delen av takle en praksis problem. Så her er problemet lagt ut. Jeg vil du skal skrive en funksjon kalt gyldig trekant. Hva denne funksjonen gjør er å ta tre reelle tall som representerer lengden av de tre sidene av en trekant som parametere, eller argumentene, eller dens inputs-- et annet sett med synonymer at du kan støte på. Denne funksjonen bør enten utgang sant eller usant avhengig av om de tre lengder er i stand til å lage en trekant. Husker du den datatypen som vi pleide å indikere sant eller usant? Nå hvordan implementerer du dette? Vel vet det er et par av reglene om trekanter som faktisk er nyttig å vite. En trekant kan bare ha sider med positiv lengde. Det er fornuftig. Du er nok å si, duh. Den andre ting å merke seg skjønt, er at summen av lengdene av alle to sider av trekanten må være større enn den lengden av den tredje side. Det er faktisk sant. Du kan ikke ha en trekant med sider 1, 2 og 4, for eksempel fordi en pluss 2 ikke er større enn fire. Så de er de reglene som bestemme hvorvidt eller ikke de tre Inngangene kan tenkes å danne en trekant. Så ta et par minutter og erklære og deretter definere Denne funksjonen kalles gyldig trekant, slik at det faktisk har atferden som er angitt her. Det vil produksjonen sant hvis disse tre sider er i stand til omfattende en trekant, og falsk ellers Klar for å se hvordan du gjorde? Her er en implementering av gyldig trekant. Det er ikke den eneste. Yours kan variere noe. Men dette gjør, faktisk, har atferd som vi forventer. Vi erklærer vår funksjon på Helt øverst, bool gyldig trekant flyte x float y float z. Så igjen, denne funksjonen tar tre reelle tall som sine argumenter, flytende punkt verdi variabler, og utganger en sann eller usann verdi, som er en boolsk, tilbakekalling. Så det er derfor returtypen er bool. Deretter definerer vi funksjonen. Første vi gjør er å sjekke for å være sikker at alle sidene er positive. Dersom x er mindre enn eller lik til 0, eller når y er lik 0, eller hvis z er mindre enn eller lik 0, som ikke kan muligens være en trekant. De har ikke positive sider. Og så kan vi gå tilbake false i den situasjonen. Neste, vi må du kontrollere at hvert par av innganger er større enn den tredje. Så hvis x pluss y er mindre enn eller lik z, eller hvis x pluss z er mindre enn eller lik y, eller hvis y pluss z er mindre enn eller lik x, som også kan være en gyldig trekant. Så vi return false igjen. Antar vi passert både av kontrollene skjønt, så vi kan returnere true. Fordi disse tre sider er i stand til returning-- for å skape en gyldig trekant. Og det er det. Du har nå erklært og definert. Og du kan være i stand til å nå bruke og kaller denne funksjonen. God jobb. Jeg er Doug Lloyd. Dette er CS50.