DAVID MALAN: Okay, velkommen tilbage. Dette er CS50. Dette er starten på uge syv. Så det har været et stykke tid, så jeg troede, vi ville tage en hurtig rundvisning, hvor vi slap, og hvor vi er nu i gang. Så dette ting her kunne have forårsaget en vis angst i første omgang. Men forhåbentlig er du begyndt at akklimatisere sig til, hvad det betegner her - stjerne repræsenterer en pointer, som er netop, hvad der i mere lægmandssprog? Så det er en adresse. Så det er adressen på noget i hukommelsen. Og vi begyndte at skrælle lagene for et par uger siden, ting som GetString og andre sådanne funktioner al denne tid har vender tilbage adresser på ting i hukommelsen, ligesom adresse for det første tegn i nogle sekvens. Så vi også indført Valgrind, som vil du begynde at bruge til dette problem indstille, især for den næste Problemet sæt samt. Og Valgrind gør hvad for os? Den kontrollerer for memory leaks, og det kontrollerer også, om misbrug af hukommelse. Det kan med en vis sandsynlighed, opdage, hvis din kode der vil berøre hukommelse at det simpelthen ikke bør. Så ikke nødvendigvis en lækage, men hvis du går ud over grænserne for nogle array, og du faktisk køre valgrind og fremkalde denne adfærd, mens Valgrind kører i dit program er kører inde i det, får du meddelelser som denne - "ugyldig skrive om str. 4 ", som, husker et par uger siden betød, at jeg havde et uheld gerne på en int for langt ud over grænserne for et array. Og så str. 4 betyder her størrelse af denne særlige int. Så tag tryghed i, at Valgrind udgang, formatet på det, er blot grusomme. Det er virkelig svært at se igennem det rod for interessante oplysninger. Så hvad vi har gjort her er bare uddrag nogle af de par mere interessante linjer. Men indser, at 80% af Valgrind s output vil være lidt af en distraktion. Bare se efter mønstre som disse - ugyldig højre, ugyldig læse, 40 bytes og nogle antallet af blokke er absolut tabt, søgeord som. Og hvad du vil forhåbentlig se en vis slags spor af hvilken funktion fejl er faktisk i. I dette tilfælde her, i hvilken linje min kode var fejlen tilsyneladende? 26 i en fil kaldet memory.c, hvilket var det eksempel, vi legede med på det tidspunkt. Så det er formentlig ikke i malloc. Det var sandsynligvis i min kode i stedet. Så vi vil se det igen og igen inden længe. Så scanf kom dette op i en par formularer hidtil. Vi så sscanf kortvarigt. Det var noget en række du dykkede ind i din forberedelserne til quizzen. Og scanf er faktisk, hvad det CS50 Biblioteket har brugt under hætte i temmelig lang tid for at få input fra brugeren. For eksempel I, hvis flytte over til CS50 Apparatet her, lad mig åbne en eksempel i dag, hedder scanf-0.c Og det er super simpelt. Det er bare et par linjer kode. Men det viser virkelig, hvor getInt har arbejdet hele denne gang. I dette program her, i linie 16 , Meddelelse om, at jeg erklærer en int. Altså ingen pejlemærker, intet magisk der, blot en int. Derefter i linie 17, beder jeg brugeren for en række, tak. Så i slutningen af ​​18, bruger jeg scanf her. Og jeg angivet, lidt ligesom printf, at jeg forventer citat citat slut procent i. Så procent i, selvfølgelig betegner en int. Men bemærk, hvad den anden argument for scanf er. Hvordan vil du beskrive den anden argument efter kommaet? Hvad er det? Det er adressen på x. Så dette er nyttigt, fordi ved at give scanf med adressen på x, hvad betyder som sætter denne funktion til at gøre? Ikke bare gå der, men også gøre hvad? Foretag en ændring til det. Fordi du kan gå der, det er en slags som et kort til en placering i hukommelsen. Og så længe du giver scanf eller enhver funktion med sådan et kort, der Funktionen kan gå der, og ikke kun se på værdien, men det kan også ændre denne værdi, som er nyttigt, hvis formålet med livet i scanf er at scanne input fra brugeren, specielt fra tastaturet. Og f betegner formateret, ligesom printf, f betegner en formateret streng, du vil udskrive. Så kort sagt, denne linje 18 siger simpelthen, forsøge at læse en int fra brugerens tastatur og gemme det inde i x, på uanset hvad adressen x sker for at leve på. Og så endelig, linje 19 bare siger, tak for int, i dette tilfælde. Så lad mig gå videre og gøre det. Så gør scanf 0. Lad mig gå videre og zoome ind Jeg vil gå og køre dette med prikker slash scanf 0. Number, please? 50.. Tak for de 50. Så det er ganske simpelt. Hvad er det nu ikke gør? Det er ikke at gøre en hel masse af fejlkontrol. For eksempel, hvis jeg ikke samarbejder og jeg kan ikke skrive i et nummer, men i stedet jeg skriver noget lignende "hej," det er bare lidt besynderligt. Og så en af ​​de ting, CS50 Biblioteket har gjort for os for nogle tid er at reprompting og reprompting. Den retry sætning tilbagekaldelse var i cs50.c, og det er grunden til, at getInt i Den CS50 biblioteket er faktisk en hel bundt af linjer lang, fordi vi er kontrol for dumme ting som dette. Har brugeren ikke give os i virkeligheden? en int Har han eller hun give os noget som en alfabetisk brev? Hvis ja, vil vi opdage det, og råber på dem. Men tingene bliver mere interessant i dette næste eksempel. Hvis jeg går til scanf-1.c, hvad er den ene ting, der er fundamentalt ændret i denne næste eksempel? Jeg bruger char *, selvfølgelig, i stedet for int. Så dette er interessant, fordi char *, husker, er egentlig bare den samme ting som streng. Så det føles som måske er dette en super simpel implementering af getString. Men jeg har skrællet tilbage laget af CS50-biblioteket, så jeg er kalde dette char * nu. Så lad os se, hvor, hvis det overalt, vi går galt. Linje 17 - Jeg atter sige, bedes du give mig noget, i dette tilfælde. en streng Og derefter i den næste linje, kalder jeg scanf, igen, giver det et format kode, men denne gang procent sek. Og så denne gang, jeg er giver det puffer. Læg nu mærke til, jeg ikke bruger -tegnet. Men hvorfor er det sandsynligvis OK her? For hvad er buffer allerede? Det er allerede en pointer. Det er allerede en adresse. Og lad os dette ord "forvirre," lad mig bare kalde det s, for eksempel til enkelhed. Men jeg har kaldt det buffer fordi generelt i programmering, hvis du har en luns af hukommelse, som en streng virkelig bare, du måske kalde det en buffer. Det er et sted at opbevare oplysningerne. Svarende til ting som YouTube, når de er buffering, så at sige, at bare betyder, at det henter bits fra internettet og gemme dem i et lokal array, en lokal klump hukommelse så at du kan se det senere uden det springer eller hængende på du under afspilning. Så der er et problem her selv, fordi jeg fortæller scanf, forventer en streng fra brugeren. Her er adressen på en luns af hukommelse. Put denne streng der. Hvorfor er der bundet giver os problemer, selvom? Hvad er det? Må jeg få adgang til at en del af hukommelsen? Du ved, jeg ikke kender. Fordi der er buffer blevet initialiseret til noget? Ikke rigtig. Og så det er hvad vi har ringet en skraldespand værdi, hvilket er ikke en formel ord. Det betyder blot, vi har ingen idé om hvad bits er indersiden af ​​fire byte, Jeg har fordelt som buffer. Jeg har ikke kaldt malloc. Jeg har absolut ikke kaldes getString. Så hvem ved hvad der rent faktisk indersiden af ​​buffer? Og alligevel fortæller scanf blindt, gå der og sætte hvad brugeren har indtastet. Så hvad er tilbøjelige til at forårsage i vores kode, hvis vi kører det? Formentlig en segfault. Måske ikke, men sandsynligvis en segfault. Og jeg siger måske ikke, fordi nogle gange du gør, nogle gange du ikke får en segfault. Nogle gange er du bare heldig, men det alligevel kommer til at være en fejl i vores program. Så lad mig gå videre og kompilere dette. Jeg har tænkt mig at gøre det på den gamle skole måde. Så klang dash 0, scanf-1, scanf-1.c, Enter. Ups, for gammel skole. Lad os se. Hvor har jeg hen? Åh, char * buffer. Åh, tak - Gem, OK - meget gamle skole. Okay, det har været et stykke tid. Så jeg har lige gemt filen efter gør, at midlertidig ændre et øjeblik siden. Og nu har jeg samlet det manuelt med Clang. Og nu vil jeg gå videre og køre scanf-1, Enter. String venligst. Jeg skrive i "hej." Og nu, her er hvor helt ærligt, printf kan er lidt irriterende. Det er faktisk ikke kommer til at segfault i dette tilfælde. Printf er lidt speciel, fordi det er så super almindeligt anvendt, at væsentlige printf gør os en tjeneste og realisere, det er ikke et gyldigt pointer. Lad mig tage det på mig selv bare at udskrive i parentes null, selv selvom det ikke er nødvendigvis, hvad vi selv havde forventet. Så vi kan ikke rigtig nemt fremkalde en segfault med dette, men det er klart det er ikke den opførsel, jeg ønskede. Så hvad er den simple løsning? Tja, i scanf-2, så lad mig foreslå, at i stedet for faktisk bare afsætte en char *, lad mig være lidt klogere dette, og lad mig allokere buffer som en sekvens af 16 tegn. Så jeg kan gøre dette i et par måder. Jeg kunne absolut bruge malloc. Men jeg kan gå tilbage til uge to, når Jeg har lige brug for en hel masse tegn. Det er bare et array. Så lad mig i stedet omdefinere buffer at være et array af 16 tegn. Og nu, når jeg passerer buffer i - og det er noget, vi ikke tale om i uge to - men du kan behandle en array som selvom det er en adresse. Teknisk set som vi har set, de er en lille smule anderledes. Men scanf vil ikke noget imod, hvis du passerer det navnet på et array, fordi det Klang vil gøre for os, er hovedsagelig behandle navnet på denne matrix som adresse luns af 16 bytes. Så dette er bedre. Det betyder nu, at jeg kan forhåbentlig du gøre følgende. Lad mig zoome ud et øjeblik og gør scanf-2, kompileret OK. Lad mig gøre fik slash scanf-2. String venligst. "Hello". Og det syntes at arbejde denne gang. Men kan nogen foreslå et scenarie hvor det måske ikke stadig arbejde? Ja? Noget længere end 16 tegn. Og faktisk kan vi være lidt mere præcis. Noget længere end 15 tegn, fordi vi virkelig har brug for at huske på at vi har brug at backslash nul implicit ved slutningen af ​​strengen, der er en mands scanf vil typisk tage sig af os. Så lad mig gøre noget lignende - Nogle gange kan vi bare overlade det sådan. OK, så vi har nu fremkaldt vores segmentering skyld. Hvorfor? Fordi jeg har skrevet til mere end 15 figurer, og så vi har faktisk rørt hukommelse, at jeg faktisk ikke burde have. Så hvad der virkelig løsningen her? Nå, hvad nu hvis vi har brug for en længere snor? Nå, vi måske gøre det 32 ​​byte. Nå, hvad nu hvis det ikke er længe nok? Hvordan omkring 64 bytes? Hvad hvis det ikke er længe nok? Hvordan omkring 128 eller 200 bytes? Hvad der virkelig er løsningen her i generelle tilfælde, hvis vi ikke kender i forhånd, hvad brugeren kommer til at skrive? Det er bare sådan en stor smerte i røven, for at være ærlig, hvilket er grunden til, CS50 bibliotek har et par dusin linjer kode, der kollektivt gennemføre GetString snor på en måde, at vi ikke nødt til at vide på forhånd, hvad brugeren kommer til at skrive. Især, hvis du ser tilbage på cs50.c fra to uger siden, vil du se at getString faktisk gør ikke bruge scanf på denne måde. Snarere det lyder ét tegn på et tidspunkt. Fordi én god ting ved læse en karakter er, vi kan garantere os til altid have mindst én char. Jeg kan bare erklære en char, og derefter tage disse virkelig baby skridt til bare læse en character ind på en tid fra tastaturet. Og så, hvad du vil se getString gør, er hver gang den løber tør for, siger 16 bytes af hukommelse, det bruger malloc eller en fætter deraf, allokere mere hukommelse, kopierer det gamle hukommelse i den nye, og så kravler sammen, at få et tegn ad gangen, og når det løber ud af det luns af hukommelse, kaster det væk, gribere en større bid af hukommelse, kopierer gamle i nye og gentagelser. Og det er virkelig en smerte til rent faktisk at gennemføre noget så simpelt som få input fra en bruger. Så du kan bruge scanf. Du kan bruge andre lignende funktioner. Og en masse lærebøger og online eksempler gør, men de er alle sårbare over for problemer som dette. Og i sidste ende, at få en segfault er slags irriterende. Det er ikke godt for brugeren. Men i værste fald gør hvad det fundamentalt sætte din kode med risiko for? En slags angreb, potentielt. Vi talte om en sådan angreb - overfyldte stakken. Men generelt, hvis du får lov til at overflow en buffer, ligesom vi gjorde en par uger siden, med blot at skrive mere end "hej" på stakken, du kan faktisk tage over et potentielt computer, eller i det mindste komme på data, ikke tilhører dig. Så kort, er det derfor, vi har disse støttehjul. Men nu begynder vi at tage dem af, som vores programmer ikke længere har brug for, nødvendigvis, input fra brugeren. Men i tilfælde af problemet sæt seks, dit input kommer fra en enorm ordbog fil med 150 nogle ulige tusind ord. Så du behøver ikke at bekymre sig om brugerens vilkårlige input. Vi vil give dig nogle antagelser om den pågældende fil. Eventuelle spørgsmål vedrørende pointers eller scanf eller input fra brugeren i almindelighed? Okay, så et hurtigt kig derefter på en efterstillede emne fra to uger siden. Og det var denne forestilling om en struct. Ikke at - det begrebet struct, hvilket var, hvad? Hvad gjorde struct gøre for os? Definer - ked af det? Definer en variabel type. Så sortere i. Vi er faktisk kombinere to emner. Så med typedef, minde om, at vi kan erklære en type af vores egne, ligesom en synonym ligesom streng for char *. Men ved hjælp af typedef og struct, kan vi skabe virkelig vores egne datastrukturer. For eksempel ind, hvis jeg gå tilbage gedit her for blot et øjeblik, og jeg går videre og gøre noget lignende, så lad mig spare dette som, lad os sige, structs.c midlertidigt, jeg bare at gå videre og medtage standardio.h, int main tomrum. Og så her antage, at jeg vil at skrive et program, der gemmer flere studerende fra flere huse, f.eks. Så det er ligesom en registrarial database af en slags. Så hvis jeg har brug for navnet én studerende, jeg kunne gøre noget lignende char * navn, og jeg vil gøre noget lignende - faktisk, lad os bruge CS50 biblioteket for bare et øjeblik at gøre dette til en lidt enklere, så vi kan låne dem dusinvis af linjer kode. Og lad os bare holde det simpelt. Vi vil holde det streng, og nu getString. Så jeg hævder nu, at jeg har gemt navnet for nogle studerende, og huset af nogle studerende, blot at bruge variabler ligesom vi gjorde og i uge et. Men formoder jeg nu ønsker at understøtte flere studerende. Okay, så mine instinkter er at gøre string name2, får getString, string house2 får getString. Og så vores tredje elev, lad os gøre NAME3 getString. Okay, så det er forhåbentlig slående dig som en slags dum, fordi denne proces virkelig aldrig er kommer til at ende, og det er bare at gøre min kode se værre og værre og værre. Men vi løst dette også i uge to. Hvad var vores relativt rene løsning når vi havde flere variabler i samme datatype, der alle er relateret, men vi ikke ønsker, at denne grusomme rod af tilsvarende navngivne variabler? Hvad gjorde vi i stedet? Så jeg tror jeg hørte et par steder. Vi havde en matrix. Hvis du vil have flere forekomster af noget, hvorfor vi ikke rense det hele op og bare sige, giv mig vifte kaldet navne? Og for nu, lad os hårdt kode 3.. Og derefter give mig en anden matrix kaldet huse, og lad mig for nu hårdt kode 3.. Og jeg har massivt ryddet op i rod, at jeg lige har oprettet. Nu har jeg stadig svært kodet 3, men selv 3 kunne dynamisk komme fra bruger, eller argv eller lignende. Så dette er allerede renere. Men hvad er irriterende ved dette er, at nu, selv om et navn eller anden måde fundamentalt knyttet til en studerendes hus - Det er en studerende, som jeg virkelig ønsker at repræsentere - Jeg har nu to arrays, der er parallelle i den forstand at de er de samme størrelse og navne beslag 0 formentlig kort til huse beslag 0, og navne Bracket 1 maps til huse beslag 1. Med andre ord, liv, studerende i det hus, og at anden elev bor i det andet hus. Men sikkert det kunne være gøres endnu mere rent. Tja, det kan, i virkeligheden. Og lad mig gå videre og åbne up structs.h, og du vil se denne idé her. Bemærk, at jeg har brugt typedef, som du hentydede til for et øjeblik siden at erklære vores egen datatype. Men jeg bruger også dette andet søgeord kaldet struct som giver mig en ny datastruktur. Og dette datastruktur Jeg hævder går at have to ting indersiden af det - en streng kaldet navn, og en streng kaldet hus. Og det navn, jeg har tænkt mig at give til dette datastruktur går at blive kaldt elev. Jeg kunne kalde det noget, jeg vil, men dette semantisk gøre mening for mig i mit sind. Så nu, hvis jeg åbner en bedre version af det program, jeg begyndte at skrive der, lad mig rulle til toppen. Og der er nogle flere linjer kode her, men lad mig fokusere for øjeblikket på én. Jeg har erklæret en konstant kaldet studerende og hårdt kodet 3 for nu. Men nu mærke til, hvordan ren min kode begynder at få. På linje 22, erklærer jeg vifte af studerende. Og læg mærke til, at studerende er tilsyneladende nu er en datatype. Fordi i toppen af ​​denne fil, mærke Jeg har medtaget denne header fil at jeg trak op bare for et øjeblik siden. Og det header fil simpelthen havde denne definition af en studerende. Så nu har jeg oprettet mine egne brugerdefinerede data typen, at forfatterne af C-år siden ikke tænke på i forvejen. Men ikke noget problem. Jeg kan gøre det selv. Så dette er en matrix kaldes studerende hver af hvis medlemmer er studerende struktur. Og jeg vil have tre af disse i array. Og nu, hvad gør resten af dette program gøre? Jeg havde brug for noget lidt vilkårlig. Så fra online 24 og fremefter, Jeg gentage fra 0 til 3. Jeg derefter bede brugeren om elevens navn. Og så har jeg bruger getString som før. Så jeg beder om den studerendes hus, og jeg bruger getString som før. Men varsel - lidt nyt stykke syntaks - Jeg kan stadig indeks til i'te student, men hvordan får jeg på specifikke data felt inde i struct? Jamen, hvad er tilsyneladende nyt stykke syntaks? Det er bare dot operatør. Vi har ikke rigtig set det før. Du har set det i Pset fem, hvis du har investerer allerede med bitmap-filer. Men prik betyder bare på indersiden af ​​dette struct eller flere felter, giver dot navn, eller give mig dot hus. Det betyder gå inde i struct og få disse særlige områder. Hvad resten af ​​dette program gøre? Det er ikke alle, der sexet. Bemærk, at jeg gentage fra 0 til 3 igen, og jeg blot oprette en engelsk sætning som så og så er i en sådan, og et sådant hus, der passerer i dot navn fra det i'te studerende og deres huset så godt. Og så endelig, nu skal vi begynde at få anal om dette, nu hvor vi er fortrolig med, hvad malloc og andre funktioner har været gør alt dette tidspunkt. Hvorfor skal jeg nødt til at frigøre både navn og hus, selvom jeg ikke kalde malloc? GetString gjorde. Og det var beskidte lille hemmelighed for flere uger, men getString har været utætte hukommelse hele placere alle semester hidtil. Og Valgrand vil endelig afsløre dette til os. Men det er ikke en big deal, fordi jeg kender at jeg simpelthen kan frigøre navnet og huset, men teknisk, være super, super sikker, bør jeg være laver nogle fejlkontrol her. Hvad er dine instinkter fortæller dig? Hvad skal jeg være kontrol for før jeg frigøre hvad er en string, alias som en char *? Jeg skal virkelig være kontrol, hvis de studerende beslag i dot navn ikke lige null. Så det vil være OK at gå videre og fri denne pegepind, og samme eller anden en så godt. Hvis eleverne beslag jeg dot hus ikke er svarende til null, det nu vil beskytte mod hjørnet tilfælde, hvor GetString returnerer noget som null. Og vi så et øjeblik siden, printf vil beskytte os op her ved blot at sige null, som er kommer til at se underligt. Men i det mindste vil det ikke segfault, som vi har set. Nå, lad mig gøre en anden ting her. structs-0 er lidt af en dum program fordi jeg indtaste alle disse data, og derefter det er tabt, når programmet slutter. Men lad mig gå videre og gøre det. Lad mig gøre terminalen Vinduet lidt større. Lad mig gøre structs-1, som er en ny version af denne. Jeg zoome ind en lille smule. Og lad mig nu køre dot slash structs -1. Studerendes navn - David Mather, lad os gøre Rob Kirkland, lad os gøre Lauren Leverett. Det interessante er nu varsel - og jeg kender kun dette, fordi Jeg skrev programmet - der er en fil nu på min nuværende mappe kaldet students.csv. Nogle af jer har måske set disse i den virkelige verden. Hvad er en CSV-fil? Kommasepareret værdier. Det er lidt ligesom en fattig mands version af en Excel-fil. Det er en tabel over rækker og kolonner, du kan åbne i et program som Excel, eller tal på en Mac. Og hvis jeg åbner denne fil her på gedit, varsel - og tallene er der ikke. Det er bare gedit fortælle mig linjenumre. Meddelelse om den første linje i denne fil er David og Mather. Den næste linie er Rob komma Kirkland. Og den tredje linje er Lauren komma Leverett. Så hvad har jeg lavet? Jeg har nu skrevet et C-program, der effektivt kan generere regneark der kan åbnes i en program som Excel. Ikke alt, overbevisende et datasæt, men hvis du har meget større bidder af data, som du rent faktisk ønsker at manipulere og gøre grafer i og gerne, det er måske en måde at skabe disse data. Desuden CSVs er faktisk super fælles bare til opbevaring simple data - Yahoo Finance, for eksempel, hvis du får aktiekurser via deres såkaldte API, den gratis service, der lader dig få strøm up-to-the-date lager citater for virksomhederne, at de giver dataene tilbage i super enkel CSV-format. Så hvordan har vi det? Nå mærke, de fleste af programmets næsten den samme. Men bemærk hernede, snarere end print de studerende ud, på linie 35 fremefter, jeg hævder, at jeg gemmer studerende til disk, så gemmer en fil. Så opdager jeg erklære en fil * - nu det er lidt af en anomali i C. Uanset årsagen, er FIL alle caps, som ikke er som de fleste andre datatyper i C. Men det er en indbygget datatype, FILE *. Og jeg erklære en pointer til en fil, er, hvordan du kan tænke på det. fopen betyder åben fil. Hvilken fil du ønsker at åbne? Jeg ønsker at åbne en fil, som jeg vil vilkårligt kalder students.csv. Jeg kunne kalde det hvad jeg vil. Og derefter tage et gæt. Hvad det andet argument til fopen formentlig betyde? Right, w for write, kunne være r for læsning. Der er en for append hvis du ønsker at tilføje rækker og ikke overskrive det hele. Men jeg ønsker blot at oprette denne fil én gang, så jeg vil bruge citat citat slut w. Og jeg ved, at kun fra at have læst dokumentationen eller manden siden. Hvis filen ikke er nul - med andre ord, Hvis intet gik galt - lad mig gentage over for studerende fra 0 til 3. Og nu mærke til at der er noget nogensinde så lidt anderledes om linje 41 her. Det er ikke printf. Det er fprintf til fil-printf. Så det kommer til at skrive til filen. Hvilken fil? Den ene, hvis pointer du angiver som det første argument. Så kan vi angive et format streng. Så kan vi angive, hvilken snor, vi ønsker at plug in for første procent s, og derefter en anden variabel eller den anden procent sek. Så vi lukker filen med fclose. End jeg frigøre hukommelse som før, selv om Jeg skulle gå tilbage og tilføje nogle kontroller for null. Og det er det. fopen, fprintf, fclose giver mig evne til at skabe tekstfiler. Nu vil du se i opgavesæt fem, som involverer billeder, du skal bruge binære filer i stedet. Men fundamentalt, ideen er den samme, selvom de funktioner, du se er en lille smule anderledes. Så hvirvelvind tur, men du vil få alt for bekendt med filen I/O-- indgang og udgang - med Pset fem. Og eventuelle spørgsmål om indledende grundlæggende her? Ja? Hvad hvis du forsøger at frigøre en null værdi? Jeg tror, ​​med mindre fri har fået et lidt mere brugervenlig, kan du potentielt segfault. Passing det null er dårligt, fordi jeg ikke gør tror fri generer at tjekke for dig, fordi det potentielt ville være et spild af tid for det at gøre sig selv til alle i verden. Godt spørgsmål, selv om. Okay, så denne form for får os til et interessant emne. Temaet for problemet sæt fem er retsvidenskab. Mindst det er en del af problemet sættet. Retsvidenskab generelt refererer til inddrivelse af oplysninger, der kan eller måske ikke er blevet slettet bevidst. Og så tænkte jeg ville give dig en hurtig forsmag på, hvad der virkelig foregår hele denne gang under kølerhjelmen af ​​din computer. For eksempel af, hvis du har inde i din bærbare eller din stationære computer en harddisk, er det enten en mekanisk enhed, der faktisk spins - der er cirkulære ting kaldet fade der ser helt lide, hvad jeg lige haft op på skærmen her, selvom det i stigende grad gamle skole. Dette er en tre-og-en-halv-tomme harddisk. Og tre og en halv inches refererer til med den ting, når du installerer det i en computer. Mange af jer fyre i din bærbare nu har solid state-drev, eller SSD'er, som ikke har nogen bevægelige dele. De er mere som RAM og mindre som disse mekaniske anordninger. Men ideerne er stadig de samme, sikkert, som de vedrører til problemet sæt fem. Og hvis du tænker over nu en harddisk repræsenterer være en cirkel, som Jeg vil tegne som dette her. Når du opretter en fil på din computer, om det er en SSD, eller dette tilfælde en ældre skole harddisk, filen indeholder flere bits. Lad os sige, at det er denne 0 og 1, en hel masse 0'er og 1-taller. Så dette er mit hele harddisken. Det er tilsyneladende en temmelig stor fil. Og det er ved hjælp op 0'er og 1-taller på det del af den fysiske plade. Nå, hvad er det fysiske del? Tja, det viser sig, at på en harddisk, mindst af denne type, er der disse bittesmå magnetiske partikler. Og de har i det væsentlige mod nord og sydpoler til dem, så at hvis du vende en af ​​disse magnetiske partikler denne måde, kan man sige, at det er repræsenterer en 1. Og hvis det er hovedet syd til nord, kan man sige, at det er repræsenterer et 0. Så i den virkelige fysiske verden, er der hvordan du kan repræsentere noget i binær tilstand 0 og 1. Så det hele er en fil er. Der er en hel flok af magnetisk partikler, som er deres denne måde eller På denne måde skaber mønstre af 0'er og 1-taller. Men det viser sig, når du gemmer en fil, nogle oplysninger gemmes separat. Så dette er en lille tabel, en mappe, så at sige. Og jeg vil kalde denne kolonne navn, og Jeg ringer denne kolonne placering. Og jeg har tænkt mig at sige, formoder dette er mit CV. Min resume.doc opbevares ved placering, lad os sige 123. Jeg går altid efter det nummer. Men er det tilstrækkeligt at sige, at ligesom i RAM, kan du tage en harddisk Det er en gigabyte eller 200 gigabyte eller en terabyte, og du kan antal alle bytes. Du kan tælle alle bidder af 8 bit. Så vi vil sige, at dette er placering 123.. Så denne mappe inde i mit operativsystem Systemet husker, at min cv er på location 123. Men det bliver interessant, når du sletter en fil. Så for eksempel - og heldigvis, det meste af verden har fanget på det - hvad der sker, når du trækker en fil til din Mac OS Trash eller din Windows-papirkurven? Hvad er formålet med at gøre det? Det er selvfølgelig for at slippe af filen, men hvad betyder den handling at trække og slippe ind i din papirkurv eller din Papirkurven gøre på en computer? Absolut intet, virkelig. Det er ligesom en mappe. Det er en særlig mappe, for at være sikker. Men betyder det egentlig slette filen? Nå, nej, fordi nogle af jer sikkert have været ligesom, oh damn, du gjorde ikke betyder at gøre det. Så du dobbeltklikke på Papirkurv eller papirkurven. Du har prikkede rundt og du har genvundet filen ved blot at trække det ud derfra. Så klart, det er ikke nødvendigvis at slette det. OK, du er klogere end som så. Du ved, at bare trække det ind i Papirkurv eller papirkurven betyder ikke du tømme papirkurven. Så du gå op til menuen, og du siger Tøm papirkurv eller Tøm papirkurv. Så hvad sker der? Yeah, så det er slettet mere så. Men alt det der sker, er dette. Computeren glemmer hvor resume.doc var. Men hvad har ikke ændret sig tilsyneladende i billedet? De bits, den 0'er og 1-taller, som jeg hævder er på stedet for nogle fysiske aspekt af hardware. De er der stadig. Det er bare at computeren har glemt, hvad de er. Så det er hovedsageligt befriet filens bits, således at de kan genbruges. Men ikke før du oprette flere filer, og flere filer, og flere filer probabilistisk dem, 0'er og 1-taller, disse magnetiske partikler, bliver genbrugt, upside eller højre side op, for andre filer, 0'er og 1'ere. Så du har dette vindue af tid. Og det er ikke forudsigelig længde, rigtig. Det afhænger af størrelsen på din harddisk drev og hvor mange filer du har, og hvor hurtigt du gøre nye. Men der er dette vindue af tid i løbet af som denne fil er stadig helt erstattes. Så hvis du nogensinde bruge programmer som McAfee eller Norton for at forsøge at inddrive data, er alt de laver forsøger at genvinde denne såkaldte mappe til regne ud, hvor din fil var. Og nogle gange Norton og vil sige, fil er 93% erstattes. Nå, hvad betyder det? Det betyder blot, at en anden fil tilfældigvis endte med at bruge, siger, disse bits ud af din oprindelige fil. Så hvad der rent faktisk er involveret i at inddrive data? Tja, hvis du ikke har noget som Norton pre-installeret på din computer, det bedste du kan sommetider gøre er at kigge på hele harddisken søger bitmønstre. Og en af ​​de temaer, opgavesæt fem er, at du vil søge på svarer til en harddisk, en retsmedicinsk billede af en compact flash kort fra en digitalt kamera, søger efter den 0'er og 1s der typisk med høj sandsynlighed, repræsenterer starten af ​​et JPEG-billede. Og du fyre kan genvinde disse billeder ved antager, hvis jeg ser dette mønster af bits på retsmedicinske billede, med høj sandsynlighed, der markerer starten på en JPEG. Og hvis jeg ser det samme mønster igen, som formentlig markerer starten på anden JPEG og anden JPEG og anden JPEG. Og det er typisk, hvordan data recovery vil arbejde. Hvad er rart om JPEG er, selvom filformat selv er noget komplekse, i begyndelsen af ​​hvert sådant fil er faktisk temmelig identificerbare og enkle, som du vil se, hvis du ikke allerede har. Så lad os tage et nærmere kig nedenunder hætten, præcis hvad der har været foregår, og hvad disse 0'er og 1-taller er, for at give dig en smule mere af en Baggrunden for denne særlige udfordring. [VIDEO AFSPIL] -Hvor din pc gemmer de fleste af dens permanente data. At gøre det, at dataene rejser fra RAM sammen med software-signaler, der fortæller harddisken, hvordan man opbevarer disse data. Harddisken kredsløb oversætte disse signaler til spænding udsving. Disse, til gengæld, styre harddiskens bevægelige dele, nogle af de få bevægelige dele tilbage i moderne computer. Nogle af signaler til styring af en motor der spinder metal-belagte plader. Dine data er faktisk gemt på disse plader. Andre signaler flytte læse / skrive hoveder til at læse eller skrive data på pladerne. Denne maskine så præcise, at et menneske hår kunne ikke engang passere mellem hoveder og spinning fade. Men det hele virker på forrygende hastigheder. [END VIDEOAFSPILNING] DAVID MALAN: Zoom i en lille dybere nu på, hvad der er faktisk på disse fade. [VIDEO AFSPIL] -Lad os se på, hvad vi lige så i slowmotion. Når en kort puls af elektricitet er sendt til læse / skrive hovedet, hvis flips på en lille elektromagnetisk til en brøkdel af et sekund. Magneten skaber et område, som ændrer polaritet en lille, lille del af metalpartikler, der coat hver fad overflade. Et mønster serie af disse små, opladet bebyggelse på disken repræsenterer en enkelt bit af data i det binære tal system, der anvendes af computere. Nu, hvis strøm sendes én måde gennem læse / skrive hoved, området er polariseret i én retning. Hvis strøm sendes i modsatte retning, den polarisering vendes. Hvordan du får data fra harddisken? Bare vende processen. Så det er partiklerne på disken der får strømmen i læse / skrive hovedet bevæger sig. Sammensæt millioner af disse magnetiseret segmenter, og du har fået en fil. Nu er de stykker af en enkelt fil kan være spredt over en drevets fade, lidt ligesom det rod af papirer på dit skrivebord. Så en ekstra fil registrer hvor alt er. Må ikke du ønsker du havde sådan noget? [END VIDEOAFSPILNING] DAVID MALAN: OK, sandsynligvis ikke. Så hvor mange af jer voksede op med disse? OK, så det er færre og færre hænder hvert år. Men jeg er glad for du er det mindste kender med dem, fordi dette og vores egne bog demo desværre er ved at dø en meget langsom død her af fortrolighed. Men dette er hvad jeg i det mindste tilbage i high school, brugte brug for backup. Og det var fantastisk, fordi du kunne gemme 1.4 megabyte på denne bestemte disk. Og dette var den høje tæthed versionen, som angivet af HD, der har betyder før dagens HD-videoer. Standard tæthed var 800 kilobyte. Og før det var der 400 kilobyte diske. Og før det var der 5 og 1/4 tommer diske, som var virkelig diskette, og lidt bredere og højere end disse ting her. Men du kan faktisk se den såkaldte floppy aspekt af disse diske. Og funktionelt, de er faktisk temmelig ligner harddiske på mindst denne type. Igen, SSD'er i nyere computere arbejde lidt anderledes. Men hvis du flytter den lille metal fanen kan du faktisk se en lille cookie, eller fad. Det er ikke metal som denne. Denne ene er faktisk nogle billigere plastmateriale. Og du kan slags vrikke det. Og du har trully lige tørres nogle antallet af bits eller magnetiske partikler fra denne disk. Så heldigvis, der er intet på det. Hvis den ting der er i vejen - og dække dine øjne og jeres nabo - kan du bare slags trække dette Hele kappe off sådan. Men der er en lille fjeder, så vær opmærksom på, at med dine øjne. Så nu har du virkelig en diskette. Og hvad er bemærkelsesværdigt ved denne er, at i så meget som dette er et mindre repræsentation af et større harddisk, disse ting er super, super enkel. Hvis du knibe bunden af ​​det nu, at metal ting er slukket, og skræl dem åbne, alle der er, er to stykker filt og den såkaldte diskette med et stykke metal på indersiden. Og der går halvdelen af min disk indhold. Der går en anden halvdelen af ​​dem. Men det er alt, der var spinning inde af din computer på gårsdagens. Og igen, for at sætte dette i perspektiv, hvor stor er de fleste af dine harddiske i disse dage? 500 gigabyte, en terabyte, måske i en stationær computer, 2 terabyte, 3 terabytes, 4 terabytes, right? Dette er en megabyte, give eller tage, der kan ikke engang passe en typisk MP3 længere disse dage, eller nogle lignende musikfil. Så en lille souvenir til dig i dag, og også for at hjælpe kontekstualisere, hvad vi vil tage for givet nu problem sæt fem. Så dem er dine til at holde. Så lad mig overgangen til hvor vil være tilbringe den næste Pset så godt. Så vi har nu sat denne side til - oh, et par meddelelser hurtigt. Denne fredag, hvis du gerne vil deltage i CS50 til frokost, gå til det sædvanlige, cs50.net/rsvp. Og afgangsprojekt - så per pensum, vi har sendt den afgangsprojekt specifikation allerede. Indse, at det ikke betyder det er på grund særligt snart. Det er udstationeret, virkelig, bare for at få du fyre tænker over det. Og ja, en super betydelig procentdel af du vil tackle afgangsprojekter på materiale, som vi har ikke engang fået i klassen, men vil så tidligt som i næste uge. Bemærk dog, at spec opfordrer til et par forskellige komponenter i afgangsprojekt. Den første, i et par uger, er en foreløbige forslag, en temmelig afslappet e-mail til din TF at fortælle ham, eller hvad du er tænker til dit projekt, med Ingen Commitment. Forslaget vil være din særlige engagement, sagde her, dette er hvad Jeg vil gerne gøre for mit projekt. Hvad mener du? Too big? For lille? Er det overskueligt? Og du kan se spec for flere detaljer. Par uger efter det er status rapport, der er et tilsvarende afslappet e-mail til din TF til at sige lige hvordan langt bagud du er i din endelige projektets gennemførelse, efterfulgt af Den CS50 hackathon som alle er inviteret, som vil være en begivenhed fra 20:00 på en aften indtil 07:00 AM næste morgen. Pizza, som jeg måske har nævnt i uge nul, skal wil serveres på 9:00 PM, Kinesisk mad på 1:00 AM. Og hvis du stadig vågen på 5:00 AM, Vi vil tage dig til IHOP til morgenmad. Så hackathon er en af ​​de mere mindeværdige oplevelser i klassen. Derefter gennemførelse skyldes, og derefter klimaks CS50 Fair. Flere detaljer om alle disse i de kommende uger. Men lad os gå tilbage til noget gamle skole - igen, et array. Så et array var rart, fordi det løser problemer som vi så bare en øjeblik siden med studerende strukturer få lidt ud af kontrol, hvis vi ønsker at have studerende en, student to, student tre, student dot dot dot, nogle vilkårligt antal studerende. Så arrays, et par uger siden slog i og løst alle vores problemer af ikke vide på forhånd, hvor mange ting af nogle type vi måske ønsker. Og vi har set, at structs kan hjælpe os yderligere at organisere vores kode og holde begrebsmæssigt lignende variabler, som en navn og et hus, sammen, så vi kan behandle dem som én enhed, indvendig hvoraf der er mindre stykker. Men arrays har nogle ulemper. Hvad er nogle af de ulemper Vi er stødt på med arrays hidtil? Hvad er det? Fast størrelse - så selvom du måske være i stand til at afsætte hukommelse til en array, når du ved, hvor mange studerende du har, hvor mange tegn du har fra brugeren, du engang har afsat array, har du slags malet selv ind i et hjørne. Fordi du ikke kan indsætte nye elementer i midten af ​​et array. Du kan ikke indsætte flere elementer ved slutningen af ​​et array. Virkelig, er du nødt til at ty til at skabe et helt ny array, som vi har diskuteret, kopierer det gamle til den nye. Og igen, det er hovedpine, GetString tilbud med for dig. Men igen, kan du ikke engang indsætte noget ind i midten af ​​array hvis satsen ikke er helt fyldt. For eksempel, på hvis dette array her størrelse seks har kun fem ting i det, godt, du bare kunne tack noget på enden. Men hvad nu hvis du ønsker at indsætte noget i midten af matrix, selvom det kan have fem ud af seks ting i det? Nå, hvad gjorde vi gør, når vi havde alle af vores frivillige på scenen i uger tidligere? Hvis vi ønskede at sætte nogen her, hverken disse folk, hvordan at flytte denne måde eller disse mennesker, hvordan man flytte denne måde, og det blev dyrt. Flytning af mennesker inde i en matrix endte med at tilføje op og koster os tiden, og dermed masse af vores n kvadreret kører tider som indsættelse sortere, for eksempel, i værste fald. Så arrays er store, men du er nødt til vide på forhånd, hvor stor du vil have dem. Så OK, her er en løsning. Hvis jeg ikke vide på forhånd, hvor mange elever, jeg måtte have, og jeg ved engang Jeg beslutter, selvom, jeg sidder med, at mange studerende, hvorfor jeg ikke bare altid tildele dobbelt så meget plads som jeg tror måske jeg har brug for? Er det ikke en fornuftig løsning? Realistisk set tror jeg ikke, at vi er vil få brug for mere end 50 slots i et array for en medium størrelse klasse, så lad os bare runde op. Jeg vil gøre 100 slots i min array, bare så vi kan helt sikkert få den Antallet af elever, jeg forventer at være i en mellemstor klasse. Så hvorfor ikke bare runde op og tildele mere hukommelse, typisk for et array end du tror, ​​du måske endda brug for? Hvad er denne enkle pushback til denne idé? Du er bare spilder hukommelse. Bogstaveligt talt hver program, du skriver så er måske ved hjælp dobbelt så meget hukommelse som du faktisk har brug for. Og der bare ikke føler sig som en særligt elegant løsning. Desuden er det blot nedsætter sandsynligheden for et problem. Hvis du tilfældigvis har en populær kursus et semester, og du har 101 studerende dit program er stadig fundamentalt står over for samme problem. Så heldigvis er der en løsning på Denne annonce alle vores problemer i form af datastrukturer, der er mere komplekse end dem vi har set hidtil. Det jeg hævder, er en sammenkædet liste. Dette er en liste over numre - 9, 17, 22, 26 og 34 - der er blevet kædet sammen ved hjælp af, hvad jeg har tegnet som pile. Med andre ord, jeg hvis ønsket at repræsentere et array, kunne jeg gøre noget som dette. Og jeg vil sætte dette over hovedhøjde på bare et øjeblik. Jeg kunne gøre - hej, okay. Standby. Ny computer her, klar - okay. Så hvis jeg har disse numre i array - 9, 17, 22, 26, 24 - ikke nødvendigvis at skalere. Okay, så her er mit array - Åh min Gud. Okay, så her er mit array. Åh min Gud. [Latter] DAVID MALAN: Pretend. Det er for besværligt at gå tilbage og ordne det, så der - 26.. Så vi har denne vifte af 9, 17, 22, 26, og 34.. For dem af jer kan se pinligt fejl jeg lige lavet, der er det. Så jeg hævder, at dette er en meget effektiv løsning. Jeg har afsat så mange ints som Jeg har brug for - en, to, tre, fire, fem eller seks - og jeg har derefter lagret tallene indersiden af ​​dette array. Men formoder, så jeg ønsker at indsætte en værdi som nummer 8? Tja, hvor det gå? Antag jeg ønsker at indsætte et nummer ligesom 20. Tja, hvor det gå? Et eller andet sted er der i midten, eller antallet 35 har til at gå sted ved udgangen. Men jeg er alt ud af rummet. Og så dette er en grundlæggende udfordring af arrays, der ikke er løsningen. Jeg påstod for et øjeblik siden, getString løser dette problem. Hvis du ønsker at indsætte en sjette nummer i dette array, er det mindst én løsning, du kan falde tilbage på sikker, ligesom vi gør med getString? Hvad er det? Nå, gøre det større er lettere sagt end gjort. Vi kan ikke nødvendigvis gøre array større, men hvad kan vi gøre? Lav et nyt array, der er større, størrelse 6, eller måske størrelse 10, hvis vi ønsker at komme foran på tingene, og derefter kopiere den gamle array i den nye, og derefter frigøre den gamle array. Men hvad er den løbende tid nu i denne proces? Det er stort O n, fordi kopieringen kommer til at koste dig nogle enheder af tid, så ikke så ideel, hvis vi er nødt til tildele en ny matrix, som vil at forbruge dobbelt så meget hukommelse midlertidigt. Kopier gammelt til nyt - Jeg mener, det er bare en hovedpine, som er, igen, hvorfor vi skrev GetString for dig. Så hvad kunne vi gøre i stedet? Nå, hvad hvis vores datastruktur har faktisk huller i det? Antag, at jeg slap mit mål om at have sammenhængende bidder af hukommelsen, hvor 9 er lige ved siden af ​​til 17, hvilket er ret ud til 22, og så videre. Og formoder, at 9 kan være herovre i RAM og 17 kan herovre i RAM, og 22 kan herovre i RAM. Med andre ord, jeg ikke har brug for dem selv tilbage til tilbage længere. Jeg har bare en eller anden måde tråd en nål gennem hver af disse numre, eller hver af disse knudepunkter, vi som ringer efter rektangler, som jeg har trukket dem til huske, hvordan man kommer til den sidste sådan node fra den første. Så hvad er det programmeringssprog konstruere vi har set for nylig, som jeg kan gennemføre denne tråd, eller trukket her, som jeg kan gennemføre disse pile? Så pointere, right? Hvis jeg ikke allokere bare en int, men en node - og ved node, jeg bare mener container. Og visuelt, mener jeg et rektangel. Så en knude tilsyneladende behov at indeholde to værdier - int selv, og så, som indikeret den nederste halvdel af rektanglet, nok plads til en int. Så bare tænke fremad her hvor stor er dette knudepunkt, dette container i spørgsmål? Hvor mange byte for int? Formentlig 4, hvis det er den samme som sædvanlig. Og så hvor mange bytes for pointeren? 4.. Så denne beholder eller dette knudepunkt, er vil være en 8-byte struktur. Åh, og det er en glad tilfældighed, at vi bare indført denne forestilling om en struct, eller en C-struktur. Så jeg påstå, at jeg ønsker at tage et skridt mod dette mere sofistikerede gennemførelse af en liste af tal, et knyttet liste over numre, jeg har brug for at gøre en lidt mere at tænke op foran og erklære ikke bare en int, men en struct at jeg ringer, konventionelt her, node. Vi kunne kalde det noget, vi ønsker, men node bliver tematisk i en masse af de ting, vi begynder at se på nu. Inde i denne node er en int n. Og så denne syntaks, lidt underligt ved første øjekast - struct node * næste. Nå billedligt, hvad er det? Det er den nederste halvdel af rektanglet, som vi oplevede bare for et øjeblik siden. Men hvorfor siger jeg struct node * i modsætning til blot node *? For hvis denne pegepind peger på en anden node, er det bare adresse af en knude. Det er i overensstemmelse med, hvad vi har diskuterede pointers hidtil. Men hvorfor, hvis jeg hævder denne struktur er kaldet node, behøver jeg sige struct node herinde? Præcis. Det er en slags en dum virkelighed C. Den typedef, så at sige, har ikke sket endnu. C er super bogstavelig. Den læser din kode top til bund, venstre mod højre. Og indtil den rammer at semikolon på bundlinjen, gæt hvad der ikke eksistere som en datatype? Node, citat citat slut node. Men på grund af den mere detaljeret erklæring jeg gjorde på den første linje - typedef struct node - fordi der kom først, før krøllede parenteser, det er lidt ligesom pre-uddanne Clang det, du hvad, giv mig et struct kaldet struct node. Helt ærligt, jeg kan ikke lide kalde tingene struct node, struct node alle hele min kode. Men jeg vil kun bruge det én gang, lige inden, så jeg kan effektivt skabe en slags cirkulær reference, ikke en pointer til mig selv, men en pointer til en anden af samme type. Så det viser sig, at der på en datastruktur som dette, er der et par operationer, der kan være af interesse for os. Vi måske ønsker at indsætte ind i en liste som denne. Vi vil måske slette fra en liste som denne. Vi vil måske søge listen for en værdi, eller mere generelt, travers. Og traverse er bare en fancy måde siger starter til venstre og flytte alle vejen til højre. Og meddelelse, selv med denne lidt mere sofistikerede datastruktur, lad mig foreslår, at vi kan låne nogle af ideerne i de seneste to uger og gennemføre en funktion kaldet søge som dette. Det kommer til at returnere true eller falsk, hvilket indikerer, ja eller nej, n er på listen. Sit andet argument er en pointer til selve listen, så en pointer til et knudepunkt. Alt jeg har tænkt mig at så gøre, er at erklære en midlertidig variabel. Vi kalder det ptr af konventionen, for pointer. Og jeg tildele det lig med den begyndelsen af ​​listen. Og nu mærke til, mens du løkken. Så længe pointer ikke er lig til null, jeg kommer til at kontrollere. Er Markørpilen n lig med n, der blev vedtaget i? Og vent et øjeblik - ny stykke syntaks. Hvad er pil pludselig? Ja? Præcis. Så mens nogle få minutter siden, brugte vi dot notation adgang noget indersiden af ​​en struct, hvis variablen har du er ikke den struct sig selv, men en pointer til en struct, heldigvis et stykke syntaks, endelig gør intuitiv fornemmelse. Pilen betyder at følge markøren, ligesom vores pile typisk betyder billedligt, og går på datafelt indeni. Så pilen er den samme som prik, men du bruge det, når du har en pointer. Så bare for at opsummere så, hvis n feltet indersiden af ​​struct kaldet markøren lig lig n, returnere sandt. Ellers er dette linje her - pointer lig pointer næste. Så hvad det gør, varsel, er, hvis jeg er i øjeblikket peger på struct indeholdende 9, og 9 er ikke antallet Jeg leder efter - formoder jeg leder for n lig 50 - Jeg har tænkt mig at opdatere min midlertidige pointer for ikke at pege på dette knudepunkt længere, men Markørpilen næste, som kommer til at sætte mig op her. Nu indså jeg er en hvirvelvind introduktion. På onsdag vil vi faktisk gøre dette med nogle mennesker og med nogle mere kode i et langsommere tempo. Men indse, vi nu gør vores data strukturer mere kompleks, så vores algoritmer kan få mere effektiv, hvilket vil være nødvendige for Pset seks, når vi lægger i, igen, de 150.000 ord, men er nødt til at gøre det effektivt, og ideelt set, at skabe en program, der kører for vores brugere ikke er i lineær, ikke i n kvadreret, men i konstant tid, i det ideelle. Vi vil se dig på onsdag. SPEAKER: På det næste CS50, David glemmer sin base case. DAVID MALAN: Og det er, hvordan du sender tekstbeskeder med C. Hvad - [FORSKELLIGE TEKSTMEDDELELSE ANMELDELSE SOUNDS]